Skip to content

Extract peer-connection tagging into a TagExtractor<InetSocketAddress>#11822

Draft
dougqh wants to merge 3 commits into
dougqh/tag-extractor-apifrom
dougqh/peer-connection-extractor
Draft

Extract peer-connection tagging into a TagExtractor<InetSocketAddress>#11822
dougqh wants to merge 3 commits into
dougqh/tag-extractor-apifrom
dougqh/peer-connection-extractor

Conversation

@dougqh

@dougqh dougqh commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

What

Second TagExtractor canary (stacked on #11817). Lifts the pure peer-connection field→tag logic — peer.hostname / peer.ipv4 / peer.ipv6 / peer.port — out of BaseDecorator.onPeerConnection(...) into PeerConnectionExtractor, a named singleton TagExtractor<InetSocketAddress>.

Why this one

  • It's the extrinsic TagExtractor case — extraction from a JDK type we don't own (InetSocketAddress) — complementing the JDBC canary's intrinsic case (our own DBInfo). Together they exercise both shapes of the API.
  • Bucket (a) pure field-extraction: no service/operation/peer-service derivation, no AppSec/IAST/DSM side-effects — the cleanest, safest slice to start dissolving the hierarchy.
  • It exercises the cache-in-extractor pattern cleanly: the hostName(...) resolver cache becomes a class static the extractor consults (not lambda-captured state) — which is exactly why it's promoted to a named class.

Named singleton class

Promoted from an inline lambda to PeerConnectionExtractor implements TagExtractor<InetSocketAddress> with a private-ctor INSTANCE. Buys a name at call sites (span.setTags(addr, PeerConnectionExtractor.INSTANCE)), a home for the pure statics + the resolver cache, and composability — the axis the Decorator inheritance chain lacked. This is the convention the rest of the dissolution follows.

Scope / honesty

onPeerConnection is a concrete shared base method (52 call sites), not a megamorphic template method — so this is a structural dissolution step and a demonstrator of the extrinsic pattern, largely perf-neutral (it's not one of the per-leaf overridden dispatch sites where the megamorphic cost lives). The dispatch win comes later, from the overridden template methods (see #11823).

Behavior preservation

Identical tag output. Internal plumbing invokes extract() directly (so it runs on Spock test doubles too — a default-method span.setTags wouldn't); the span-first span.setTags(source, extractor) sugar is reserved for hand-written integration call sites. BaseDecoratorTest / ClientDecoratorTest / ServerDecoratorTest pass.

🤖 Generated with Claude Code

Lifts the pure peer-connection field->tag logic (hostname / IPv4 / IPv6 /
port) out of BaseDecorator into a static-final, non-capturing
PEER_CONNECTION_EXTRACTOR. This is the extrinsic TagExtractor case — extraction
from a JDK type we don't own (InetSocketAddress) — complementing the JDBC
canary's intrinsic (owned DBInfo) case.

Behavior-preserving: onPeerConnection(span, InetSocketAddress) now invokes the
extractor (the shared setPeerAddress helper + port), and the hostName resolver
cache is unchanged. Internal plumbing calls extract() directly so it runs on
test doubles; the span-first span.setTags(...) sugar is for hand-written
integration call sites.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dougqh dougqh added the tag: no release notes Changes to exclude from release notes label Jul 1, 2026
Turns the inline lambda into PeerConnectionExtractor (a proper TagExtractor
implementation with a private-ctor INSTANCE singleton). This gives it a name at
call sites (span.setTags(addr, PeerConnectionExtractor.INSTANCE)), makes it
composable with other extractors — the axis the Decorator inheritance chain
lacked — and gives the pure statics + the hostName resolver cache a clean home
(a class static, not lambda-captured state). Behavior unchanged; BaseDecorator
delegates.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dougqh dougqh force-pushed the dougqh/peer-connection-extractor branch from 4601b3b to 07dc157 Compare July 1, 2026 01:08
@datadog-official

datadog-official Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

🎯 Code Coverage (details)
Patch Coverage: 72.22%
Overall Coverage: 54.94% (-0.01%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 175086b | Docs | Datadog PR Page | Give us feedback!

@dd-octo-sts

dd-octo-sts Bot commented Jul 1, 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 13.88 s 14.07 s [-2.1%; -0.6%] (maybe better)
startup:insecure-bank:tracing:Agent 12.93 s 13.00 s [-1.4%; +0.4%] (no difference)
startup:petclinic:appsec:Agent 16.84 s 16.83 s [-0.9%; +1.1%] (no difference)
startup:petclinic:iast:Agent 16.31 s 16.98 s [-8.2%; +0.3%] (no difference)
startup:petclinic:profiling:Agent 16.94 s 16.94 s [-1.2%; +1.2%] (no difference)
startup:petclinic:sca:Agent 16.93 s 16.30 s [-0.5%; +8.2%] (no difference)
startup:petclinic:tracing:Agent 15.73 s 16.27 s [-7.4%; +0.7%] (no difference)

Commit: 175086be · 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.

onPeerConnection(span, remoteConnection.getAddress(), !remoteConnection.isUnresolved());
setPeerPort(span, remoteConnection.getPort());
}
// Invoke the extractor directly rather than via span.setTags(...): this legacy plumbing path

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably don't need this much commenting here

@@ -150,10 +146,10 @@ public ContextScope onError(final ContextScope scope, final Throwable throwable)

public AgentSpan onPeerConnection(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually, I think we'll want onPeerConnection to simply go away, but maybe not in this PR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tag: no release notes Changes to exclude from release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant