Skip to content

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

Draft
dougqh wants to merge 2 commits into
masterfrom
dougqh/direction-scoped-gettag
Draft

dougqh wants to merge 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.

This branch has not been deployed

No deployments
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.

1 participant