Skip to content

Resolve direction-scoped OpenTelemetry names when reading span tags (OTLP/tag registry) - #12972

Merged
gh-worker-dd-mergequeue-cf854d[bot] merged 2 commits into
masterfrom
dougqh/direction-scoped-gettag
Oct 21, 2026
Merged

gh-worker-dd-mergequeue-cf854d[bot] merged 2 commits into
masterfrom
dougqh/direction-scoped-gettag

Conversation

@dougqh

@dougqh dougqh commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

What Does This Do

Makes getTag and unsafeGetTag resolve OpenTelemetry names whose tag depends on the span's direction, using the span's kind:

Name Inbound (server, consumer) Outbound (client, producer)
server.address http.hostname peer.hostname
server.port server.port (its own tag) peer.port
network.peer.address network.client.ip —
client.port peer.port (the client's port) —

The fallback runs only after a plain lookup misses:

  • Literal name wins: a tag set under the literal name (for example server.address set through the Datadog API, stored as a custom tag) is still returned first.
  • Only null results change: a read that finds something today returns the same value.
  • No direction, no resolution: internal, broker, custom and unset kinds resolve nothing.
  • server.port on outbound spans: server.port is also a Datadog name (the server's own port, set only on inbound spans). On a client or producer span, a read of server.port that misses now returns peer.port, matching its OpenTelemetry meaning there. So a sampling rule such as server.port:5432 matches database client spans. A Datadog-meaning reader can't get a wrong value, because the Datadog server.port tag isn't set on outbound spans.

The direction comes from the cached span-kind ordinal, so the fallback doesn't touch the tag map or take a lock to find it.

Motivation

Tag sampling with OpenTelemetry names. Trace and span sampling rules match tags with span.getTag(name). Today, a rule written with the OpenTelemetry name of a direction-independent rename already works (http.request.method, http.response.status_code, url.full, …), because TagMap maps OTel names to Datadog names on lookup. But a rule on server.address silently never matched, because KnownTagCodec.keyOf deliberately returns 0 for direction-scoped names. Resolving direction was only done at the OpenTelemetry boundary, on writes.

Checked on master before this change, with a probe against real spans:

  • http.method vs http.request.method: match;
  • http.status_code vs http.response.status_code:2*: match;
  • server.address on server spans (http.hostname) and on client spans (peer.hostname): no match.

Timing: sampling decides at the first inject or at the root's finish (trace sampling), or at span finish (span sampling). By then, decorators, span prototypes or the OpenTelemetry span builder have set span.kind.

Additional Notes

  • Cost: none on hits. On a miss with a known direction, one extra registry lookup (directionalKeyOf). Internal readers are moving to tag ids, so the name path being a little slower on misses is acceptable.
  • Tests (DDSpanContextTest):
    • resolution on server, consumer, client and producer spans;
    • no resolution where the name names no tag (an outbound-only rename on a server span, and the reverse), or the span is internal or broker, or has no kind;
    • the literal name wins;
    • a sampling rule on server.address matches a client span through TagsMatcher.
  • Local run: full dd-trace-core; the only failures are the two Docker-based tests (no Docker locally).
  • Overlap: Split TagMap into id and name stores, owned directly by the span #12918 rewrites DDSpanContext's tag storage. This fallback is a few lines and moves easily with it.

Jira ticket: [PROJ-IDENT]

🤖 Generated with Claude Code

dougqh and others added 2 commits October 20, 2026 21:45
getTag and unsafeGetTag already resolve an OpenTelemetry name to its
Datadog tag when the name means the same tag in every direction. Names
whose tag depends on the span's direction (server.address is
http.hostname inbound and peer.hostname outbound) found nothing, so a
sampling rule on server.address never matched.

After a plain lookup misses, resolve such a name by the span's kind,
using the cached span-kind ordinal. A tag set under the literal name
still wins, and spans with no direction resolve nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dougqh dougqh added type: feature Enhancements and improvements comp: core Tracer core tag: ai generated Largely based on code generated by an AI or LLM labels Oct 21, 2026
@datadog-official

This comment has been minimized.

@dougqh dougqh changed the title Resolve direction-scoped OpenTelemetry names when reading span tags Resolve direction-scoped OpenTelemetry names when reading span tags (OTLP/tag registry) Oct 21, 2026
@dd-octo-sts

dd-octo-sts Bot commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

🟢 Java Benchmark SLOs — All performance SLOs passed

Suite Status
Startup 🟢 pass

SLO thresholds are defined here based on automatically generated metrics. A warning is raised when results are within 5% of the threshold.

PR vs. master results
Scenario Candidate master Δ (95% CI of mean)
startup:insecure-bank:iast:Agent 14.65 s 14.63 s [-0.5%; +0.8%] (no difference)
startup:insecure-bank:tracing:Agent 13.53 s 13.63 s [-1.6%; +0.2%] (no difference)
startup:petclinic:appsec:Agent 17.17 s 16.98 s [+0.2%; +2.0%] (maybe worse)
startup:petclinic:iast:Agent 17.03 s 16.87 s [+0.1%; +1.8%] (maybe worse)
startup:petclinic:profiling:Agent 16.53 s 16.75 s [-2.2%; -0.4%] (maybe better)
startup:petclinic:sca:Agent 17.02 s 16.83 s [+0.4%; +1.8%] (maybe worse)
startup:petclinic:tracing:Agent 16.10 s 15.68 s [-1.8%; +7.1%] (no difference)

Commit: 81429bf5 · CI Pipeline · Benchmarking Platform UI


Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion.

@dougqh
dougqh marked this pull request as ready for review October 21, 2026 12:12
@dougqh
dougqh requested a review from a team as a code owner October 21, 2026 12:12
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-21T12:16:03.815617Z 81429bf Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@datadog-official datadog-official Bot left a comment

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.

Bits Code Review: PASS

More details

Existing tag values retain precedence, while direction-scoped misses resolve consistently with the registry mappings and cached span kind.

Was this helpful? React 👍 or 👎

Open Bits AI session

🤖 Bits Code Review · Commit 81429bf

@mcculls mcculls left a comment

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.

LGTM

@dougqh
dougqh added this pull request to the merge queue Oct 21, 2026
@dd-octo-sts

dd-octo-sts Bot commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

/merge

@gh-worker-devflow-routing-ef8351

gh-worker-devflow-routing-ef8351 Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

View all feedbacks in Devflow UI.

2026-10-21 13:02:46 UTC ℹ️ Start processing command /merge


2026-10-21 13:02:50 UTC ℹ️ MergeQueue: pull request added to the queue

The expected merge time in master is approximately 1h (p90).


2026-10-21 14:16:45 UTC ℹ️ MergeQueue: This merge request was merged

@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 21, 2026
@gh-worker-dd-mergequeue-cf854d
gh-worker-dd-mergequeue-cf854d Bot merged commit fff28e2 into master Oct 21, 2026
624 of 628 checks passed
@gh-worker-dd-mergequeue-cf854d
gh-worker-dd-mergequeue-cf854d Bot deleted the dougqh/direction-scoped-gettag branch October 21, 2026 14:16
@github-actions github-actions Bot added this to the 1.68.0 milestone Oct 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: core Tracer core tag: ai generated Largely based on code generated by an AI or LLM type: feature Enhancements and improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants