Skip to content

Add OTLP trace export via the sidecar (OTEL_TRACES_EXPORTER=otlp)#3971

Draft
bm1549 wants to merge 4 commits into
masterfrom
brian.marks/otlp-trace-export
Draft

Add OTLP trace export via the sidecar (OTEL_TRACES_EXPORTER=otlp)#3971
bm1549 wants to merge 4 commits into
masterfrom
brian.marks/otlp-trace-export

Conversation

@bm1549

@bm1549 bm1549 commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Description

Adds OTLP trace export to dd-trace-php. When OTEL_TRACES_EXPORTER=otlp is set, the extension resolves the OTLP traces endpoint/headers/timeout and passes them to the libdatadog sidecar, which exports this session's traces over OTLP http/json via libdatadog's TraceExporter instead of the Datadog agent MessagePack path. This mirrors the existing OTLP metrics plumbing.

Configuration:

  • OTEL_TRACES_EXPORTERotlp enables OTLP export; none disables tracing
  • OTEL_EXPORTER_OTLP_TRACES_ENDPOINT → fallback OTEL_EXPORTER_OTLP_ENDPOINT + /v1/traces → default http://<agent_host>:4318/v1/traces
  • OTEL_EXPORTER_OTLP_TRACES_HEADERS / _TIMEOUT (10s) / _PROTOCOL (only http/json honored this phase; warns otherwise)

Behavior: DD_TRACE_AGENT_PROTOCOL_VERSION disables OTLP; only sampled spans are exported (libdatadog drop_chunks); the agent path (and Remote Config) is unchanged when OTLP is off.

⚠️ Depends on the libdatadog sidecar change (DataDog/libdatadog brian.marks/otlp-trace-export) — the bundled libdatadog submodule is bumped to that branch for development. Before merge, the libdatadog change must land + release and the submodule must be re-bumped to the released commit. See Related PRs.

Reviewer checklist

  • Test coverage seems ok.
  • Appropriate labels assigned.

Tests: extension-side config plumbing + the libdatadog FFI wiring; .phpt tests under tests/ext/otlp_traces_*.phpt; the Rust glue (components-rs) builds and unit-tests pass. Full .phpt end-to-end + extension build run in CI. End-to-end coverage added in system-tests (Test_Otel_Tracing_OTLP, activated for php). Scope is RFC "OTLP Traces Export 2026Q1" Phase 1 (http/json only).

Related PRs (cross-language OTLP traces export):

Merge order: libdatadog #2101 → dd-trace-php #3971 (re-bump the submodule to the released libdatadog commit). system-tests #7121 validates rust/ruby/php once the tracer branches are available.

🤖 Generated with Claude Code

bm1549 and others added 4 commits June 9, 2026 18:44
Add config plumbing for OTLP trace export, triggered by
OTEL_TRACES_EXPORTER=otlp, mirroring the existing OTLP metrics endpoint
path.

Configuration:
- OTEL_TRACES_EXPORTER=otlp now enables OTLP trace export via a new
  DD_TRACE_OTLP_ENABLED config (previously only "none" was handled).
- OTEL_EXPORTER_OTLP_TRACES_ENDPOINT used as-is; falls back to
  OTEL_EXPORTER_OTLP_ENDPOINT (trailing slash stripped, /v1/traces
  appended); computed default http://<agent_host>:4318/v1/traces.
- OTEL_EXPORTER_OTLP_TRACES_HEADERS / _TIMEOUT / _PROTOCOL parsed and
  reported, with fallbacks to the non-signal-specific OTEL_EXPORTER_OTLP_*
  variants. Only http/json is honored for the protocol.
- All new configs flow through config telemetry like any other entry.

Gates:
- OTLP trace export is enabled iff OTEL_TRACES_EXPORTER=otlp.
- DD_TRACE_AGENT_PROTOCOL_VERSION being set disables OTLP trace export
  (the agent trace protocol version takes precedence); a notice is logged.
- Agent interaction (/info, Remote Config, telemetry) is unaffected: the
  OTLP traces endpoint is kept separate from the agent endpoint, exactly
  as the OTLP metrics endpoint already is.

Sampler:
- OTEL_TRACES_SAMPLER mapping to the DD sample rate now warns when a
  non-parentbased sampler is mapped to its parentbased equivalent.

Wiring:
- New Rust glue (components-rs): datadog_otel_traces_endpoint_from_url /
  _from_agent_url build the endpoint; ddog_sidecar_session_set_otlp_traces_endpoint /
  _clear register the resolved endpoint/headers/timeout per session.
- ext/sidecar.c forwards the resolved OTLP traces endpoint to the sidecar
  in dd_sidecar_post_connect, alongside the OTLP metrics endpoint.

Note: the libdatadog submodule is intentionally not modified. The sidecar's
trace flush path (TraceFlusher/SendData to the agent endpoint) and the
ddog_sidecar_session_set_config SessionConfig live in libdatadog and would
need changes there to consume the registered OTLP traces endpoint via the
OTLP TraceExporter. This change delivers the complete extension-side config
plumbing and the FFI surface to carry the endpoint to the sidecar.

Tests:
- Rust unit tests for the endpoint builders and the session-config registry
  (components-rs).
- .phpt tests: OTEL_TRACES_EXPORTER=otlp selection, endpoint fallback,
  explicit endpoint/headers/timeout/protocol, the
  DD_TRACE_AGENT_PROTOCOL_VERSION disable gate, and exporter=none.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Connect the extension's resolved OTLP traces config to libdatadog's new sidecar
OTLP path, replacing the dead-end process-local OTLP_TRACES_CONFIG registry that
the prior groundwork wired but never consumed.

- ext/sidecar.c: in dd_sidecar_post_connect, build the OTLP traces ddog_Endpoint
  (datadog_otel_traces_endpoint) when OTLP trace export is enabled and pass it,
  with headers/timeout, into the new libdatadog FFI
  ddog_sidecar_session_set_otlp_traces_endpoint(transport, ...). A NULL endpoint
  clears the config and keeps the default agent path. Mirrors the OTLP metrics
  endpoint plumbing.
- components-rs/sidecar.rs: remove the dead-end OtlpTracesConfig registry and the
  old URL-based ddog_sidecar_session_set/clear_otlp_traces_endpoint stubs; the
  real symbol now comes from datadog-sidecar-ffi.
- ext/endpoints.c/.h: drop the now-unused datadog_otel_traces_url helper; the
  endpoint builder (datadog_otel_traces_endpoint) is what the sidecar FFI needs.
- Bump libdatadog submodule to the matching OTLP TraceExporter commit.
- Regenerate components-rs headers (cbindgen 0.29.0 + dedup): sidecar.h gains the
  new FFI declaration; datadog.h drops the removed stubs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bumps the libdatadog gitlink to pick up the OTLP encoder fallback that
derives `deployment.environment.name` / `service.version` resource
attributes from span meta for the sidecar OTLP traces path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…notice

- Warn when OTEL_TRACES_EXPORTER=otlp is set but the OTLP traces endpoint
  can't be resolved (was a silent fallback to the agent path).
- Warn on a configured non-http/json OTLP protocol (only http/json is
  supported this phase), matching dd-trace-rs/rb, so it isn't a silent no-op.
- Clamp a negative OTEL_EXPORTER_OTLP_TRACES_TIMEOUT to 0 (FFI default)
  instead of wrapping to a huge uint64.
- Strengthen the agent-url endpoint test to assert Some rather than passing
  vacuously.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@bm1549 bm1549 added the AI Generated Largely based on code generated by an AI or LLM. This label is the same across all dd-trace-* repos label Jun 10, 2026
@datadog-prod-us1-4

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

Copy link
Copy Markdown

Pipelines  Tests

Fix all issues with BitsAI

⚠️ Warnings

🚦 233 Pipeline jobs failed

DataDog/apm-reliability/dd-trace-php | Configuration Consistency   View in Datadog   GitLab

DataDog/apm-reliability/dd-trace-php | Extension Tea Tests: [7.0, debug-zts]   View in Datadog   GitLab

DataDog/apm-reliability/dd-trace-php | Extension Tea Tests: [7.0, debug]   View in Datadog   GitLab

View all 233 failed jobs.

ℹ️ Info

No other issues found (see more)

🧪 All tests passed
❄️ No new flaky tests detected

🔄 Datadog auto-retried 2 jobs - 0 passed on retry View in Datadog

Useful? React with 👍 / 👎

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI Generated Largely based on code generated by an AI or LLM. This label is the same across all dd-trace-* repos

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant