Conversation
Set _dd.sdk.otlp_export=false on the first span of each trace chunk exported to the agent, so the backend can tell native export apart from OTLP export. dd-trace-rs has no OTLP trace export yet, so the marker is unconditional. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
🔒 Cargo Deny Results📦 Root workspace - 5 error(s), 19 warning(s)Show output |
Move the _dd.sdk.otlp_export=false marker out of the OTel to Datadog span conversion and into send_trace_chunks, through a new mark_native_export helper. The exporter is where the output format is chosen, so once OTLP trace export lands the marker can be gated there on the actual export mode. The payload is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Move the _dd.sdk.otlp_export=false marker back into otel_trace_chunk_to_dd_trace_chunk and drop the mark_native_export helper. Add comments at the marker and at its call site noting that the export mode must be passed in to skip the tag once OTLP trace export is added. The payload is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Tag the first span of each chunk from inside the per-span map, using enumerate and a small add_native_export_marker helper, instead of editing the collected Vec afterwards. The conversion chain is the function's return value again, as on main. The payload is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The snapshot tests already check the full payload, including the marker on the first span of each chunk only, so the inline unit tests in ddtrace_transform.rs are redundant. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The marker is correctly limited to each chunk’s first span and is covered by multi-span integration snapshots.
Review effort: Balanced
Findings: None
What changed in this PR
Adds a native-export marker to the first span of every trace chunk sent to the Datadog Agent.
Changes:
- Adds
_dd.sdk.otlp_export: "false"during trace-chunk conversion. - Documents future OTLP export-mode handling.
- Updates integration snapshots to verify first-span-only placement.
| File | Description |
|---|---|
datadog-opentelemetry/src/ddtrace_transform.rs |
Adds the native export marker. |
datadog-opentelemetry/src/span_exporter.rs |
Documents future export-mode propagation. |
datadog-opentelemetry/tests/snapshots/tracing_api/test_smoke.json |
Verifies multi-span marker placement. |
datadog-opentelemetry/tests/snapshots/tracing_api/test_remote_span_extraction_propagation.json |
Updates expected trace metadata. |
datadog-opentelemetry/tests/snapshots/tracing_api/test_instrument_error_reporting.json |
Updates expected error-span metadata. |
datadog-opentelemetry/tests/snapshots/opentelemetry_api/test_trace_writer_synchronous_mode.json |
Updates synchronous-export expectations. |
datadog-opentelemetry/tests/snapshots/opentelemetry_api/test_stats_cardinality_limit.json |
Updates each expected trace chunk. |
datadog-opentelemetry/tests/snapshots/opentelemetry_api/test_sampling_extraction.json |
Updates sampling expectations. |
datadog-opentelemetry/tests/snapshots/opentelemetry_api/test_remote_config_sampling_rates.json |
Updates remote-sampling expectations. |
datadog-opentelemetry/tests/snapshots/opentelemetry_api/test_received_traces.json |
Updates received-trace expectations. |
datadog-opentelemetry/tests/snapshots/opentelemetry_api/test_injection_extraction.json |
Updates propagation expectations. |
datadog-opentelemetry/tests/snapshots/opentelemetry_api/test_injection_extraction_extract_behavior_restart_single_context.json |
Updates restart-mode expectations. |
datadog-opentelemetry/tests/snapshots/opentelemetry_api/test_injection_extraction_extract_behavior_restart_multiple_contexts.json |
Updates multi-context expectations. |
datadog-opentelemetry/tests/snapshots/opentelemetry_api/test_injection_extraction_extract_behavior_restart_child_not_relinked.json |
Updates child-link expectations. |
datadog-opentelemetry/tests/snapshots/opentelemetry_api/test_injection_extraction_extract_behavior_ignore.json |
Updates ignore-mode expectations. |
datadog-opentelemetry/tests/snapshots/opentelemetry_api/test_baggage_with_trace_context_applies_baggage_span_tags.json |
Updates baggage expectations. |
datadog-opentelemetry/tests/snapshots/opentelemetry_api/test_baggage_only_no_trace_context_applies_baggage_span_tags.json |
Updates baggage-only expectations. |
datadog-opentelemetry/tests/snapshots/opentelemetry_api/test_baggage_not_applied_to_non_local_root_child.json |
Updates non-local-root expectations. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This branch has not been deployed
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.
What does this PR do?
This adds
_dd.sdk.otlp_export: "false"to the meta of the first span of each trace chunk exported to the Datadog agent.otel_trace_chunk_to_dd_trace_chunk(datadog-opentelemetry/src/ddtrace_transform.rs), inside the per-span conversionmap: the span at index 0 of the chunk gets it through a smalladd_native_export_markerhelper.span_exporter.rsexport_trace_chunkscalls it once perTraceChunk, andspan_processor.rsfinish_spankeeps the local root at index 0.export_trace_chunksnote that the export mode must be passed in once OTLP trace export is added.SDK_OTLP_EXPORT_KEYinddtrace_transform.rs.mainonly exports traces in v0.4 format to the agent (TraceExporterOutputFormat::V04), and it doesn't guard against a user tag with the same key. That matches the other tracers.Motivation
This is part of the "Measuring Adoption of Datadog SDKs in OTel Mode (Traces)" RFC. Today the backend infers which spans came from Datadog SDKs exporting OTLP at ingest time, using
telemetry.sdk.nameandspan_source. That's unreliable: the OpenTelemetry Collector'sdatadogreceiverhardcodestelemetry.sdk.name:Datadogon native payloads it converts. So tracers now declare their export mode on the wire."true"goes on the OTLP resource when exporting over OTLP, and"false"goes on the first span of each chunk for native export. An absent marker means an older tracer.Additional Notes
Interaction with #251 (OTLP trace export): #251 sends the same converted Datadog spans through libdatadog's OTLP path, and libdatadog's OTLP mapper copies every
metaentry into the OTLP span attributes. So once it lands,otel_trace_chunk_to_dd_trace_chunkneeds the export mode passed in, and must skip the marker for OTLP. The right value is the exporter'sotlp_export_active, notconfig.otlp_traces_enabled(): on thegrpcfallback, #251 exports natively even though OTLP is configured. The OTLP side,_dd.sdk.otlp_export: "true"anddatadog.sdk.semanticsas resource attributes, needs libdatadog to emit them on the OTLP resource, so it's out of scope here.Partial flush: later chunks of the same trace start with a non-root span. That span still gets the marker, which matches "first span of each chunk" in the other tracers.
Tests:
datadog-opentelemetry/tests/snapshots/gain one line per trace chunk for the marker, on the first span only. No other snapshot content changed. These cover the marker; there are no separate unit tests.cargo test -p datadog-opentelemetry(383 unit, 48 integration and 11 other tests, including the Docker snapshot tests),cargo fmt --check,cargo clippy -p datadog-opentelemetry --all-targets.Related changes:
_dd.sdk.otlp_exportfrom Tracer to Intake datadog-agent#56749 hoists the marker from the first span of the first chunk into the payload.This change was written with AI assistance and reviewed before submission.
🤖 Generated with Claude Code