feat(trace-utils): add _dd.sdk.otlp_export and datadog.sdk.semantics OTLP resource attributes - #2603
Conversation
…OTLP resource attributes
Mark OTLP trace payloads so the intake can tell a Datadog SDK exporting
over OTLP apart from a native payload converted by the datadogreceiver
(RFC: Measuring Adoption of Datadog SDKs in OTel Mode). The resource now
carries _dd.sdk.otlp_export:true and datadog.sdk.semantics ("otel" when
OTel trace semantics is enabled, else "datadog"). Any span-level
_dd.sdk.otlp_export is stripped from span attributes (v0.4 and v1
mappers) so it cannot contradict the resource value.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: 321fe20 | Docs | View more details | Give us feedback! |
BenchmarksComparisonBenchmark execution time: 2026-09-30 20:40:24 Comparing candidate commit 321fe20 in PR branch Found 7 performance improvements and 2 performance regressions! Performance is the same for 120 metrics, 0 unstable metrics.
|
Artifact Size Benchmark Reportaarch64-alpine-linux-musl
aarch64-unknown-linux-gnu
libdatadog-x64-windows
libdatadog-x86-windows
x86_64-alpine-linux-musl
x86_64-unknown-linux-gnu
|
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The v1 test does not actually exercise chunk-only marker filtering because the duplicate span attribute suppresses it first.
Review effort: Balanced
Findings: 1
What changed in this PR
Adds OTLP resource attributes identifying Datadog SDK exports and trace semantics while removing conflicting span-level markers.
Changes:
- Adds
_dd.sdk.otlp_exportanddatadog.sdk.semanticsresource attributes. - Strips span-level export markers in v0.4 and v1 mappings.
- Updates unit and integration coverage across OTLP transports.
| File | Description |
|---|---|
libdd-trace-utils/src/otlp_encoder/mapper.rs |
Adds resource markers and v0.4 filtering. |
libdd-trace-utils/src/otlp_encoder/mapper_v1.rs |
Adds v1 resource markers and filtering. |
libdd-data-pipeline/src/trace_exporter/builder.rs |
Documents semantics behavior. |
libdd-data-pipeline/tests/test_trace_exporter_otlp_export.rs |
Verifies JSON OTLP attributes. |
libdd-data-pipeline/tests/test_trace_exporter_otlp_grpc.rs |
Verifies gRPC resource attributes. |
libdd-data-pipeline/tests/test_trace_exporter_otlp_protobuf_export.rs |
Verifies protobuf resource attributes. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bf2ab9908d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…v1 mapper The existing test put the marker on both the span and the chunk, so merged_attrs_v1 discarded the chunk copy as a collision before the eligibility filter ran. Add a case where only the chunk carries the marker, past the attribute cap, asserting it is stripped and not counted as dropped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ab1c67a
into
main
…ibdd-data-pipeline, libdd-li... (#2619) <!-- release-proposal-inputs: {"crates":"libdd-capabilities-impl, libdd-common, libdd-data-pipeline, libdd-library-config, libdd-profiling-heap-allocator, libdd-remote-config, libdd-sampling, libdd-shared-runtime, libdd-telemetry, libdd-tinybytes, libdd-trace-utils","main_start_ref":"","level_overrides":"","bypass_standard_checks":false} --> # Release proposal for libdd-capabilities-impl, libdd-common, libdd-data-pipeline, libdd-library-config, libdd-profiling-heap-allocator, libdd-remote-config, libdd-sampling, libdd-shared-runtime, libdd-telemetry, libdd-tinybytes, libdd-trace-utils and their dependencies This PR contains version bumps based on public API changes and commits since last release. ###⚠️ Crates left out of this proposal affected by its major bumps These publishable workspace crates are not part of this release but their dependency requirement was rewritten on this branch while their published version still requires the old major. If they are a dependency on your deployment not including them in the release could result in duplicate packages or symbol incompatibility. - `libdd-capabilities-impl` `6.0.0` → `7.0.0` affects: `libdd-crashtracker`, `libdd-live-debugger`, `libdd-tracer-flare` - `libdd-common` `7.0.0` → `8.0.0` affects: `libdd-crashtracker`, `libdd-ffe`, `libdd-http-client`, `libdd-ipc`, `libdd-live-debugger`, `libdd-profiling`, `libdd-tracer-flare` - `libdd-data-pipeline` `11.0.0` → `12.0.0` affects: `libdd-live-debugger` - `libdd-remote-config` `6.0.0` → `7.0.0` affects: `libdd-ffe`, `libdd-live-debugger`, `libdd-tracer-flare` - `libdd-telemetry` `9.0.0` → `10.0.0` affects: `libdd-crashtracker` - `libdd-trace-stats` `10.0.0` → `11.0.0` affects: `libdd-ipc` - `libdd-trace-utils` `13.0.0` → `14.0.0` affects: `libdd-tracer-flare` ## libdd-capabilities **Next version:** `4.0.1` **Semver bump:** `patch` **Tag:** `libdd-capabilities-v4.0.1` ### Commits - build: Update workspace to Rust 2024 edition (#2575) ## libdd-common **Next version:** `8.0.0` **Semver bump:** `major` **Tag:** `libdd-common-v8.0.0` ### Commits - fix(ipc)!: use atomic deadlines for shared limiters (#2604) - feat(sidecar)!: Authenticate sidecar connections and shared memory (#2551) - build: Update workspace to Rust 2024 edition (#2575) - feat(trace_utils)!: add mutable metadata (#2545) ## libdd-ddsketch **Next version:** `1.1.3` **Semver bump:** `patch` **Tag:** `libdd-ddsketch-v1.1.3` ### Commits - build: Update workspace to Rust 2024 edition (#2575) ## libdd-profiling-heap-sampler **Next version:** `1.1.1` **Semver bump:** `patch` **Tag:** `libdd-profiling-heap-sampler-v1.1.1` ### Commits - build: Update workspace to Rust 2024 edition (#2575) ## libdd-tinybytes **Next version:** `1.1.5` **Semver bump:** `patch` **Tag:** `libdd-tinybytes-v1.1.5` ### Commits - build: Update workspace to Rust 2024 edition (#2575) ## libdd-trace-protobuf **Next version:** `5.1.0` **Semver bump:** `minor` **Tag:** `libdd-trace-protobuf-v5.1.0` ### Commits - fix(data-pipeline)!: revert changes that made /info un-parsable (#2586) - build: Update workspace to Rust 2024 edition (#2575) ## libdd-capabilities-impl **Next version:** `7.0.0` **Semver bump:** `major` **Tag:** `libdd-capabilities-impl-v7.0.0` ###⚠️ major bump forced due to: - `libdd-common`: ^7.0.0 → ^8.0.0 ### Commits - feat(sidecar)!: Authenticate sidecar connections and shared memory (#2551) - build: Update workspace to Rust 2024 edition (#2575) ## libdd-profiling-heap-allocator **Next version:** `1.2.0` **Semver bump:** `minor` **Tag:** `libdd-profiling-heap-allocator-v1.2.0` ### Commits - build: Update workspace to Rust 2024 edition (#2575) ## libdd-library-config **Next version:** `4.2.0` **Semver bump:** `minor` **Tag:** `libdd-library-config-v4.2.0` ### Commits - build: Update workspace to Rust 2024 edition (#2575) ## libdd-trace-normalization **Next version:** `4.2.0` **Semver bump:** `minor` **Tag:** `libdd-trace-normalization-v4.2.0` ### Commits - build: Update workspace to Rust 2024 edition (#2575) ## libdd-remote-config **Next version:** `7.0.0` **Semver bump:** `major` **Tag:** `libdd-remote-config-v7.0.0` ###⚠️ major bump forced due to: - `libdd-common`: ^7.0.0 → ^8.0.0 ### Commits - feat(sidecar)!: Authenticate sidecar connections and shared memory (#2551) - build: Update workspace to Rust 2024 edition (#2575) ## libdd-shared-runtime **Next version:** `6.0.0` **Semver bump:** `major` **Tag:** `libdd-shared-runtime-v6.0.0` ###⚠️ major bump forced due to: - `libdd-common`: ^7.0.0 → ^8.0.0 ### Commits - build: Update workspace to Rust 2024 edition (#2575) ## libdd-trace-utils **Next version:** `14.0.0` **Semver bump:** `major` **Tag:** `libdd-trace-utils-v14.0.0` ###⚠️ major bump forced due to: - `libdd-common`: ^7.0.0 → ^8.0.0 ### Commits - feat(trace-utils): add _dd.sdk.otlp_export and datadog.sdk.semantics OTLP resource attributes (#2603) - build: Update workspace to Rust 2024 edition (#2575) - feat(trace_utils)!: add mutable metadata (#2545) ## libdd-dogstatsd-client **Next version:** `8.0.0` **Semver bump:** `major` **Tag:** `libdd-dogstatsd-client-v8.0.0` ###⚠️ major bump forced due to: - `libdd-common`: ^7.0.0 → ^8.0.0 ### Commits - feat(sidecar)!: Authenticate sidecar connections and shared memory (#2551) - build: Update workspace to Rust 2024 edition (#2575) ## libdd-telemetry **Next version:** `10.0.0` **Semver bump:** `major` **Tag:** `libdd-telemetry-v10.0.0` ###⚠️ major bump forced due to: - `libdd-common`: ^7.0.0 → ^8.0.0 ### Commits - build: Update workspace to Rust 2024 edition (#2575) - feat(telemetry)!: Use mutable metadata (#2552) ## libdd-sampling **Next version:** `8.0.0` **Semver bump:** `major` **Tag:** `libdd-sampling-v8.0.0` ###⚠️ major bump forced due to: - `libdd-common`: ^7.0.0 → ^8.0.0 - `libdd-trace-utils`: ^13.0.0 → ^14.0.0 ### Commits - build: Update workspace to Rust 2024 edition (#2575) ## libdd-trace-obfuscation **Next version:** `10.0.0` **Semver bump:** `major` **Tag:** `libdd-trace-obfuscation-v10.0.0` ###⚠️ major bump forced due to: - `libdd-common`: ^7.0.0 → ^8.0.0 - `libdd-trace-utils`: ^13.0.0 → ^14.0.0 ### Commits - fix(data-pipeline)!: revert changes that made /info un-parsable (#2586) - build: Update workspace to Rust 2024 edition (#2575) - feat(obfuscation)!: make json transforms caller-provided (#2548) ## libdd-trace-stats **Next version:** `11.0.0` **Semver bump:** `major` **Tag:** `libdd-trace-stats-v11.0.0` ###⚠️ major bump forced due to: - `libdd-common`: ^7.0.0 → ^8.0.0 - `libdd-telemetry`: ^9.0.0 → ^10.0.0 - `libdd-trace-obfuscation`: ^9.0.0 → ^10.0.0 - `libdd-trace-utils`: ^13.0.0 → ^14.0.0 ### Commits - feat(sidecar)!: Authenticate sidecar connections and shared memory (#2551) - build: Update workspace to Rust 2024 edition (#2575) - feat(trace_utils)!: add mutable metadata (#2545) - fix(stats): fix precedence for http endpoint (#2582) ## libdd-data-pipeline-core **Next version:** `3.0.0` **Semver bump:** `major` **Tag:** `libdd-data-pipeline-core-v3.0.0` ###⚠️ major bump forced due to: - `libdd-common`: ^7.0.0 → ^8.0.0 - `libdd-trace-obfuscation`: ^9.0.0 → ^10.0.0 - `libdd-trace-stats`: ^10.0.0 → ^11.0.0 - `libdd-trace-utils`: ^13.0.0 → ^14.0.0 ### Commits - build: Update workspace to Rust 2024 edition (#2575) - feat(trace_utils)!: add mutable metadata (#2545) ## libdd-data-pipeline **Next version:** `12.0.0` **Semver bump:** `major` **Tag:** `libdd-data-pipeline-v12.0.0` ###⚠️ major bump forced due to: - `libdd-common`: ^7.0.0 → ^8.0.0 - `libdd-telemetry`: ^9.0.0 → ^10.0.0 - `libdd-trace-obfuscation`: ^9.0.0 → ^10.0.0 - `libdd-trace-stats`: ^10.0.0 → ^11.0.0 - `libdd-trace-utils`: ^13.0.0 → ^14.0.0 ### Commits - feat(trace-utils): add _dd.sdk.otlp_export and datadog.sdk.semantics OTLP resource attributes (#2603) - fix(data-pipeline)!: revert changes that made /info un-parsable (#2586) - build: Update workspace to Rust 2024 edition (#2575) - feat(telemetry)!: Use mutable metadata (#2552) - feat(trace_utils)!: add mutable metadata (#2545) --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: iunanua <18325288+iunanua@users.noreply.github.com>

What does this PR do?
Adds two OTLP resource attributes to traces exported over OTLP, and strips a conflicting span-level marker:
_dd.sdk.otlp_export: "true"— always set inbuild_resource, since reaching the OTLP encoder means the payload is leaving over OTLP.datadog.sdk.semantics—"otel"when OTel trace semantics mode is enabled (TraceExporterBuilder::enable_otel_trace_semantics()),"datadog"otherwise._dd.sdk.otlp_export(tracers stamp"false"on native payloads; users can set it viaDD_TAGS) is dropped from OTLP span attributes in both the v0.4 mapper (meta loop, with dropped-count accounting kept in sync) and the v1 mapper (is_eligible), so it can never contradict the resource value.The semantics flag is threaded into
build_resourceas a parameter (it ispub(super)) rather than added toOtlpResourceInfo: bothmap_traces_to_otlp*entry points already receive it per call, so a struct field would duplicate state that could diverge. No public API change.Motivation
RFC: Measuring Adoption of Datadog SDKs in OTel Mode (Traces). The intake cannot currently tell a Datadog SDK exporting over OTLP apart from a native payload converted to OTLP by the Collector's
datadogreceiver(both set a Datadog-ownedtelemetry.sdk.name). SDKs now declare the export mode explicitly; the backend promotes the marker todatadog.sdk.otlp_exportondd.trace.intake.ingested_spans, anddatadog.sdk.semanticslets us measure OTel-semantics adoption.Equivalent Java change: DataDog/dd-trace-java#12516 (
OtlpResourceAttributes). SDKs that export OTLP through libdatadog (e.g. dd-trace-py) get this without language-side changes beyond a version bump.Additional Notes
_dd.sdk.otlp_export:false): chore(tracing): mark native trace export with _dd.sdk.otlp_export dd-trace-py#20703. dd-trace-py already callsenable_otel_trace_semantics()when semantics mode + OTLP are on, so it only needs a libdatadog pin bump after this is released.libdd-data-pipeline-ffidoes not exposeenable_otel_trace_semantics, so FFI consumers will always reportdatadog.sdk.semantics: "datadog"until a setter is added (out of scope here).libdd-data-pipeline/src/otlp/metrics.rs) is unchanged; the RFC covers traces only.How to test the change?
libdd-trace-utils/src/otlp_encoder/mapper.rs,mapper_v1.rs): resource carries both attributes for each flag value; span meta_dd.sdk.otlp_exportis stripped and the dropped count stays correct past the attribute cap. v1 also has a chunk-only case (marker only inchunk.attributes, past the cap), since a span-level copy would win the merge and hide the chunk path.test_trace_exporter_otlp_export.rs(semantics on →"otel"),test_trace_exporter_otlp_grpc.rs,test_trace_exporter_otlp_protobuf_export.rs(→"datadog").Run locally:
cargo test -p libdd-trace-utils otlp— 62 passed;--lib466 passedcargo test -p libdd-data-pipeline --test test_trace_exporter_otlp_export --test test_trace_exporter_otlp_grpc --test test_trace_exporter_otlp_protobuf_export— 7 passedcargo clippy -p libdd-trace-utils -p libdd-data-pipeline --all-targets -- -D warnings— cleancargo fmt --all -- --check— clean (run on stable cargo, not the pinned nightly; CI fmt will confirm)cargo test -p libdd-data-pipeline --lib— 200 passed, 2 failed (test_agent_info_fetcher_run,test_v1_404_fails_closed_to_v04); both pass in isolation — they aresingle_threaded_testsintended for nextest, unrelated to this change.🤖 Generated with Claude Code