Skip to content

chore(deps): bump libdatadog to 48da0d8 for client-computed header fix#1244

Merged
lucaspimentel merged 3 commits into
mainfrom
lpimentel/bump-libdatadog-client-computed-headers
Jun 8, 2026
Merged

chore(deps): bump libdatadog to 48da0d8 for client-computed header fix#1244
lucaspimentel merged 3 commits into
mainfrom
lpimentel/bump-libdatadog-client-computed-headers

Conversation

@lucaspimentel

@lucaspimentel lucaspimentel commented Jun 3, 2026

Copy link
Copy Markdown
Member

Overview

Bump all libdd-* dependencies from db05e1f to 48da0d8 to pick up libdatadog PR #2071, which fixes how the datadog-client-computed-stats and datadog-client-computed-top-level headers are parsed so the behavior matches the Go trace-agent.

Bottlecap consumes this exact path in bottlecap/src/traces/trace_agent.rs via (&parts.headers).into(), so it directly benefits from the fix.

Adapting to breaking API changes between the two revisions

  • HttpClientTrait was renamed to HttpClientCapability
  • SendData::send now requires C: HttpClientCapability + SleepCapability, so implemented SleepCapability for HttpClient

Testing

Added Tier 0 coverage in trace_agent.rs pinning the new header-parsing behavior at the (&headers).into() boundary handle_traces uses:

  • true, yes, t, 1 -> flag set
  • false, 0, f, F, FALSE, False -> flag clear
  • absent/empty -> clear
  • client_computed_top_level no longer set by presence alone (pre-bump regression)

These test would fail on the pre-bump rev (db05e1f), so they lock in the fix.

"Turns out yes means yes and false means false. Took a whole PR to teach the parser what every toddler already knows." — Claude 🤖

APMSVLS-487

Bump all libdd-* dependencies from db05e1f to 48da0d8 to pick up
libdatadog PR #2071, which fixes how `From<&HeaderMap> for
TracerHeaderTags` parses the `datadog-client-computed-stats` and
`datadog-client-computed-top-level` headers so the behavior matches the
Go trace-agent. Bottlecap consumes this path in
traces/trace_agent.rs via `(&parts.headers).into()`.

Adapt to breaking API changes between the two revisions:

- libdd_capabilities `HttpClientTrait` was renamed to
  `HttpClientCapability`.
- `SendData::send` now requires `C: HttpClientCapability +
  SleepCapability`, so implement `SleepCapability` for `HttpClient`
  (backed by tokio::time::sleep, mirroring libdatadog's
  NativeSleepCapability).
@datadog-prod-us1-4

datadog-prod-us1-4 Bot commented Jun 3, 2026

Copy link
Copy Markdown

Pipelines

Fix all issues with BitsAI

⚠️ Warnings

🚦 2 Pipeline jobs failed

DataDog/datadog-lambda-extension | integration-suite: [auth]   View in Datadog   GitLab

DataDog/datadog-lambda-extension | integration-suite: [snapstart]   View in Datadog   GitLab

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 7c77ad6 | Docs | Datadog PR Page | Give us feedback!

@lucaspimentel lucaspimentel changed the title chore(deps): bump libdatadog to 48da0d8 for client-computed header fix chore(deps): bump libdatadog to 48da0d8 for client-computed header fix Jun 3, 2026
…the libdatadog bump

Adds a #[cfg(test)] mod tests block at the (&headers).into() boundary that
handle_traces uses, giving the db05e1f -> 48da0d8 bump its missing behavioral
coverage for libdatadog#2071. Assertions are Go-agent-aligned (isHeaderTrue/
ParseBool): truthy values -> true, absent/empty -> false, falsey literals
(false/0/f/F/FALSE/False) -> false, and client_computed_top_level no longer set
by presence alone. These would fail on the pre-bump rev.
lucaspimentel added a commit that referenced this pull request Jun 3, 2026
…datadog bump PR

The Tier 0 tests assert libdatadog parsing behavior (not the _dd.compute_stats
feature), and libdatadog#2071 changes that behavior via the db05e1f -> 48da0d8
bump in PR #1244. Move them there so the bump carries its own behavioral
coverage and the assertions don't need to assert opposite things on two
branches. Feature branch keeps Tiers 1-3; rebase onto #1244 after it merges.
lucaspimentel added a commit that referenced this pull request Jun 3, 2026
…datadog bump PR

The Tier 0 tests assert libdatadog parsing behavior (not the _dd.compute_stats
feature), and libdatadog#2071 changes that behavior via the db05e1f -> 48da0d8
bump in PR #1244. Move them there so the bump carries its own behavioral
coverage and the assertions don't need to assert opposite things on two
branches. Feature branch keeps Tiers 1-3; rebase onto #1244 after it merges.
Describe the exact false-set the parser recognizes and note that non-ParseBool
values like "yes" resolve to true, matching what the truthy-values test asserts.

🤖 Co-Authored-By: Claude Code <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Comment thread bottlecap/src/traces/http_client.rs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated no new comments.

@lucaspimentel lucaspimentel merged commit 1c181be into main Jun 8, 2026
54 of 57 checks passed
@lucaspimentel lucaspimentel deleted the lpimentel/bump-libdatadog-client-computed-headers branch June 8, 2026 21:12
duncanista added a commit to DataDog/serverless-components that referenced this pull request Jun 10, 2026
Aligns libdatadog rev across all crates with the
datadog-lambda-extension bottlecap binary, which was bumped to this
rev in DataDog/datadog-lambda-extension#1244 for the client-computed
header fix. Required so bottlecap can consume datadog-agent-config
without ending up with two incompatible copies of
libdd-trace-obfuscation::ReplaceRule in its dependency graph.
lucaspimentel added a commit that referenced this pull request Jun 11, 2026
## Overview

Makes the extension respect the tracer's `Datadog-Client-Computed-Stats`
header and moves `_dd.compute_stats` from a baked-in function tag to a
per-span backend directive.

We tried supporting the `Datadog-Client-Computed-Stats` header before in
#1118, but that was reverted in #1176.

### Background

Span attribute `_dd.compute_stats` asks the backend to compute trace
stats. It must be set to `"1"` only when nobody else computed them —
neither the extension (agent) nor the tracer. Previously the extension:

1. **Baked `_dd.compute_stats` into the function tags** unconditionally
(`tags_from_env`), which also leaked the key into `_dd.tags.function`.
2. **Ignored `Datadog-Client-Computed-Stats`** entirely, so when a
tracer computed stats client-side, the backend was still asked to
compute them.

### Canonical semantics (validated against the Go agent)

The Go agent (`pkg/serverless/tags/tags.go`) only ever sets
`_dd.compute_stats = "1"`, never `"0"`, and leaves the key absent
otherwise. This PR matches that:

> Set `_dd.compute_stats="1"` iff `!compute_trace_stats_on_extension &&
!client_computed_stats`; otherwise leave it absent.

| `client_computed_stats` (header from tracer) | `compute_on_extension`
(extension config) | who computes | stamp `_dd.compute_stats="1"`?
| -------------------- | --------------------- | --------------- | ---
| true                 | (ignored)             | tracer          | ❌ no
| false                | true                  | extension       | ❌ no
| false                | false                 | backend         | ✅ yes

### Changes

- **`tags/lambda/tags.rs`** — stop baking `_dd.compute_stats` in
`tags_from_env` (no longer leaks into `_dd.tags.function`);
`COMPUTE_STATS_KEY` is now `pub` so the integration test can reuse it
instead of re-declaring the literal.
- **Path A: `traces/trace_processor.rs`** — `ChunkProcessor` gains
`client_computed_stats` and stamps `_dd.compute_stats="1"` per-span only
when neither side computes stats; the extension-side stats-generation
guard in `send_processed_traces` now also skips when
`client_computed_stats` is set.
- **Path B (extension-generated `aws.lambda` span)** —
`client_computed_stats` is propagated from the tracer's placeholder span
through `context.rs` → `processor.rs` → `processor_service.rs` →
`trace_agent.rs`, so Path B reuses the same `ChunkProcessor` stamping
(single source of truth).
- **OTLP: `otlp/agent.rs`** — the OTLP stats-generation guard previously
checked only `compute_trace_stats_on_extension`, so an OTLP request
carrying `Datadog-Client-Computed-Stats` would still generate
extension-side stats and double-count against the tracer. It now also
skips when `client_computed_stats` is set, mirroring the
`send_processed_traces` guard.
- **Single source of truth: `traces/trace_processor.rs`** — the three
decisions over the same two inputs (the per-span `_dd.compute_stats`
stamp, plus the extension-side stats-generation guards in
`send_processed_traces` and `otlp/agent.rs`) are now derived from one
`StatsComputedBy::resolve(compute_on_extension, client_computed_stats)`
helper, so the stamp and the guards can't silently drift apart.

### Note on the header value (cross-runtime)

`Datadog-Client-Computed-Stats` is not standardized (`"true"`
.NET/Java/PHP/Python, `"yes"` JS/Ruby/C++, `"t"` Go). bottlecap consumes
the already-parsed `client_computed_stats` bool from
`libdd_trace_utils`, where any non-empty value → `true`, so the fix
triggers on every runtime. A separate libdatadog PR
([DataDog/libdatadog#2071](DataDog/libdatadog#2071))
aligns the header parsing with the Go agent's `isHeaderTrue`/`ParseBool`
rules; this PR only consumes the bool and does not depend on that
change.

## Testing

- ~**Tier 0** (header-parsing contract)~ — moved to the libdatadog bump
PR #1244, since those tests assert libdatadog parsing behavior that the
`db05e1f → 48da0d8` bump changes. This branch keeps Tiers 1–3 and
rebases onto [#1244](//pull/1244) after
it merges.
- **Tier 1** (`trace_processor.rs`) — truth-table on `Span.meta`,
stats-skip guard via the real `StatsConcentratorService`, and updated
`tags.rs` unit tests asserting the key no longer appears in the tags
map. Fixed the logs/metrics integration tests that asserted the old
leak.
- **Tier 2** (`context.rs`, `processor.rs`) — context-level flag
recording and an end-to-end Path B test driving `send_ctx_spans` through
the `trace_tx` channel, asserting `_dd.compute_stats` on the
`aws.lambda` span across the truth table.
- **Tier 3** (`apm_integration_test.rs`) — full fake-intake E2E routing
a trace through `SendingTraceProcessor::send_processed_traces`: asserts
on the captured `AgentPayload` span meta and on `stats_payloads()`
(stats suppressed unless the extension computes and the tracer did not).

### ⚠️ TODO before merging

- [x] Rebase onto the libdatadog bump PR
([#1244](#1244))
after it merges.
- [ ] E2E tests.

---

> *"Computing stats twice doesn't make them twice as true, it just makes
the backend twice as grumpy."* — Claude 🤖

[APMSVLS-487](https://datadoghq.atlassian.net/browse/APMSVLS-487)

[APMSVLS-487]:
https://datadoghq.atlassian.net/browse/APMSVLS-487?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
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.

3 participants