feat(llmobs): propagate session_id across distributed traces [MLOB-7756]#5011
feat(llmobs): propagate session_id across distributed traces [MLOB-7756]#5011ncybul wants to merge 5 commits into
Conversation
Add session_id to the LLMObs propagating tag set (_dd.p.llmobs_session_id), mirroring ml_app: inject the active span's resolved session, extract it into PropagatedLLMSpan, and fall back to the propagated session in propagatedSessionID. A downstream service's LLM spans now inherit the session_id set upstream; an explicit session_id still takes precedence. MLOB-7756 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Config Audit |
🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: 4239375 | Docs | Datadog PR Page | Give us feedback! |
BenchmarksBenchmark execution time: 2026-07-15 12:16:43 Comparing candidate commit 6eea11e in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 326 metrics, 0 unstable metrics, 1 flaky benchmarks without significant changes.
|
Matches the wire contract agreed in dd-trace-py#18952: keep the llmobs_ namespace, shorten session_id -> sid to conserve x-datadog-tags budget. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9d5e22ef4f
ℹ️ 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".
LLMObs propagation tags are trace-scoped, so a session-bearing span's _dd.p.llmobs_sid lingered when a later active LLM span had no session, causing downstream services to inherit an unrelated session. Unset the tag when the active span has no session, mirroring keyPropagatedUserID. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
We need a stamp from @DataDog/ml-observability |
What Does This Do
Adds LLMObs
session_idto the cross-service propagation set (_dd.p.llmobs_sid), so a downstream service's LLM spans inherit thesession_idset on an upstream service's span. Mirrors the existingml_apppropagation and the dd-trace-py change in dd-trace-py#18952.Changes
internal/llmobs/context.go— addSessionIDtoPropagatedLLMSpan.internal/llmobs/span.go— addSessionID()accessor;propagatedSessionIDfalls back tos.propagated.SessionID(mirrorspropagatedMLApp).ddtrace/tracer/span.go— addkeyPropagatedLLMObsSessionID(_dd.p.llmobs_sid); inject the active span's resolved session insetLLMObsPropagatingTags(only when non-empty, to conservex-datadog-tagsbudget).ddtrace/tracer/context.go— extract_dd.p.llmobs_sidinpropagatedLLMSpanFromTags.The tag key
_dd.p.llmobs_sidmatches the wire contract agreed across SDKs (dd-trace-py, dd-trace-js): thellmobs_namespace is kept (consistent with_dd.p.llmobs_parent_id/_ml_app/_trace_id) whilesession_idis shortened tosidto conserve thex-datadog-tagsbudget.An explicit
session_idon a span still takes precedence over a propagated one.Scope note
This PR is cross-service propagation only. It does not add the in-process "trace-level default" (a sibling under a session-less parent inheriting the trace's session), which py/js get via their trace-shared propagating bag. In go,
internal/llmobscan't reach the tracer's trace-level propagating tags (one-way import boundary), so a trace default would need a separate trace-scoped store with lifecycle management — deferred as a follow-up. Go already covers the common case (session on the root span → all descendants inherit via the parent-chain walk).Testing
Simulating a distributed session (trace)
session_id:my-sessionset in service A which calls service B and inherits the same session IDSimulating session inheritance in a trace unless explicitly annotated (trace)
session_id:my-sessionwhich is inherited by its children spans except those explicitly annotated withsession_id:other-sessionMLOB-7756