Skip to content

feat(otel): Enable improved OTel trace compatibility via opt-in configuration#18495

Draft
zacharycmontoya wants to merge 26 commits into
mainfrom
zach.montoya/otel-trace-compatibility
Draft

feat(otel): Enable improved OTel trace compatibility via opt-in configuration#18495
zacharycmontoya wants to merge 26 commits into
mainfrom
zach.montoya/otel-trace-compatibility

Conversation

@zacharycmontoya

@zacharycmontoya zacharycmontoya commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds a configuration to process spans as closely as possible to the OTel SDK. The result is that using OpenTelemetry Tracing instrumentations allows DD SDKs to produce OTLP spans with nearly identical span fields.

When enabled, this updates the dd-trace-py behavior in the following ways:

  • Configures the libdatadog native trace exporter with enable_otel_trace_semantics() (see the related libdatadog PR for specific attribute changes)
  • OtelSpan.set_attribute no longer remaps span tags such as http.response.status_code or service.name so they will maintain their intended key and value type
  • OtelSpan.record_exception no longer sets span attributes error.message, error.type, or error.stack. These exist on the exception span event and will be recognized by Error Tracking
  • OtelSpan.record_exception sets the attribute exception.stacktrace on the exception span event to align with OpenTelemetry
  • The OTel span will not have span attribute span.kind

This PR also enables native span events when OTLP traces export is enabled via OTEL_TRACES_EXPORTER=otlp because OTLP spans have a first-class events field.

Relies on DataDog/libdatadog#2091 to implement the OTLP trace exporter changes

// TODO: Fix the exception.type change so it only applies when the OTel compatibility mode is enabled

Testing

Unit tests are included for the updated OTel test span behavior and the native span events configuration

Risks

Besides the native span events change, the remaining changes are opt-in so the risk is low.

Additional Notes

Currently the libdatadog dependency is set to a development branch which contains the updated TraceExporterBuilder::enable_otel_trace_semantics() API

zacharycmontoya and others added 14 commits June 4, 2026 13:34
…LED.

When enabled, the tracer will not attempt to remap known OpenTelemetry attributes when handling OTEL spans and instead preserve them. A unit test has been added to assert that `otelspan.set_attribute("http.response.status_code", 200)` maintains both the original attribute key AND value (an integer)
…. Requires an updated libdatadog dependency as this is configured via a new interop call in the TraceExporterBuilder
…ontoya/otlp-compatibility-mode to consume the new native changes
…export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ER=otlp

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ve span events

Adds the _trace_native_span_events private field to the type stub for AgentConfig and adds a test case documenting that multi-exporter OTEL_TRACES_EXPORTER strings (e.g. "otlp,zipkin") intentionally do NOT trigger auto-enable, only the exact value "otlp" does.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… behaviors:

- Do not set error tracking tags on the main span (they exist on the span event)
- Add the attribute 'exception.stacktrace' to the exception span event
…here builtins is not included in the module name

Note: This could be considered a breaking change as the signature of the error will be updated.
@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Pipelines  Tests

Fix all issues with BitsAI

⚠️ Warnings

🚦 11 Pipeline jobs failed

DataDog/apm-reliability/dd-trace-py | build linux serverless: [amd64, cp315-cp315, v113741238-d2b8243-manylinux2014_x86_64, 1]   View in Datadog   GitLab

DataDog/apm-reliability/dd-trace-py | build linux serverless: [amd64, cp315-cp315, v113741491-d2b8243-musllinux_1_2_x86_64, 1]   View in Datadog   GitLab

DataDog/apm-reliability/dd-trace-py | build linux serverless: [arm64, cp315-cp315, v113741357-d2b8243-manylinux2014_aarch64, 1]   View in Datadog   GitLab

View all 11 failed jobs.

ℹ️ Info

No other issues found (see more)

🧪 All tests passed
❄️ No new flaky tests detected

🔄 Datadog auto-retried 1 job - 0 passed on retry View in Datadog

Useful? React with 👍 / 👎

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

Comment thread ddtrace/internal/settings/_agent.py Outdated
Comment thread ddtrace/internal/opentelemetry/span.py Outdated
@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codeowners resolved as

src/native/Cargo.lock                                                   @DataDog/apm-core-python

@pr-commenter

pr-commenter Bot commented Jun 8, 2026

Copy link
Copy Markdown

Benchmarks

Benchmark execution time: 2026-06-12 01:52:04

Comparing candidate commit c68a85b in PR branch zach.montoya/otel-trace-compatibility with baseline commit 58ac3af in branch main.

Found 0 performance improvements and 4 performance regressions! Performance is the same for 613 metrics, 10 unstable metrics.

scenario:httppropagationinject-ids_only

  • 🟥 execution_time [+1.452µs; +1.632µs] or [+7.100%; +7.980%]

scenario:iastaspects-swapcase_aspect

  • 🟥 execution_time [+40.273µs; +46.630µs] or [+11.797%; +13.659%]

scenario:iastaspectsospath-ospathbasename_aspect

  • 🟥 execution_time [+102.159µs; +110.289µs] or [+23.795%; +25.689%]

scenario:span-start

  • 🟥 execution_time [+1.404ms; +1.553ms] or [+9.060%; +10.025%]

# We will not set the exception.stacktrace attribute, this will reduce the size of the span event
# https://github.com/open-telemetry/opentelemetry-python/blob/v1.25.0/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py#L1018
module = type(exception).__module__
qualname = type(exception).__qualname__

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Using __qualname__ is a semantic change from using __name__.

I think that __qualname__ is more accurate: it captures nested exception class names, but a change nevertheless.

I think we'd need someone with more Python experience to know the write answer here.
But leaving it as __name__ is always an option, to avoid changing behaviour.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@mabdinur do you have an opinion here?
The otel spec for exception.type says (link):

The type of the exception (its fully-qualified class name, if applicable).

__qualname__ will return a fully nested exception class, unlike __name__, but it's a change on the error type.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm happy to keep the name update behind a feature flag, but I think we should update our tracer to write the fully qualified type name

Comment thread ddtrace/internal/native/_native.pyi Outdated
def enable_otel_trace_compatibility(self) -> TraceExporterBuilder:
"""
Enable OTel trace compatibility mode: omit DD-specific per-span attributes
(service.name, operation.name, resource.name, span.type) from the OTLP payload.

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.

Is this an exhaustive list? I expect we'll add more values as we align more with otel sematnics.

Suggested change
(service.name, operation.name, resource.name, span.type) from the OTLP payload.
(ex: service.name, operation.name, resource.name, span.type) from the OTLP payload.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This should almost be exhaustive. In my testing at https://github.com/DataDog/evalya/pull/767 this almost fully aligns FastAPI spans when using the OTel instrumentation, so if there are any further attributes that need to be modified then I expect they will be small in number

Comment thread ddtrace/internal/opentelemetry/span.py Outdated
@@ -0,0 +1,71 @@
# Design: Suppress DD error tags in `record_exception` when OTel compatibility mode is enabled

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.

Are these doc changes intentional?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No, I'll remove the docs file changes

@zacharycmontoya zacharycmontoya force-pushed the zach.montoya/otel-trace-compatibility branch from a6560fb to a2d179a Compare June 9, 2026 17:32
@zacharycmontoya zacharycmontoya force-pushed the zach.montoya/otel-trace-compatibility branch from 10a9453 to 3869cc9 Compare June 12, 2026 01:12
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