Skip to content

[SVLS-8713] test(logs): contract tests, fake logs intake and benchmark for the logs pipeline - #1448

Draft
litianningdatadog wants to merge 1 commit into
mainfrom
tianning.li/logs-bc-0-contract-tests
Draft

litianningdatadog wants to merge 1 commit into
mainfrom
tianning.li/logs-bc-0-contract-tests

Conversation

@litianningdatadog

@litianningdatadog litianningdatadog commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Part of SVLS-8713: bottlecap is replacing its own logs aggregator and flusher with the shared datadog-logs-agent crate from serverless-components. Lambda users must not notice the swap, so the plan is: pin today's behavior with tests (this stack), fix two real bugs first so the swap stays a pure refactor (this stack), then swap the aggregator and the flusher (bc-1 and bc-2, which will be opened after the serverless-components PRs merge).

Pins what the logs pipeline does today so the coming swap to datadog-logs-agent can be shown to change nothing for users. Almost all of it is tests; the only production change is a small refactor.

  • refactor: the code that builds the logs aggregator, agent and flusher moves from main.rs into build_logs_pipeline() in the library, so tests run exactly the production wiring. Runtime behavior is unchanged.
  • fake logs intake: a test server (HTTP and HTTPS with a self-signed cert) that records every request, decompresses zstd bodies and answers with scripted status codes or hangs.
  • contract tests (tests/logs_contract_test.rs) through the real pipeline: every log field by field (START/END/REPORT, plain and JSON logs, logs before START, Managed Instance, processing rules, OOM, durable execution); URL, headers, method and compression per destination (Datadog, OPW, two additional endpoints, custom intake URL with a path); retries, redrive and drops for 400/401/403/413/429/500, timeouts and refused connections; batching; oversized logs; and warning/error line counts.
  • benchmark (benches/logs_pipeline.rs, criterion dev-dependency): process-and-batch and flush, used as the baseline for the swap.

Two contract tests record known bugs on purpose (OPW + additional endpoints; one log over 5 MiB blocking the queue); the next two PRs fix them and update those tests.

Testing

755 tests pass (lib + contract + integration). clippy (-D warnings) and fmt clean. Every commit compiles. The benchmark only adds a dev-dependency; the extension binary is unchanged.

Stack

Each PR is nested under the PR it builds on (and targets). Review and merge from the top down.

serverless-components (datadog-logs-agent options; merge first)

datadog-lambda-extension (bottlecap)

🤖 Generated with Claude Code

@datadog-datadog-us1-prod

datadog-datadog-us1-prod Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Pipelines

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 31214a0 | Docs | View more details | Give us feedback!

…r the logs pipeline

Why: we are about to replace the logs aggregator and flusher with the shared
datadog-logs-agent crate, and Lambda users must not notice. These changes
record exactly what bottlecap does today, so any change in what it sends
shows up as a failing test instead of a surprise in production, and give a
performance baseline to compare against.

What:
- refactor: the code that creates the logs aggregator, agent and flusher
  moves from main.rs into build_logs_pipeline() in the library, so tests run
  exactly the production wiring. main.rs still starts the agent in the
  background; runtime behavior is unchanged. A unit test checks that a log
  sent into the pipeline reaches the aggregator.
- fake logs intake: a test server that accepts log requests over HTTP or
  HTTPS (self-signed test certificate), records each request (method, URL,
  headers, body), decompresses zstd bodies, and answers with status codes
  chosen by the test or hangs on purpose. It has its own tests.
- contract tests (tests/logs_contract_test.rs) through the real pipeline:
  - every log field by field: START/END/REPORT lines, plain and JSON
    function logs, logs that arrive before START, Managed Instance mode,
    processing rules, OOM lines and durable execution logs;
  - the URL path, API key, headers, method and compression of each request
    for the Datadog intake (compressed and not), Observability Pipelines
    Worker, two additional HTTPS endpoints, and a custom intake URL with a
    path;
  - retry, redrive and drop rules: 403 dropped with no retry; 400, 401,
    413, 429 and 500 tried three times, handed back and resent once more;
    a redrive resends only the failed request; timeouts and refused
    connections are handed back; additional-endpoint failures are resent
    only to that endpoint; a missing API key drops the primary's logs with
    an error while additional endpoints still get them;
  - batching (2,500 small logs and three 2 MiB logs arrive exactly once
    within the per-request limits) and oversized logs (a 2 MiB log is sent
    with one warning);
  - how many warning and error lines the pipeline writes.
  Two tests record known bugs on purpose (OPW applied to additional
  endpoints; one log over 5 MiB blocking the queue); the next changes fix
  them and update those tests.
- benchmark (benches/logs_pipeline.rs): turning Lambda telemetry events into
  batched logs, and flushing 1,000 varied logs to a local fake intake with
  zero or two additional endpoints, using the extension's allocator. Adds
  criterion as a dev-dependency only; the extension binary is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant