Repository navigation
Conversation
…ty working Selecting a standalone sampler only when ASM/IAST/SCA is enabled left every other DD_APM_TRACING_ENABLED=false configuration on the default sampler, which keeps traces, so APM traces kept flowing. Drop them instead, as dd-trace-js and dd-trace-py do; LLM Observability spans are unaffected because they ship to the LLM Observability intake, which is independent of APM sampling priority. DD_TRACE_ENABLED=false installed the real LLM Observability SDK with no tracer to back it, and the no-op tracer's buildSpan() returns null, so every LLMObs.start*Span() call threw out of application code. Keep the SDK no-op. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
🟢 Java Benchmark SLOs — All performance SLOs passed
PR vs. master results
Commit: Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion. |
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The two new Groovy smoke tests would have needed the `tag: override groovy enforcement` label. What they proved end-to-end — a dropped APM trace is still handed to the writers, which is how LLM Observability spans still reach their intake — is now asserted in SamplerTest instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
sabrenner
left a comment
There was a problem hiding this comment.
makes sense for agent obs, probably just needs java tracer signoff!
There was a problem hiding this comment.
A sampled parent can lock a keep priority before the new sampler runs. The sampler then fails to drop that normal APM trace when APM tracing is off.
🤖 Datadog Autotest · Commit 5923093 · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 592309351a
ℹ️ 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".
mhlidd
left a comment
There was a problem hiding this comment.
One comment about expected behavior
…d no product marked the trace Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
7860cdc to
80e580e
Compare
mhlidd
left a comment
There was a problem hiding this comment.
LGTM following addressing Codex and Copilot comments 👍
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
The new drop sampler cannot replace manual keep decisions. APM traces can still leave the process when APM tracing is off. Remote AppSec activation and shutdown after single-span sampling also have trace-loss paths.
🤖 Datadog Autotest · Commit fe764e7 · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…sabled Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a153f2dacf
ℹ️ 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".
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jandro996
left a comment
There was a problem hiding this comment.
LGTM! thanks for the changes!
…lisecond Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
With APM tracing disabled, configured span sampling can leave LLMObs spans undelivered at shutdown. Mixed propagation formats can also lose product keep decisions, and repeated ASM sampling can overwrite the service-catalog keep.
🤖 Bits Code Review · Commit 56f612a
What Does This Do
Two fixes for running LLM Observability without APM tracing (solves #10051):
DD_APM_TRACING_ENABLED=falsenow drops APM traces. The standalone sampler was only selected when ASM/IAST/SCA was enabled; every other configuration — including LLM Observability — fell through to the default sampler, which keeps traces, so APM traces kept flowing. On distributed traces the drop was defeated a second way: an extracted sampling priority is locked onto the span context at construction, so a request arriving withx-datadog-sampling-priority: 1silenced the drop before it was ever decided locally.DD_TRACE_ENABLED=falsewithDD_LLMOBS_ENABLED=trueno longer throws.LLMObsSystem.start()installed the real SDK implementation even with no tracer installed, andAgentTracer.get().buildSpan()returnsnullon the no-op tracer, so everyLLMObs.start*Span()call threw aNullPointerExceptionout of application code. The SDK now stays no-op unless a tracer is installed — including the CI Visibility case, which installs one even withDD_TRACE_ENABLED=false.Motivation
DD_APM_TRACING_ENABLED=falseis documented as working in all SDKs. LLM Observability users who don't want APM tracing had no working way to turn it off: the APM flag was a no-op, andDD_TRACE_ENABLED=falsebroke the LLMObs SDK.Additional Notes
Approach. This is a reduced port of #10989, which had gone stale. That PR introduced a
ProductTraceSource.LLMOBSbit plus aStandaloneProductenum and a unifiedStandaloneSamplerreplacingAsmStandaloneSampler. Neither is needed:0x20is now taken byAI_GUARD, no other tracer allocates an LLMObs_dd.p.tsbit (dd-trace-js and dd-trace-py both have exactlyAPM/ASM/DSM/DJM/DBM/AI_GUARD), and LLMObs spans ship to the LLM Observability intake (/evp_proxy/v2/api/v2/llmobs), which is independent of APM sampling priority. That leaves the selection logic other tracers already have — comparegetProductRateLimiterin dd-trace-js andLLMObsProcessor.process_tracein dd-trace-py:AsmStandaloneSampler: 1 APM trace per minute for the service catalog.ApmTracingDisabledSampler: drops every APM trace, but still hands it to the writers, which is what keeps the LLM Observability spans riding on it flowing to their own intake. It re-readsActiveSubsystems.APPSEC_ACTIVEper trace, because Remote Configuration can activate AppSec after the sampler was built, and falls back to the ASM trickle when that happens.Sampling priority. Three things could outrank the drop, and each is now handled narrowly:
DDSpanContextlocks an extracted priority at construction, so the drop-all vote was silently refused on exactly the distributed traces the flag exists to suppress.ContextInterpreter.samplingPriorityOrDefaultnow leaves itUNSETwhen APM tracing is disabled and no product marked the trace (no_dd.p.ts), letting the local sampler decide — the same shape as dd-trace-js' standaloneonSpanExtracthook. It sits inContextInterpreterbecause every propagation style funnels through it, including Haystack, whosedefaultSamplingPriority()override manufactures aSAMPLER_KEEPout of headers that carry no priority at all.manual.keep. It force-keeps the span before the sampler ever votes, which left the trace indexed and billed as APM. The drop is now exempt from the priority lock inSamplingMechanism.canAvoidSamplingPriorityLock. The exemption is limited to a drop — aDEFAULTkeep still cannot override a priority someone else set — and matches dd-trace-js, whose standalone sampler honorsmanual.keeponly alongside a product trace source.DATA_JOBSpriority and has no_dd.p.tsbit set to protect it, so the drop would silently discard Spark traces.ASM and AI Guard are unaffected throughout:
TraceCollector.setSamplingPriorityIfNecessaryalready skips the sampler for_dd.p.ts-marked traces, soasm.keepandai_guard.keepkeep working exactly as before, whichAIGuardSamplingTestcovers.Flush.
TraceProcessingWorkernow sweeps the secondary queue before completing a flush. The flush marker is only ever offered to the primary queue, so a trace published to the secondary queue could still be sitting there whenflush()returned andclose()interrupted the serializer thread. That was harmless for a sampled-out APM trace, but a dropped trace now carries LLM Observability spans that have to reach their intake regardless.Testing.
SamplerTest: APM traces are dropped when APM tracing is disabled, with and without LLM Observability enabled, and the dropped trace is still handed to the writers;manual.keepis overridden, but honored on ASM-marked traces; a Data Jobs keep survives; the ASM trickle resumes when AppSec is activated at runtime.LLMObsSystemTest: the SDK stays no-op when tracing is disabled.DatadogHttpExtractorTest.ApmTracingDisabled: an upstreamSAMPLER_KEEPis dropped when no product marked the trace, and preserved when_dd.p.tsis set.TraceProcessingWorkerTest: a trace sitting in the secondary queue is dispatched by a flush.AIGuardSamplingTest,ApmTracingDisabledChunkMarkerTestand theapm-tracing-disabledsmoke tests pass unchanged.Contributor Checklist
type:and (comp:orinst:) labels in addition to any other useful labelsclose,fix, or any linking keywords when referencing an issueClaude session:
ba8ff7f0-b73e-41d6-a806-3603ab1c7329Resume:
claude --resume ba8ff7f0-b73e-41d6-a806-3603ab1c7329🤖 Generated with Claude Code