Add trace.builder.tags.precedence.enabled to let explicit builder tags win#11738
Draft
dougqh wants to merge 1 commit into
Draft
Add trace.builder.tags.precedence.enabled to let explicit builder tags win#11738dougqh wants to merge 1 commit into
dougqh wants to merge 1 commit into
Conversation
…s win
Today the span builder applies tag contributors in this last-wins order:
mergedTracerTags, tagLedger (builder tags), coreTags (inbound header tags),
rootSpanTags, contextualTags. So inbound header / root-span / contextual tags
silently OVERRIDE explicit per-span tags set via the builder -- a wart flagged
in-code by Björn since 2020 ("maybe the builder tags should come last").
This adds an off-by-default flag that applies the ledger LAST so explicit
builder tags take precedence (the logical order), gated for gradual rollout.
The flag is a constant-folded `static final` (mirroring SPAN_BUILDER_REUSE_ENABLED)
so the JIT dead-code-eliminates the unused ordering branch on the hot span-build
path -- the flag is process-constant.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
🟢 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. |
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.
Floating an idea — feedback welcome before this is hardened
This is a draft to float a precedence fix behind an off-by-default flag. Looking for reactions to the concept (and the rollout plan) before investing in telemetry + a forked on-path test.
The wart
At span build, tag contributors are applied last-wins in this order:
So inbound-header / root-span / contextual tags silently override explicit per-span tags set via the builder. This is illogical — the explicit, more-specific tag should win — and it's been flagged in-code since 2020 (
git blame: Björn): "maybe thetagsset in the builder should come last, so that they override other tags."Provenance audit (is it a wart or load-bearing?)
coreTagsTagContext.getTags())rootSpanTags_dd.*)contextualTagsDDSpanContext— the common non-root case),coreTagsandrootSpanTagsare bothnull, so the hazard can only occur on root / extraction-path spans.rootSpanTags(process identity), but those are_dd./runtime-namespaced tags users don't set on a builder → real collision ≈ 0.coreTags(header tags) colliding with explicit instrumentation tags is exactly the case where the builder tag should win.Conclusion: documented long-standing wart, safe to correct, low blast radius.
The change
Off-by-default flag
trace.builder.tags.precedence.enabled. When enabled, the ledger is applied last so explicit builder tags win:BUILDER_TAGS_PRECEDENCEis a constant-foldedstatic final(mirroringSPAN_BUILDER_REUSE_ENABLEDright above it), so the JIT dead-code-eliminates the unused ordering branch on the hot span-build path — the flag is process-constant, so there's no per-span branch cost."Does any existing test assert the old order?"
Ran the span-builder + interceptor suites with the logical order forced on:
CoreSpanBuilderTest— passestaginterceptor.*— passBuilderTagsPrecedenceTest(pins the default order) — flips, confirming the flag works + propagates→ nothing in those suites asserts the historical order. (The full
dd-trace-coresuite isn't a clean instrument locally — writer/intake/serialization/testcontainer tests fail for env reasons regardless of this flag — so the full-suite check is deferred to CI.)Proposed rollout (the point of the flag)
flag default-off → opt-in canary → telemetry on the real collision rate (root spans only) → flip default → remove the historical path + flag. The collision-rate counter is not yet built — intentionally deferred until the concept lands.
Testing
BuilderTagsPrecedenceTestcharacterizes the default (off) order (green).static final) is a TODO once the concept is agreed.tag: ai generated· default-off, no behavior change unless explicitly enabled.🤖 Generated with Claude Code