Conversation
Adds two wire markers so the intake can attribute ingested spans to the SDK's export path and semantics instead of inferring them from telemetry.sdk.name. - _dd.sdk.otlp_export: written once per payload on the first span of the first chunk by the MessagePack formatter (always "false", since reaching it means native Datadog encoding), and as an OTLP resource attribute set to "true" on the OTLP export path. - datadog.sdk.semantics: OTLP resource attribute, "otel" when DD_TRACE_OTEL_SEMANTICS_ENABLED is set, "datadog" otherwise. Both keys are suppressed as span attributes so a user tag of the same name cannot contradict the resource-scoped values. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fold the _dd.sdk.otlp_export write and the process tags write into a single "first span of the first chunk" condition, with the process tags null checks nested inside it. The export marker stays unconditional: an absent marker is indistinguishable from an older tracer at intake, so it must not inherit the process tags gating. Also move the _dd.sdk.otlp_export entry to the end of the DefaultTagAssertions chain to keep the diff off unrelated lines. No change to the serialized payload: msgpack maps are unordered and both readers key by name. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
SdkOtlpExport_IsWrittenOncePerPayload only exercised a single trace chunk, so it verified IsFirstSpanInChunk but never IsFirstChunkInPayload. Dropping the latter half of the gate would have written one marker per chunk and still passed. Flush two traces into one payload and assert exactly one _dd.sdk.otlp_export marker across the whole payload, on the first span of the first chunk. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing This PR (9310) and master. ✅ No regressions detected |
BenchmarksBenchmark execution time: 2026-09-25 19:43:24 Comparing candidate commit 36c3b83 in PR branch Found 0 performance improvements and 11 performance regressions! Performance is the same for 61 metrics, 0 unstable metrics, 73 known flaky benchmarks, 53 flaky benchmarks without significant changes.
|
_dd.sdk.otlp_export is written once per payload, which broke tests asserting exact tag counts and tests byte-comparing serialized chunks. - TagsListTests: exclude payload-scoped tags from count assertions - AgentWriter/ApmAgentWriter tests: build expectations with isFirstChunkInPayload: true, matching SpanBuffer's real behaviour - CI XUnit/NUnit/MsTestV2 tests: strip the marker alongside process tags Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds the two new OTLP resource attributes (_dd.sdk.otlp_export, datadog.sdk.semantics) and the native msgpack _dd.sdk.otlp_export meta entry to the snapshots that assert on them, regenerated from Azure DevOps build 209972. Also ignores meta._dd.sdk.otlp_export in the smoke test snapshot comparison, alongside meta._dd.tags.process, since both are written once per payload rather than on every span. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Snapshots difference summaryThe following differences have been observed in committed snapshots. It is meant to help the reviewer. 75 occurrences of : + },
+ {
+ "key": "_dd.sdk.otlp_export",
+ "value": {
+ "stringValue": "true"
+ }
+ },
+ {
+ "key": "datadog.sdk.semantics",
+ "value": {
+ "stringValue": "datadog"
+ }
27 occurrences of : + },
+ {
+ "key": "_dd.sdk.otlp_export",
+ "value": {
+ "stringValue": "true"
+ }
+ },
+ {
+ "key": "datadog.sdk.semantics",
+ "value": {
+ "stringValue": "otel"
+ }
|
_dd.sdk.otlp_export is written to the first span of a payload, and which span that is is not stable, so pinning it in a snapshot fails on any machine that orders spans differently (x64 snapshots vs arm64 runs). ScrubCIVisibilityTags already drops _dd.tags.process for exactly this reason; drop the export marker alongside it and remove the lines it had already been baked into. The existing Tags.Remove(SdkOtlpExport) calls in the CI test files stay: they run on the spans used for the tag-count assertions, not on the copy taken for the snapshot. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Reserved marker names can still be emitted through numeric metric overloads as span attributes.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
Open (1)
What changed in this PR
Adds OTLP export and semantic-convention adoption markers to native and OTLP trace payloads.
Changes:
- Defines payload and resource marker keys.
- Emits markers through MessagePack and OTLP serializers.
- Updates tests, snapshots, and verification helpers.
| File | Reviewed change |
|---|---|
tracer/test/snapshots/XUnitTests.SubmitTraces_packageVersion=all.verified.txt |
Updates payload snapshot expectations. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.OtelSemantics.__method=GET_path=_status-code_500.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.OtelSemantics.__method=GET_path=_status-code_400.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.OtelSemantics.__method=GET_path=_status-code_302.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.OtelSemantics.__method=GET_path=_rewrite-me.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.OtelSemantics.__method=GET_path=_ping.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.OtelSemantics.__method=GET_path=_path-base_api_delay_0.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.OtelSemantics.__method=GET_path=_bad-request.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.OtelSemantics.__method=GET_path=_api_delay_0.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.OtelSemantics.__method=GET_path=_api_delay_0-token=SUPER-SECRET-TOKEN-VALUE.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.OtelSemantics.__method=GET_path=_api_delay_0-id=1.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.OtelSemantics.__method=GET_path=_.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.OtelSemantics.__method=FOO_path=_ping.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.WithFF.__method=GET_path=_status-code_500.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.WithFF.__method=GET_path=_status-code_400.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.WithFF.__method=GET_path=_status-code_302.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.WithFF.__method=GET_path=_rewrite-me.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.WithFF.__method=GET_path=_ping.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.WithFF.__method=GET_path=_path-base_api_delay_0.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.WithFF.__method=GET_path=_bad-request.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.WithFF.__method=GET_path=_api_delay_0.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.WithFF.__method=GET_path=_api_delay_0-token=SUPER-SECRET-TOKEN-VALUE.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.WithFF.__method=GET_path=_api_delay_0-id=1.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.WithFF.__method=GET_path=_.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.WithFF.__method=FOO_path=_ping.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.SingleSpan.__method=GET_path=_status-code_500.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.SingleSpan.__method=GET_path=_status-code_400.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.SingleSpan.__method=GET_path=_status-code_302.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.SingleSpan.__method=GET_path=_rewrite-me.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.SingleSpan.__method=GET_path=_ping.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.SingleSpan.__method=GET_path=_path-base_api_delay_0.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.SingleSpan.__method=GET_path=_bad-request.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.SingleSpan.__method=GET_path=_api_delay_0.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.SingleSpan.__method=GET_path=_api_delay_0-token=SUPER-SECRET-TOKEN-VALUE.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.SingleSpan.__method=GET_path=_api_delay_0-id=1.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.SingleSpan.__method=GET_path=_.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.SingleSpan.__method=FOO_path=_ping.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.NoFF.__method=GET_path=_status-code_500.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.NoFF.__method=GET_path=_status-code_400.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.NoFF.__method=GET_path=_status-code_302.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.NoFF.__method=GET_path=_rewrite-me.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.NoFF.__method=GET_path=_ping.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.NoFF.__method=GET_path=_path-base_api_delay_0.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.NoFF.__method=GET_path=_bad-request.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.NoFF.__method=GET_path=_api_delay_0.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.NoFF.__method=GET_path=_api_delay_0-token=SUPER-SECRET-TOKEN-VALUE.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.NoFF.__method=GET_path=_api_delay_0-id=1.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.NoFF.__method=GET_path=_.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMvc31Tests.DatadogSemantics.NoFF.__method=FOO_path=_ping.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.OtelSemantics.__method=GET_path=_status-code_500.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.OtelSemantics.__method=GET_path=_status-code_400.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.OtelSemantics.__method=GET_path=_status-code_302.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.OtelSemantics.__method=GET_path=_rewrite-me.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.OtelSemantics.__method=GET_path=_ping.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.OtelSemantics.__method=GET_path=_path-base_api_delay_0.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.OtelSemantics.__method=GET_path=_bad-request.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.OtelSemantics.__method=GET_path=_api_delay_0.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.OtelSemantics.__method=GET_path=_api_delay_0-token=SUPER-SECRET-TOKEN-VALUE.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.OtelSemantics.__method=GET_path=_api_delay_0-id=1.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.OtelSemantics.__method=GET_path=_.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.OtelSemantics.__method=FOO_path=_ping.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.WithFF.__method=GET_path=_status-code_500.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.WithFF.__method=GET_path=_status-code_400.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.WithFF.__method=GET_path=_status-code_302.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.WithFF.__method=GET_path=_rewrite-me.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.WithFF.__method=GET_path=_ping.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.WithFF.__method=GET_path=_path-base_api_delay_0.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.WithFF.__method=GET_path=_bad-request.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.WithFF.__method=GET_path=_api_delay_0.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.WithFF.__method=GET_path=_api_delay_0-token=SUPER-SECRET-TOKEN-VALUE.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.WithFF.__method=GET_path=_api_delay_0-id=1.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.WithFF.__method=GET_path=_.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.WithFF.__method=FOO_path=_ping.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.SingleSpan.__method=GET_path=_status-code_500.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.SingleSpan.__method=GET_path=_status-code_400.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.SingleSpan.__method=GET_path=_status-code_302.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.SingleSpan.__method=GET_path=_rewrite-me.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.SingleSpan.__method=GET_path=_ping.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.SingleSpan.__method=GET_path=_path-base_api_delay_0.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.SingleSpan.__method=GET_path=_bad-request.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.SingleSpan.__method=GET_path=_api_delay_0.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.SingleSpan.__method=GET_path=_api_delay_0-token=SUPER-SECRET-TOKEN-VALUE.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.SingleSpan.__method=GET_path=_api_delay_0-id=1.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.SingleSpan.__method=GET_path=_.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.SingleSpan.__method=FOO_path=_ping.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.NoFF.__method=GET_path=_status-code_500.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.NoFF.__method=GET_path=_status-code_400.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.NoFF.__method=GET_path=_status-code_302.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.NoFF.__method=GET_path=_rewrite-me.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.NoFF.__method=GET_path=_ping.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.NoFF.__method=GET_path=_path-base_api_delay_0.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.NoFF.__method=GET_path=_bad-request.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.NoFF.__method=GET_path=_api_delay_0.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.NoFF.__method=GET_path=_api_delay_0-token=SUPER-SECRET-TOKEN-VALUE.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.NoFF.__method=GET_path=_api_delay_0-id=1.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.NoFF.__method=GET_path=_.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OtlpAspNetCoreMinimalApisTests.DatadogSemantics.NoFF.__method=FOO_path=_ping.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OpenTelemetryWebRequestTests.SubmitsOtlpTraces_OtelSemantics_Net5.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OpenTelemetryWebRequestTests.SubmitsOtlpTraces_Net5.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OpenTelemetrySdkTests.SubmitsOtlpTraces_DD.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OpenTelemetrySdkTests.SubmitsOtlpTraces_DD_OtelSemantics.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OpenTelemetryHttpClientTests.SubmitsOtlpTraces.verified.txt |
Updates OTLP resource markers. |
tracer/test/snapshots/OpenTelemetryHttpClientTests.SubmitsOtlpTraces_OtelSemantics.verified.txt |
Updates OTLP resource markers. |
tracer/test/Datadog.Trace.Tests/Tagging/TagsListTests.cs |
Adjusts tag-count assertions. |
tracer/test/Datadog.Trace.Tests/OpenTelemetry/OtlpMapperTests.cs |
Tests resource markers and filtering. |
tracer/test/Datadog.Trace.Tests/Agent/MessagePack/SpanMessagePackFormatterTests.cs |
Tests payload-scoped native markers. |
tracer/test/Datadog.Trace.Tests/Agent/AgentWriterTests.cs |
Updates payload expectations. |
tracer/test/Datadog.Trace.TestHelpers/SpanTagAssertion.cs |
Allows the native marker. |
tracer/test/Datadog.Trace.TestHelpers.SharedSource/VerifyHelper.cs |
Scrubs payload-scoped markers. |
tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/CI/XUnitTests.cs |
Updates integration assertions. |
tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/CI/NUnitTests.cs |
Updates integration assertions. |
tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/CI/MsTestV2Tests.cs |
Updates integration assertions. |
tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/CI/Agent/ApmAgentWriterTests.cs |
Updates native payload expectations. |
tracer/src/Datadog.Trace/Tags.cs |
Defines adoption marker keys. |
tracer/src/Datadog.Trace/OpenTelemetry/OtlpMapper.cs |
Emits resource markers and filters span attributes. |
tracer/src/Datadog.Trace/Agent/MessagePack/TraceChunkModel.cs |
Carries semantic settings into serialization. |
tracer/src/Datadog.Trace/Agent/MessagePack/SpanMessagePackFormatter.cs |
Writes the native marker once per payload. |
tracer/build/_build/SmokeTests/SmokeTestScenario.cs |
Ignores the marker in smoke snapshots. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Keeps the payload-scoped comment in SpanMessagePackFormatter, reworded from "Process tags" since the block now covers the export marker too. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Summary of changes
Adds two wire markers that let the backend attribute ingested spans to the SDK's export path and semantic conventions:
_dd.sdk.otlp_export— written once per payload (not per span): on the first span of the first chunk bySpanMessagePackFormatterwith value"false", and as an OTLP resource attribute with value"true"byOtlpMapper.datadog.sdk.semantics— OTLP resource attribute,"otel"whenDD_TRACE_OTEL_SEMANTICS_ENABLEDis enabled,"datadog"otherwise.Reason for change
Today "how many customers run Datadog SDKs emitting OTLP" is answered by
dd.trace.intake.ingested_spanstagged withsdk_name/span_source, which are inferred at ingest time rather than declared by the tracer. Thedatadogreceiverhardcodestelemetry.sdk.name:Datadogon native payloads it converts, so a native payload that merely passed through a Collector is indistinguishable from one a Datadog SDK exported over OTLP, andspan_sourcerecords the endpoint the payload reached, not the tracer's export mode.Declaring the export mode and the semantics mode on the wire lets the backend resolve them into explicit tags (
datadog.sdk.otlp_export,datadog.sdk.semantics) and measure OTLP and OTel-semantics adoption directly. This mirrors the dd-trace-java implementation in DataDog/dd-trace-java#12516.Implementation details
Tags.SdkOtlpExport(_dd.sdk.otlp_export) andTags.SdkSemantics(datadog.sdk.semantics).SpanMessagePackFormatter: the existing process-tags write and the new marker now share a single payload-scoped block, gated onmodel.IsFirstSpanInChunk && model.TraceChunk.IsFirstChunkInPayload, with the process-tags null checks nested inside it. The marker therefore costs one meta entry per payload rather than one per span. It is written unconditionally within that block — it deliberately does not inherit the process-tags gating, because an absent marker is indistinguishable from an older tracer at intake. Reaching this formatter means the payload uses the native Datadog encoding, so the value is a constant"false"— the encodings are mutually exclusive in this tracer (TracesEncoding), unlike dd-trace-java, which reads a config flag because aMultiWritercan export both ways.OtlpMapper.EmitResourceAttributesFromTraceChunk: emits_dd.sdk.otlp_export=true(reaching this mapper means the payload leaves over OTLP) anddatadog.sdk.semantics, sourced from a newTraceChunkModel.OtelSemanticsEnabledpopulated alongsideClientComputedStats.IGNORED_GLOBAL_TAGSin dd-trace-java)./v0.4/tracesis the only native endpoint andTracesEncodinghas exactly three members — so only the v0.4 formatter and the two OTLP serializers are touched.datadog.sdk.semanticsis emitted on the OTLP path only, matching dd-trace-java. Native-export users are therefore not counted for semantics adoption; extending the native path would need a separate marker and is out of scope here.Test coverage
SpanMessagePackFormatterTests.SdkOtlpExport_IsWrittenOncePerPayload: flushes two traces into a single payload and asserts exactly one marker across the whole payload, on the first span of the first chunk. Covers both halves of the gate (IsFirstSpanInChunkandIsFirstChunkInPayload).OtlpMapperTests: the export marker is"true"on the resource,datadog.sdk.semanticsswitches between"otel"and"datadog"withDD_TRACE_OTEL_SEMANTICS_ENABLED, and neither key is emitted as a span attribute when a span carries a tag of the same name.TagsListTestsnow excludes payload-scoped tags from its count assertions, andAgentWriterTests/CI.Agent.ApmAgentWriterTestsbuild their expected chunks withisFirstChunkInPayload: true, matching whatSpanBufferactually does (they previously defaulted tofalse, so the expectation was already wrong — the marker only made it visible).XUnitTests,NUnitTests,MsTestV2Tests) strip the marker alongside process tags before their remaining-tag assertions.Snapshots
VerifyHelperscrubs_dd.sdk.otlp_exportfrom both the APM and CI Visibility span scrubbers, andSpanTagAssertionmarks it optional. The marker lands on whichever span is first in the payload, which is not stable across architectures, so it must never be pinned in a snapshot.SmokeTestScenario.DefaultSnapshotIgnoredAttrsignoresmeta._dd.sdk.otlp_export, alongsidemeta._dd.tags.processwhich is payload-scoped for the same reason.tracer/test/snapshots/.Other details
_dd.sdk.otlp_exportinto the outgoing payload,logs-backendpropagates it into chunk tags, anddd-goresolves it into thedatadog.sdk.otlp_exportmetric tag.datadog.sdk.otlp_exportand the wire marker_dd.sdk.otlp_exportare named differently on purpose — same concept, two layers.AgentWriterTests.ComputeSizestill constructs its chunk with the defaultisFirstChunkInPayload: false, so it under-reports the first chunk by 26 bytes. It only sizesmaxBufferSizefor the buffer-full tests, whose "room for exactly one trace" intent is preserved, so it was left alone.🤖 Generated with Claude Code