From e9b4e88243c607010623835406d93f3c01ac20a5 Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Tue, 30 Jun 2026 20:58:34 -0400 Subject: [PATCH 1/2] Extract peer-connection tagging into a TagExtractor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../decorator/BaseDecorator.java | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/BaseDecorator.java b/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/BaseDecorator.java index 2628e9416cf..c114077b17d 100644 --- a/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/BaseDecorator.java +++ b/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/BaseDecorator.java @@ -12,6 +12,7 @@ import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.ErrorPriorities; +import datadog.trace.bootstrap.instrumentation.api.TagExtractor; import datadog.trace.bootstrap.instrumentation.api.Tags; import java.lang.reflect.Method; import java.net.Inet4Address; @@ -148,12 +149,31 @@ public ContextScope onError(final ContextScope scope, final Throwable throwable) return scope; } + /** + * Extracts peer-connection tags (hostname / IPv4 / IPv6 / port) from a remote {@link + * InetSocketAddress}. This is the extrinsic {@link TagExtractor} form of the peer-connection + * tagging that used to live only in {@link #onPeerConnection(AgentSpan, InetSocketAddress)} — a + * static-final, non-capturing lambda over a JDK type we don't own, so it can be applied at a + * monomorphic call site ({@code span.setTags(addr, PEER_CONNECTION_EXTRACTOR)}) and inlined. The + * logic (and the {@code hostName} resolver cache it uses) is unchanged. + */ + public static final TagExtractor PEER_CONNECTION_EXTRACTOR = + (remoteConnection, span) -> { + if (remoteConnection != null) { + setPeerAddress(span, remoteConnection.getAddress(), !remoteConnection.isUnresolved()); + final int port = remoteConnection.getPort(); + if (port > UNSET_PORT) { + span.setTag(Tags.PEER_PORT, port); + } + } + }; + public AgentSpan onPeerConnection( final AgentSpan span, final InetSocketAddress remoteConnection) { - if (remoteConnection != null) { - onPeerConnection(span, remoteConnection.getAddress(), !remoteConnection.isUnresolved()); - setPeerPort(span, remoteConnection.getPort()); - } + // Invoke the extractor directly rather than via span.setTags(...): this legacy plumbing path + // is behavior-identical to the old inline code, and a direct call runs on test doubles too + // (the span-first span.setTags(...) sugar is for hand-written integration call sites). + PEER_CONNECTION_EXTRACTOR.extract(remoteConnection, span); return span; } @@ -162,6 +182,12 @@ public AgentSpan onPeerConnection(final AgentSpan span, final InetAddress remote } public AgentSpan onPeerConnection(AgentSpan span, InetAddress remoteAddress, boolean resolved) { + setPeerAddress(span, remoteAddress, resolved); + return span; + } + + private static void setPeerAddress( + final AgentSpan span, final InetAddress remoteAddress, final boolean resolved) { if (remoteAddress != null) { String ip = remoteAddress.getHostAddress(); if (resolved && Config.get().isPeerHostNameEnabled()) { @@ -173,7 +199,6 @@ public AgentSpan onPeerConnection(AgentSpan span, InetAddress remoteAddress, boo span.setTag(Tags.PEER_HOST_IPV6, ip); } } - return span; } public AgentSpan setPeerPort(AgentSpan span, String port) { From 07dc157661799c8911a6573a0f1c98f9d36d709f Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Tue, 30 Jun 2026 21:07:08 -0400 Subject: [PATCH 2/2] Promote PEER_CONNECTION_EXTRACTOR to a named singleton class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../decorator/BaseDecorator.java | 43 +------------- .../decorator/PeerConnectionExtractor.java | 57 +++++++++++++++++++ 2 files changed, 59 insertions(+), 41 deletions(-) create mode 100644 dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/PeerConnectionExtractor.java diff --git a/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/BaseDecorator.java b/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/BaseDecorator.java index c114077b17d..9e68a833f09 100644 --- a/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/BaseDecorator.java +++ b/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/BaseDecorator.java @@ -1,7 +1,5 @@ package datadog.trace.bootstrap.instrumentation.decorator; -import static datadog.trace.bootstrap.instrumentation.java.net.HostNameResolver.hostName; - import datadog.context.Context; import datadog.context.ContextScope; import datadog.trace.api.Config; @@ -12,11 +10,8 @@ import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.ErrorPriorities; -import datadog.trace.bootstrap.instrumentation.api.TagExtractor; import datadog.trace.bootstrap.instrumentation.api.Tags; import java.lang.reflect.Method; -import java.net.Inet4Address; -import java.net.Inet6Address; import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.concurrent.ExecutionException; @@ -149,31 +144,12 @@ public ContextScope onError(final ContextScope scope, final Throwable throwable) return scope; } - /** - * Extracts peer-connection tags (hostname / IPv4 / IPv6 / port) from a remote {@link - * InetSocketAddress}. This is the extrinsic {@link TagExtractor} form of the peer-connection - * tagging that used to live only in {@link #onPeerConnection(AgentSpan, InetSocketAddress)} — a - * static-final, non-capturing lambda over a JDK type we don't own, so it can be applied at a - * monomorphic call site ({@code span.setTags(addr, PEER_CONNECTION_EXTRACTOR)}) and inlined. The - * logic (and the {@code hostName} resolver cache it uses) is unchanged. - */ - public static final TagExtractor PEER_CONNECTION_EXTRACTOR = - (remoteConnection, span) -> { - if (remoteConnection != null) { - setPeerAddress(span, remoteConnection.getAddress(), !remoteConnection.isUnresolved()); - final int port = remoteConnection.getPort(); - if (port > UNSET_PORT) { - span.setTag(Tags.PEER_PORT, port); - } - } - }; - public AgentSpan onPeerConnection( final AgentSpan span, final InetSocketAddress remoteConnection) { // Invoke the extractor directly rather than via span.setTags(...): this legacy plumbing path // is behavior-identical to the old inline code, and a direct call runs on test doubles too // (the span-first span.setTags(...) sugar is for hand-written integration call sites). - PEER_CONNECTION_EXTRACTOR.extract(remoteConnection, span); + PeerConnectionExtractor.INSTANCE.extract(remoteConnection, span); return span; } @@ -182,25 +158,10 @@ public AgentSpan onPeerConnection(final AgentSpan span, final InetAddress remote } public AgentSpan onPeerConnection(AgentSpan span, InetAddress remoteAddress, boolean resolved) { - setPeerAddress(span, remoteAddress, resolved); + PeerConnectionExtractor.setPeerAddress(span, remoteAddress, resolved); return span; } - private static void setPeerAddress( - final AgentSpan span, final InetAddress remoteAddress, final boolean resolved) { - if (remoteAddress != null) { - String ip = remoteAddress.getHostAddress(); - if (resolved && Config.get().isPeerHostNameEnabled()) { - span.setTag(Tags.PEER_HOSTNAME, hostName(remoteAddress, ip)); - } - if (remoteAddress instanceof Inet4Address) { - span.setTag(Tags.PEER_HOST_IPV4, ip); - } else if (remoteAddress instanceof Inet6Address) { - span.setTag(Tags.PEER_HOST_IPV6, ip); - } - } - } - public AgentSpan setPeerPort(AgentSpan span, String port) { span.setTag(Tags.PEER_PORT, port); diff --git a/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/PeerConnectionExtractor.java b/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/PeerConnectionExtractor.java new file mode 100644 index 00000000000..7592961789e --- /dev/null +++ b/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/PeerConnectionExtractor.java @@ -0,0 +1,57 @@ +package datadog.trace.bootstrap.instrumentation.decorator; + +import static datadog.trace.bootstrap.instrumentation.java.net.HostNameResolver.hostName; + +import datadog.trace.api.Config; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.TagExtractor; +import datadog.trace.bootstrap.instrumentation.api.Tags; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; + +/** + * Named singleton {@link TagExtractor} for peer-connection tags (hostname / IPv4 / IPv6 / port) + * from a remote {@link InetSocketAddress}. + * + *

Promoted from an inline lambda in {@link BaseDecorator} to a named class so it can be: + * referenced by name at call sites ({@code span.setTags(addr, PeerConnectionExtractor.INSTANCE)}), + * composed with other extractors (the axis the Decorator inheritance chain lacked), and + * given a home for the pure statics and the {@code hostName} resolver cache it consults. + * Non-capturing and stateless — the single {@link #INSTANCE} is effectively a static function + * object, so a monomorphic call site inlines it away. + */ +public final class PeerConnectionExtractor implements TagExtractor { + public static final PeerConnectionExtractor INSTANCE = new PeerConnectionExtractor(); + + private static final int UNSET_PORT = 0; + + private PeerConnectionExtractor() {} + + @Override + public void extract(final InetSocketAddress remoteConnection, final AgentSpan span) { + if (remoteConnection != null) { + setPeerAddress(span, remoteConnection.getAddress(), !remoteConnection.isUnresolved()); + final int port = remoteConnection.getPort(); + if (port > UNSET_PORT) { + span.setTag(Tags.PEER_PORT, port); + } + } + } + + static void setPeerAddress( + final AgentSpan span, final InetAddress remoteAddress, final boolean resolved) { + if (remoteAddress != null) { + String ip = remoteAddress.getHostAddress(); + if (resolved && Config.get().isPeerHostNameEnabled()) { + span.setTag(Tags.PEER_HOSTNAME, hostName(remoteAddress, ip)); + } + if (remoteAddress instanceof Inet4Address) { + span.setTag(Tags.PEER_HOST_IPV4, ip); + } else if (remoteAddress instanceof Inet6Address) { + span.setTag(Tags.PEER_HOST_IPV6, ip); + } + } + } +}