Repository navigation
Conversation
lym953
added a commit
that referenced
this pull request
Oct 16, 2026
…logs Drop the lock on h2, hyper, reqwest and rustls. The lock kept their lines out of the logs that the extension sends to Datadog, because those libraries log each log upload too. #1429 keeps their lines out of the upload instead, so this commit must merge after #1429. The four libraries stay off by default. serverless-components goes back to main (19270f5), which has no lock argument. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
❌ ErrorsYour PR has failed checks. Please review the issues below and take necessary action before merging. 🚦 1 Pipeline job failed
Useful? React with 👍 / 👎 This comment will be updated automatically if new data arrives.🔗 Commit SHA: b0ed4d7 | Docs | View more details | Give us feedback! |
lym953
force-pushed
the
yiming.luo/http-library-debug-logs
branch
from
October 16, 2026 18:33
c706c4b to
151ec55
Compare
The extension sends its own stdout to Datadog as logs. The HTTP libraries
(h2, hyper, reqwest, rustls) log each request, including the requests that
send those logs, so their lines must stay out of the upload. Otherwise each
flush logs lines for the next flush to send.
- The formatter starts each line from those targets with
`{"target":"<target>",` and appends the event's other fields as
`name=value`, so that h2 frame lines show the frame.
- The Lambda logs processor drops extension records that start that way.
The lines still reach CloudWatch.
- The logger is installed with `init()`, which also forwards records from
the `log` crate to it.
- The default-off filter for these targets is built from the same list.
- The logger README says that these lines appear only in CloudWatch.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lym953
force-pushed
the
yiming.luo/http-library-debug-logs
branch
from
October 16, 2026 18:40
151ec55 to
dd01db2
Compare
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The scoped formatting, filtering, and initialization changes have regression coverage and no identified blocking issues.
0 open findings
What changed in this PR
Keeps HTTP-library diagnostics in CloudWatch without forwarding them to Datadog, preventing log-flush feedback loops when target-specific logging is enabled.
Changes:
- Marks HTTP-library logs and excludes them from Datadog ingestion.
- Includes diagnostic fields and forwards
logcrate records through tracing. - Adds regression tests and documents CloudWatch-only behavior.
| File | Description |
|---|---|
| bottlecap/src/logs/lambda/processor.rs | Drops marked HTTP-library records; adds coverage. |
| bottlecap/src/logger/README.md | Documents CloudWatch-only diagnostics. |
| bottlecap/src/logger/mod.rs | Adds target markers, diagnostic fields, detection, and tests. |
| bottlecap/src/bin/bottlecap/main.rs | Shares default-off targets and initializes log forwarding. |
| bottlecap/Cargo.toml | Adds the tracing-log dependency. |
| bottlecap/Cargo.lock | Records the direct dependency. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
What is true today. When a flush to Datadog stalls, the extension's debug logs end at the line
Attempting request. They cannot show whether DNS, the TCP connect, TLS or the response stalled. A customer's invocations ran to their 25 s timeout this way, and the logs could not tell us where. The HTTP libraries that make these flushes (h2, hyper, reqwest and rustls) log each of these steps, but the extension turns their logs off.What #1413 adds. A new environment variable,
DD_LOG_LEVEL_BY_TARGET, sets the log level for one target. It can turn the four HTTP libraries on.The problem. The extension sends its own stdout to Datadog as logs. These libraries log every request, including the requests that send those logs. So their lines would go into the next flush, and each flush would log lines for the next one to send.
This PR
{"target":"<target>",, and the Lambda logs processor drops extension records that start that way. In the same way, the Go extension keeps its failover message out of the logs that it sends.name=value. h2 logs each frame in a field, so its lines showsend frame=Headers { stream_id: StreamId(1), … }. h2 leaves header values and body bytes out of this output.init(). This call of tracing-subscriber, the library that writes the extension's logs, also forwards records from thelogcrate to the logger.This PR is stacked on #1413. Merge #1413 first and this PR right after it, because #1413 alone lets an entry turn these libraries on.
Impact
logcrate reach the logger at the configured level. Before, nothing received them. For example, the crate that obfuscates trace data,libdd-trace-obfuscation, logsFailed to parse DD_APM_REPLACE_TAGSwithlog.targetkey and the extra fields.Testing
Automated tests
Steps
cargo test --lib -- logger:: logs::cargo clippy --all-targetsandcargo fmt --checkResult
87 tests pass, including the 5 new logger tests and the new processor test. Clippy and
cargo fmt --checkpass.Only these unit tests cover an extension record that arrives as a JSON object.
End-to-end tests in Lambda
Steps
main. The build used the script that publishes a layer to the sandbox account,scripts/publish_bottlecap_sandbox.sh(x86_64, not FIPS).DD_LOG_LEVEL=debugandDD_LOG_LEVEL_BY_TARGET=hyper_util=debug,h2=debug:DD_LOG_LEVEL=debug.Result
Last lines before the stall, for the same function with the released layer and with the test layer:
Attempting request, then no other line for that request until the 25 s timeoutconnected to 127.0.0.1:9443, then no other line for that connection until the 25 s timeoutAttempting request, thenRequest failed with errorafter 15.5 sconnecting to <ip>:443for 3 intake IPs, and noconnected toChecks on the test layer only:
send frame=Headers { … },send frame=Data { … END_STREAM },received frame=Headers { … }These cases did not get lines from all libraries. rustls wrote no lines, because release builds have no rustls
loggingfeature (only a dev-dependency turns it on). The trace flush showed only the connect lines, because it uses HTTP/1 through hyper 1.x, which is built withouttracing.🤖 Generated with Claude Code