From 2cfb6c8b406f498f223e04f296e187a6106b0b77 Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Tue, 10 Mar 2026 10:18:45 +0100 Subject: [PATCH 01/12] phase 1 --- .../ApacheHttpClientInstrumentation.java | 59 ++++++++++++++----- .../apachehttpclient/HelperMethods.java | 33 +++++++++-- .../ApacheHttpClientInstrumentation.java | 43 ++++++++++---- .../apachehttpclient5/HelperMethods.java | 18 ++++-- .../client/ClientCallImplInstrumentation.java | 22 ++++++- .../CommonsHttpClientInstrumentation.java | 21 ++++++- 6 files changed, 153 insertions(+), 43 deletions(-) diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpclient/ApacheHttpClientInstrumentation.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpclient/ApacheHttpClientInstrumentation.java index 9cde4c7a2df..4f70c43a034 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpclient/ApacheHttpClientInstrumentation.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpclient/ApacheHttpClientInstrumentation.java @@ -1,5 +1,6 @@ package datadog.trace.instrumentation.apachehttpclient; +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.implementsInterface; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.isMethod; @@ -10,6 +11,7 @@ import datadog.appsec.api.blocking.BlockingException; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.agent.tooling.annotation.AppliesOn; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -82,65 +84,72 @@ public void methodAdvice(MethodTransformer transformer) { // some methods can share the same advice class. The call depth tracking ensures only 1 span is // created - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("execute")) .and(takesArguments(1)) .and(takesArgument(0, named("org.apache.http.client.methods.HttpUriRequest"))), - ApacheHttpClientInstrumentation.class.getName() + "$UriRequestAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$UriRequestAdvice", + ApacheHttpClientInstrumentation.class.getName() + "$UriRequestContextPropagationAdvice"); - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("execute")) .and(takesArguments(2)) .and(takesArgument(0, named("org.apache.http.client.methods.HttpUriRequest"))) .and(takesArgument(1, named("org.apache.http.protocol.HttpContext"))), - ApacheHttpClientInstrumentation.class.getName() + "$UriRequestAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$UriRequestAdvice", + ApacheHttpClientInstrumentation.class.getName() + "$UriRequestContextPropagationAdvice"); - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("execute")) .and(takesArguments(2)) .and(takesArgument(0, named("org.apache.http.client.methods.HttpUriRequest"))) .and(takesArgument(1, named("org.apache.http.client.ResponseHandler"))), - ApacheHttpClientInstrumentation.class.getName() + "$UriRequestWithHandlerAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$UriRequestWithHandlerAdvice", + ApacheHttpClientInstrumentation.class.getName() + "$UriRequestContextPropagationAdvice"); - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("execute")) .and(takesArguments(3)) .and(takesArgument(0, named("org.apache.http.client.methods.HttpUriRequest"))) .and(takesArgument(1, named("org.apache.http.client.ResponseHandler"))) .and(takesArgument(2, named("org.apache.http.protocol.HttpContext"))), - ApacheHttpClientInstrumentation.class.getName() + "$UriRequestWithHandlerAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$UriRequestWithHandlerAdvice", + ApacheHttpClientInstrumentation.class.getName() + "$UriRequestContextPropagationAdvice"); - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("execute")) .and(takesArguments(2)) .and(takesArgument(0, named("org.apache.http.HttpHost"))) .and(takesArgument(1, named("org.apache.http.HttpRequest"))), - ApacheHttpClientInstrumentation.class.getName() + "$RequestAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$RequestAdvice", + ApacheHttpClientInstrumentation.class.getName() + "$RequestContextPropagationAdvice"); - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("execute")) .and(takesArguments(3)) .and(takesArgument(0, named("org.apache.http.HttpHost"))) .and(takesArgument(1, named("org.apache.http.HttpRequest"))) .and(takesArgument(2, named("org.apache.http.protocol.HttpContext"))), - ApacheHttpClientInstrumentation.class.getName() + "$RequestAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$RequestAdvice", + ApacheHttpClientInstrumentation.class.getName() + "$RequestContextPropagationAdvice"); - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("execute")) .and(takesArguments(3)) .and(takesArgument(0, named("org.apache.http.HttpHost"))) .and(takesArgument(1, named("org.apache.http.HttpRequest"))) .and(takesArgument(2, named("org.apache.http.client.ResponseHandler"))), - ApacheHttpClientInstrumentation.class.getName() + "$RequestWithHandlerAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$RequestWithHandlerAdvice", + ApacheHttpClientInstrumentation.class.getName() + "$RequestContextPropagationAdvice"); - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("execute")) .and(takesArguments(4)) @@ -148,7 +157,8 @@ public void methodAdvice(MethodTransformer transformer) { .and(takesArgument(1, named("org.apache.http.HttpRequest"))) .and(takesArgument(2, named("org.apache.http.client.ResponseHandler"))) .and(takesArgument(3, named("org.apache.http.protocol.HttpContext"))), - ApacheHttpClientInstrumentation.class.getName() + "$RequestWithHandlerAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$RequestWithHandlerAdvice", + ApacheHttpClientInstrumentation.class.getName() + "$RequestContextPropagationAdvice"); } public static class UriRequestAdvice { @@ -274,4 +284,21 @@ public static void methodExit( HelperMethods.doMethodExit(scope, result, throwable); } } + + @AppliesOn(CONTEXT_TRACKING) + public static class UriRequestContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void methodEnter(@Advice.Argument(0) final HttpUriRequest request) { + HelperMethods.doInjectContext(request); + } + } + + @AppliesOn(CONTEXT_TRACKING) + public static class RequestContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void methodEnter( + @Advice.Argument(0) final HttpHost host, @Advice.Argument(1) final HttpRequest request) { + HelperMethods.doInjectContext(host, request); + } + } } diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpclient/HelperMethods.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpclient/HelperMethods.java index 389f58a50f5..e7eca09f24c 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpclient/HelperMethods.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpclient/HelperMethods.java @@ -2,6 +2,7 @@ import static datadog.context.Context.current; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.instrumentation.apachehttpclient.ApacheHttpClientDecorator.DECORATE; import static datadog.trace.instrumentation.apachehttpclient.ApacheHttpClientDecorator.HTTP_REQUEST; @@ -40,14 +41,36 @@ private static AgentScope activateHttpSpan(final HttpUriRequest request) { DECORATE.afterStart(span); DECORATE.onRequest(span, request); - final boolean awsClientCall = request.containsHeader("amz-sdk-invocation-id"); - // AWS calls are often signed, so we can't add headers without breaking the signature. - if (!awsClientCall) { - DECORATE.injectContext(current().with(span), request, SETTER); + return scope; + } + + public static void doInjectContext(final HttpUriRequest request) { + if (request.containsHeader("amz-sdk-invocation-id")) { + return; } + final AgentSpan span = activeSpan(); + if (span == null) { + return; + } + DECORATE.injectContext(current().with(span), request, SETTER); + } - return scope; + public static void doInjectContext(final HttpHost host, final HttpRequest request) { + final HttpUriRequest uriRequest; + if (request instanceof HttpUriRequest) { + uriRequest = (HttpUriRequest) request; + } else { + uriRequest = new HostAndRequestAsHttpUriRequest(host, request); + } + if (uriRequest.containsHeader("amz-sdk-invocation-id")) { + return; + } + final AgentSpan span = activeSpan(); + if (span == null) { + return; + } + DECORATE.injectContext(current().with(span), uriRequest, SETTER); } public static void doMethodExit( diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpClientInstrumentation.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpClientInstrumentation.java index 051b5305771..64b783b7d41 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpClientInstrumentation.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpClientInstrumentation.java @@ -1,5 +1,6 @@ package datadog.trace.instrumentation.apachehttpclient5; +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.implementsInterface; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.isMethod; @@ -10,6 +11,7 @@ import datadog.appsec.api.blocking.BlockingException; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.agent.tooling.annotation.AppliesOn; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -70,39 +72,43 @@ public String[] helperClassNames() { @Override public void methodAdvice(MethodTransformer transformer) { - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("execute")) .and(takesArguments(1)) .and(takesArgument(0, named("org.apache.hc.core5.http.ClassicHttpRequest"))), - ApacheHttpClientInstrumentation.class.getName() + "$RequestAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$RequestAdvice", + ApacheHttpClientInstrumentation.class.getName() + "$RequestContextPropagationAdvice"); - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("execute")) .and(takesArguments(2)) .and(takesArgument(0, named("org.apache.hc.core5.http.ClassicHttpRequest"))) .and(takesArgument(1, named("org.apache.hc.core5.http.protocol.HttpContext"))), - ApacheHttpClientInstrumentation.class.getName() + "$RequestAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$RequestAdvice", + ApacheHttpClientInstrumentation.class.getName() + "$RequestContextPropagationAdvice"); - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("execute")) .and(takesArguments(3)) .and(takesArgument(0, named("org.apache.hc.core5.http.HttpHost"))) .and(takesArgument(1, named("org.apache.hc.core5.http.ClassicHttpRequest"))) .and(takesArgument(2, named("org.apache.hc.core5.http.protocol.HttpContext"))), - ApacheHttpClientInstrumentation.class.getName() + "$HostRequestAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$HostRequestAdvice", + ApacheHttpClientInstrumentation.class.getName() + "$HostRequestContextPropagationAdvice"); - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("execute")) .and(takesArguments(2)) .and(takesArgument(0, named("org.apache.hc.core5.http.HttpHost"))) .and(takesArgument(1, named("org.apache.hc.core5.http.ClassicHttpRequest"))), - ApacheHttpClientInstrumentation.class.getName() + "$HostRequestAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$HostRequestAdvice", + ApacheHttpClientInstrumentation.class.getName() + "$HostRequestContextPropagationAdvice"); - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("execute")) .and(takesArguments(4)) @@ -110,7 +116,8 @@ public void methodAdvice(MethodTransformer transformer) { .and(takesArgument(1, named("org.apache.hc.core5.http.ClassicHttpRequest"))) .and(takesArgument(2, named("org.apache.hc.core5.http.protocol.HttpContext"))) .and(takesArgument(3, named("org.apache.hc.core5.http.io.HttpClientResponseHandler"))), - ApacheHttpClientInstrumentation.class.getName() + "$ResponseHandlerAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$ResponseHandlerAdvice", + ApacheHttpClientInstrumentation.class.getName() + "$HostRequestContextPropagationAdvice"); } public static class RequestAdvice { @@ -194,4 +201,20 @@ public static void methodExit( HelperMethods.doMethodExit(scope, result, throwable); } } + + @AppliesOn(CONTEXT_TRACKING) + public static class RequestContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void methodEnter(@Advice.Argument(0) final ClassicHttpRequest request) { + HelperMethods.doInjectContext(request); + } + } + + @AppliesOn(CONTEXT_TRACKING) + public static class HostRequestContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void methodEnter(@Advice.Argument(1) final ClassicHttpRequest request) { + HelperMethods.doInjectContext(request); + } + } } diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/HelperMethods.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/HelperMethods.java index e6187609433..8cc80661c65 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/HelperMethods.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/HelperMethods.java @@ -2,6 +2,7 @@ import static datadog.context.Context.current; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.instrumentation.apachehttpclient5.ApacheHttpClientDecorator.DECORATE; import static datadog.trace.instrumentation.apachehttpclient5.ApacheHttpClientDecorator.HTTP_REQUEST; @@ -41,15 +42,20 @@ private static AgentScope activateHttpSpan(final HttpRequest request) { DECORATE.afterStart(span); DECORATE.onRequest(span, request); - final boolean awsClientCall = request.containsHeader("amz-sdk-invocation-id"); - // AWS calls are often signed, so we can't add headers without breaking the signature. - if (!awsClientCall) { - DECORATE.injectContext(current().with(span), request, SETTER); - } - return scope; } + public static void doInjectContext(final HttpRequest request) { + if (request.containsHeader("amz-sdk-invocation-id")) { + return; + } + final AgentSpan span = activeSpan(); + if (span == null) { + return; + } + DECORATE.injectContext(current().with(span), request, SETTER); + } + public static void doMethodExit( final AgentScope scope, final Object result, final Throwable throwable) { if (scope == null) { diff --git a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/ClientCallImplInstrumentation.java b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/ClientCallImplInstrumentation.java index 3c503841b2c..27d8c46b936 100644 --- a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/ClientCallImplInstrumentation.java +++ b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/ClientCallImplInstrumentation.java @@ -1,6 +1,6 @@ package datadog.trace.instrumentation.armeria.grpc.client; -import static datadog.context.Context.current; +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; @@ -15,6 +15,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import datadog.trace.agent.tooling.Instrumenter; +import datadog.trace.agent.tooling.annotation.AppliesOn; import datadog.trace.api.InstrumenterConfig; import datadog.trace.bootstrap.InstrumentationContext; import datadog.trace.bootstrap.instrumentation.api.AgentScope; @@ -43,7 +44,10 @@ public void methodAdvice(MethodTransformer transformer) { transformer.applyAdvice( isConstructor().and(takesArgument(2, named("io.grpc.MethodDescriptor"))), getClass().getName() + "$CaptureCallPos2"); - transformer.applyAdvice(named("start").and(isMethod()), getClass().getName() + "$Start"); + transformer.applyAdvices( + named("start").and(isMethod()), + getClass().getName() + "$Start", + getClass().getName() + "$StartContextPropagationAdvice"); transformer.applyAdvice(named("cancel").and(isMethod()), getClass().getName() + "$Cancel"); transformer.applyAdvice( named("request") @@ -95,7 +99,6 @@ public static AgentScope before( if (null != responseListener && null != headers) { span = InstrumentationContext.get(ClientCall.class, AgentSpan.class).get(call); if (null != span) { - DECORATE.injectContext(current().with(span), headers, SETTER); return activateSpan(span); } } @@ -120,6 +123,19 @@ public static void after( } } + @AppliesOn(CONTEXT_TRACKING) + public static final class StartContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void before( + @Advice.This ClientCall call, @Advice.Argument(1) Metadata headers) { + AgentSpan span = InstrumentationContext.get(ClientCall.class, AgentSpan.class).get(call); + if (span == null) { + return; + } + DECORATE.injectContext(span, headers, SETTER); + } + } + public static final class ActivateSpan { @Advice.OnMethodEnter public static AgentScope before(@Advice.This ClientCall call) { diff --git a/dd-java-agent/instrumentation/commons-httpclient-2.0/src/main/java/datadog/trace/instrumentation/commonshttpclient/CommonsHttpClientInstrumentation.java b/dd-java-agent/instrumentation/commons-httpclient-2.0/src/main/java/datadog/trace/instrumentation/commonshttpclient/CommonsHttpClientInstrumentation.java index 0ad7480901d..6edd7a93010 100644 --- a/dd-java-agent/instrumentation/commons-httpclient-2.0/src/main/java/datadog/trace/instrumentation/commonshttpclient/CommonsHttpClientInstrumentation.java +++ b/dd-java-agent/instrumentation/commons-httpclient-2.0/src/main/java/datadog/trace/instrumentation/commonshttpclient/CommonsHttpClientInstrumentation.java @@ -1,7 +1,9 @@ package datadog.trace.instrumentation.commonshttpclient; +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; import static datadog.trace.instrumentation.commonshttpclient.CommonsHttpClientDecorator.DECORATE; @@ -15,6 +17,7 @@ import datadog.appsec.api.blocking.BlockingException; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.agent.tooling.annotation.AppliesOn; import datadog.trace.bootstrap.CallDepthThreadLocalMap; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; @@ -44,12 +47,13 @@ public String[] helperClassNames() { @Override public void methodAdvice(MethodTransformer transformer) { - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("executeMethod")) .and(takesArguments(3)) .and(takesArgument(1, named("org.apache.commons.httpclient.HttpMethod"))), - CommonsHttpClientInstrumentation.class.getName() + "$ExecAdvice"); + CommonsHttpClientInstrumentation.class.getName() + "$ExecAdvice", + CommonsHttpClientInstrumentation.class.getName() + "$ContextPropagationAdvice"); } public static class ExecAdvice { @@ -67,7 +71,6 @@ public static AgentScope methodEnter(@Advice.Argument(1) final HttpMethod httpMe DECORATE.afterStart(span); DECORATE.onRequest(span, httpMethod); - DECORATE.injectContext(getCurrentContext().with(span), httpMethod, SETTER); return scope; } catch (BlockingException e) { @@ -98,4 +101,16 @@ public static void methodExit( } } } + + @AppliesOn(CONTEXT_TRACKING) + public static class ContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void methodEnter(@Advice.Argument(1) final HttpMethod httpMethod) { + AgentSpan span = activeSpan(); + if (span == null) { + return; + } + DECORATE.injectContext(getCurrentContext().with(span), httpMethod, SETTER); + } + } } From 410852cfa5a70ac0945662c0d396d00abd5942a7 Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Tue, 10 Mar 2026 10:49:43 +0100 Subject: [PATCH 02/12] migrate jetty and akka http clients --- .../AkkaHttpSingleRequestInstrumentation.java | 39 ++++++++++++++----- .../AkkaHttpSingleRequestInstrumentation.java | 6 ++- .../akkahttp106/SingleRequestAdvice.java | 6 --- ...SingleRequestContextPropagationAdvice.java | 30 ++++++++++++++ .../JettyClientInstrumentation.java | 5 ++- .../jetty_client10/SendAdvice.java | 3 -- .../SendContextPropagationAdvice.java | 24 ++++++++++++ .../JettyHttpClientInstrumentation.java | 5 ++- .../jetty_client12/SendAdvice.java | 3 -- .../SendContextPropagationAdvice.java | 25 ++++++++++++ .../JettyClientInstrumentation.java | 20 ++++++++-- ...PekkoHttpSingleRequestInstrumentation.java | 39 ++++++++++++++----- 12 files changed, 164 insertions(+), 41 deletions(-) create mode 100644 dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestContextPropagationAdvice.java create mode 100644 dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java11/datadog/trace/instrumentation/jetty_client10/SendContextPropagationAdvice.java create mode 100644 dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-12.0/src/main/java17/datadog/trace/instrumentation/jetty_client12/SendContextPropagationAdvice.java diff --git a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/AkkaHttpSingleRequestInstrumentation.java b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/AkkaHttpSingleRequestInstrumentation.java index 29e413e9ece..f72034e75a8 100644 --- a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/AkkaHttpSingleRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/AkkaHttpSingleRequestInstrumentation.java @@ -1,7 +1,9 @@ package datadog.trace.instrumentation.akkahttp; +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; import static datadog.trace.instrumentation.akkahttp.AkkaHttpClientDecorator.AKKA_CLIENT_REQUEST; @@ -16,6 +18,7 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.agent.tooling.annotation.AppliesOn; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import net.bytebuddy.asm.Advice; @@ -47,14 +50,18 @@ public String[] helperClassNames() { @Override public void methodAdvice(MethodTransformer transformer) { // This is mainly for compatibility with 10.0 - transformer.applyAdvice( + transformer.applyAdvices( named("singleRequest").and(takesArgument(0, named("akka.http.scaladsl.model.HttpRequest"))), - AkkaHttpSingleRequestInstrumentation.class.getName() + "$SingleRequestAdvice"); + AkkaHttpSingleRequestInstrumentation.class.getName() + "$SingleRequestAdvice", + AkkaHttpSingleRequestInstrumentation.class.getName() + + "$SingleRequestContextPropagationAdvice"); // This is for 10.1+ - transformer.applyAdvice( + transformer.applyAdvices( named("singleRequestImpl") .and(takesArgument(0, named("akka.http.scaladsl.model.HttpRequest"))), - AkkaHttpSingleRequestInstrumentation.class.getName() + "$SingleRequestAdvice"); + AkkaHttpSingleRequestInstrumentation.class.getName() + "$SingleRequestAdvice", + AkkaHttpSingleRequestInstrumentation.class.getName() + + "$SingleRequestContextPropagationAdvice"); } public static class SingleRequestAdvice { @@ -75,12 +82,6 @@ public static AgentScope methodEnter( final AgentSpan span = startSpan("akka-http", AKKA_CLIENT_REQUEST); DECORATE.afterStart(span); DECORATE.onRequest(span, request); - - if (request != null) { - DECORATE.injectContext(getCurrentContext().with(span), request, headers); - // Request is immutable, so we have to assign new value once we update headers - request = headers.getRequest(); - } return activateSpan(span); } @@ -106,4 +107,22 @@ public static void methodExit( scope.close(); } } + + @AppliesOn(CONTEXT_TRACKING) + public static class SingleRequestContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void methodEnter( + @Advice.Argument(value = 0, readOnly = false) HttpRequest request) { + final AkkaHttpHeaders headers = new AkkaHttpHeaders(request); + if (headers.hadSpan()) { + return; + } + AgentSpan span = activeSpan(); + if (span == null) { + return; + } + DECORATE.injectContext(getCurrentContext().with(span), request, headers); + request = headers.getRequest(); + } + } } diff --git a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java/datadog/trace/instrumentation/akkahttp106/AkkaHttpSingleRequestInstrumentation.java b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java/datadog/trace/instrumentation/akkahttp106/AkkaHttpSingleRequestInstrumentation.java index 7d7596befaa..c4f3e185dc4 100644 --- a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java/datadog/trace/instrumentation/akkahttp106/AkkaHttpSingleRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java/datadog/trace/instrumentation/akkahttp106/AkkaHttpSingleRequestInstrumentation.java @@ -1,5 +1,6 @@ package datadog.trace.instrumentation.akkahttp106; +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; @@ -32,8 +33,9 @@ public String[] helperClassNames() { @Override public void methodAdvice(MethodTransformer transformer) { - transformer.applyAdvice( + transformer.applyAdvices( named("singleRequest").and(takesArgument(0, named("akka.http.scaladsl.model.HttpRequest"))), - packageName + ".SingleRequestAdvice"); + packageName + ".SingleRequestAdvice", + packageName + ".SingleRequestContextPropagationAdvice"); } } diff --git a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestAdvice.java b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestAdvice.java index e70e90208e3..77e10b5cfde 100644 --- a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestAdvice.java +++ b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestAdvice.java @@ -2,7 +2,6 @@ import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; -import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; import static datadog.trace.instrumentation.akkahttp106.AkkaHttpClientDecorator.AKKA_CLIENT_REQUEST; import static datadog.trace.instrumentation.akkahttp106.AkkaHttpClientDecorator.DECORATE; @@ -27,11 +26,6 @@ public static AgentScope methodEnter( final AgentSpan span = startSpan("akka-http", AKKA_CLIENT_REQUEST); DECORATE.afterStart(span); DECORATE.onRequest(span, request); - if (request != null) { - DECORATE.injectContext(getCurrentContext().with(span), request, headers); - // Request is immutable, so we have to assign new value once we update headers - request = headers.getRequest(); - } return activateSpan(span); } diff --git a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestContextPropagationAdvice.java b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestContextPropagationAdvice.java new file mode 100644 index 00000000000..78057b50480 --- /dev/null +++ b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestContextPropagationAdvice.java @@ -0,0 +1,30 @@ +package datadog.trace.instrumentation.akkahttp106; + +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; +import static datadog.trace.instrumentation.akkahttp106.AkkaHttpClientDecorator.DECORATE; + +import akka.http.scaladsl.model.HttpRequest; +import datadog.trace.agent.tooling.annotation.AppliesOn; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import net.bytebuddy.asm.Advice; + +@AppliesOn(CONTEXT_TRACKING) +public class SingleRequestContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void methodEnter( + @Advice.Argument(value = 0, readOnly = false) HttpRequest request) { + final AkkaHttpClientHelpers.AkkaHttpHeaders headers = + new AkkaHttpClientHelpers.AkkaHttpHeaders(request); + if (headers.hadSpan()) { + return; + } + AgentSpan span = activeSpan(); + if (span == null) { + return; + } + DECORATE.injectContext(getCurrentContext().with(span), request, headers); + request = headers.getRequest(); + } +} diff --git a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java/datadog/trace/instrumentation/jetty_client10/JettyClientInstrumentation.java b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java/datadog/trace/instrumentation/jetty_client10/JettyClientInstrumentation.java index 1ddf6eb654a..24a8c15cf53 100644 --- a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java/datadog/trace/instrumentation/jetty_client10/JettyClientInstrumentation.java +++ b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java/datadog/trace/instrumentation/jetty_client10/JettyClientInstrumentation.java @@ -47,7 +47,7 @@ public Map contextStore() { @Override public void methodAdvice(MethodTransformer transformer) { - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("send")) .and( @@ -57,7 +57,8 @@ public void methodAdvice(MethodTransformer transformer) { "org.eclipse.jetty.client.api.Request", "org.eclipse.jetty.client.HttpRequest"))) .and(takesArgument(1, List.class)), - packageName + ".SendAdvice"); + packageName + ".SendAdvice", + packageName + ".SendContextPropagationAdvice"); } @Override diff --git a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java11/datadog/trace/instrumentation/jetty_client10/SendAdvice.java b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java11/datadog/trace/instrumentation/jetty_client10/SendAdvice.java index 95159ca3033..2e92e35f91b 100644 --- a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java11/datadog/trace/instrumentation/jetty_client10/SendAdvice.java +++ b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java11/datadog/trace/instrumentation/jetty_client10/SendAdvice.java @@ -1,8 +1,6 @@ package datadog.trace.instrumentation.jetty_client10; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; -import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; -import static datadog.trace.instrumentation.jetty_client.HeadersInjectAdapter.SETTER; import static datadog.trace.instrumentation.jetty_client10.JettyClientDecorator.DECORATE; import static datadog.trace.instrumentation.jetty_client10.JettyClientDecorator.HTTP_REQUEST; @@ -24,7 +22,6 @@ public static AgentSpan methodEnter( responseListeners.add(0, new SpanFinishingCompleteListener(span)); DECORATE.afterStart(span); DECORATE.onRequest(span, request); - DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); return span; } diff --git a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java11/datadog/trace/instrumentation/jetty_client10/SendContextPropagationAdvice.java b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java11/datadog/trace/instrumentation/jetty_client10/SendContextPropagationAdvice.java new file mode 100644 index 00000000000..73b2c8cea62 --- /dev/null +++ b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java11/datadog/trace/instrumentation/jetty_client10/SendContextPropagationAdvice.java @@ -0,0 +1,24 @@ +package datadog.trace.instrumentation.jetty_client10; + +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; +import static datadog.trace.instrumentation.jetty_client.HeadersInjectAdapter.SETTER; +import static datadog.trace.instrumentation.jetty_client10.JettyClientDecorator.DECORATE; + +import datadog.trace.agent.tooling.annotation.AppliesOn; +import datadog.trace.bootstrap.InstrumentationContext; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import net.bytebuddy.asm.Advice; +import org.eclipse.jetty.client.api.Request; + +@AppliesOn(CONTEXT_TRACKING) +public class SendContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void methodEnter(@Advice.Argument(0) final Request request) { + AgentSpan span = InstrumentationContext.get(Request.class, AgentSpan.class).get(request); + if (span == null) { + return; + } + DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); + } +} diff --git a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-12.0/src/main/java/datadog/trace/instrumentation/jetty_client12/JettyHttpClientInstrumentation.java b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-12.0/src/main/java/datadog/trace/instrumentation/jetty_client12/JettyHttpClientInstrumentation.java index d8d78fb9c01..82c1f39967b 100644 --- a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-12.0/src/main/java/datadog/trace/instrumentation/jetty_client12/JettyHttpClientInstrumentation.java +++ b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-12.0/src/main/java/datadog/trace/instrumentation/jetty_client12/JettyHttpClientInstrumentation.java @@ -50,11 +50,12 @@ public Map contextStore() { @Override public void methodAdvice(MethodTransformer transformer) { transformer.applyAdvice(isConstructor(), packageName + ".RequestCreateAdvice"); - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("send")) .and(takesArgument(0, named("org.eclipse.jetty.client.Response$CompleteListener"))), - packageName + ".SendAdvice"); + packageName + ".SendAdvice", + packageName + ".SendContextPropagationAdvice"); transformer.applyAdvice( isMethod() .and(isPublic()) diff --git a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-12.0/src/main/java17/datadog/trace/instrumentation/jetty_client12/SendAdvice.java b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-12.0/src/main/java17/datadog/trace/instrumentation/jetty_client12/SendAdvice.java index e1682a4020e..cc08b865280 100644 --- a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-12.0/src/main/java17/datadog/trace/instrumentation/jetty_client12/SendAdvice.java +++ b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-12.0/src/main/java17/datadog/trace/instrumentation/jetty_client12/SendAdvice.java @@ -2,8 +2,6 @@ import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; -import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; -import static datadog.trace.instrumentation.jetty_client12.HeadersInjectAdapter.SETTER; import static datadog.trace.instrumentation.jetty_client12.JettyClientDecorator.DECORATE; import static datadog.trace.instrumentation.jetty_client12.JettyClientDecorator.HTTP_REQUEST; @@ -21,7 +19,6 @@ public static AgentScope methodEnter(@Advice.This final HttpRequest request) { InstrumentationContext.get(Request.class, AgentSpan.class).put(request, span); DECORATE.afterStart(span); DECORATE.onRequest(span, request); - DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); return activateSpan(span); } diff --git a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-12.0/src/main/java17/datadog/trace/instrumentation/jetty_client12/SendContextPropagationAdvice.java b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-12.0/src/main/java17/datadog/trace/instrumentation/jetty_client12/SendContextPropagationAdvice.java new file mode 100644 index 00000000000..490763613f8 --- /dev/null +++ b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-12.0/src/main/java17/datadog/trace/instrumentation/jetty_client12/SendContextPropagationAdvice.java @@ -0,0 +1,25 @@ +package datadog.trace.instrumentation.jetty_client12; + +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; +import static datadog.trace.instrumentation.jetty_client12.HeadersInjectAdapter.SETTER; +import static datadog.trace.instrumentation.jetty_client12.JettyClientDecorator.DECORATE; + +import datadog.trace.agent.tooling.annotation.AppliesOn; +import datadog.trace.bootstrap.InstrumentationContext; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import net.bytebuddy.asm.Advice; +import org.eclipse.jetty.client.Request; +import org.eclipse.jetty.client.transport.HttpRequest; + +@AppliesOn(CONTEXT_TRACKING) +public class SendContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void methodEnter(@Advice.This final HttpRequest request) { + AgentSpan span = InstrumentationContext.get(Request.class, AgentSpan.class).get(request); + if (span == null) { + return; + } + DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); + } +} diff --git a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-9.1/src/main/java/datadog/trace/instrumentation/jetty_client91/JettyClientInstrumentation.java b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-9.1/src/main/java/datadog/trace/instrumentation/jetty_client91/JettyClientInstrumentation.java index 041c6d008b6..6ce36afd159 100644 --- a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-9.1/src/main/java/datadog/trace/instrumentation/jetty_client91/JettyClientInstrumentation.java +++ b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-9.1/src/main/java/datadog/trace/instrumentation/jetty_client91/JettyClientInstrumentation.java @@ -1,5 +1,6 @@ package datadog.trace.instrumentation.jetty_client91; +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; @@ -17,6 +18,7 @@ import datadog.trace.agent.tooling.ExcludeFilterProvider; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.agent.tooling.annotation.AppliesOn; import datadog.trace.bootstrap.InstrumentationContext; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.java.concurrent.ExcludeFilter; @@ -61,7 +63,7 @@ public Map contextStore() { @Override public void methodAdvice(MethodTransformer transformer) { - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("send")) .and( @@ -71,7 +73,8 @@ public void methodAdvice(MethodTransformer transformer) { "org.eclipse.jetty.client.api.Request", "org.eclipse.jetty.client.HttpRequest"))) .and(takesArgument(1, List.class)), - JettyClientInstrumentation.class.getName() + "$SendAdvice"); + JettyClientInstrumentation.class.getName() + "$SendAdvice", + JettyClientInstrumentation.class.getName() + "$ContextPropagationAdvice"); } @Override @@ -90,7 +93,6 @@ public static AgentSpan methodEnter( responseListeners.add(0, new SpanFinishingCompleteListener(span)); DECORATE.afterStart(span); DECORATE.onRequest(span, request); - DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); return span; } @@ -104,4 +106,16 @@ public static void methodExit( } } } + + @AppliesOn(CONTEXT_TRACKING) + public static class ContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void methodEnter(@Advice.Argument(0) final Request request) { + AgentSpan span = InstrumentationContext.get(Request.class, AgentSpan.class).get(request); + if (span == null) { + return; + } + DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); + } + } } diff --git a/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/PekkoHttpSingleRequestInstrumentation.java b/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/PekkoHttpSingleRequestInstrumentation.java index e230a604172..3e3ad0678ac 100644 --- a/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/PekkoHttpSingleRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/PekkoHttpSingleRequestInstrumentation.java @@ -1,7 +1,9 @@ package datadog.trace.instrumentation.pekkohttp; +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; import static datadog.trace.instrumentation.pekkohttp.PekkoHttpClientDecorator.DECORATE; @@ -13,6 +15,7 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.agent.tooling.annotation.AppliesOn; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import net.bytebuddy.asm.Advice; @@ -47,15 +50,19 @@ public String[] helperClassNames() { @Override public void methodAdvice(MethodTransformer transformer) { // This is mainly for compatibility with 10.0 - transformer.applyAdvice( + transformer.applyAdvices( named("singleRequest") .and(takesArgument(0, named("org.apache.pekko.http.scaladsl.model.HttpRequest"))), - PekkoHttpSingleRequestInstrumentation.class.getName() + "$SingleRequestAdvice"); + PekkoHttpSingleRequestInstrumentation.class.getName() + "$SingleRequestAdvice", + PekkoHttpSingleRequestInstrumentation.class.getName() + + "$SingleRequestContextPropagationAdvice"); // This is for 10.1+ - transformer.applyAdvice( + transformer.applyAdvices( named("singleRequestImpl") .and(takesArgument(0, named("org.apache.pekko.http.scaladsl.model.HttpRequest"))), - PekkoHttpSingleRequestInstrumentation.class.getName() + "$SingleRequestAdvice"); + PekkoHttpSingleRequestInstrumentation.class.getName() + "$SingleRequestAdvice", + PekkoHttpSingleRequestInstrumentation.class.getName() + + "$SingleRequestContextPropagationAdvice"); } public static class SingleRequestAdvice { @@ -76,12 +83,6 @@ public static AgentScope methodEnter( final AgentSpan span = startSpan("pekko-http", PEKKO_CLIENT_REQUEST); DECORATE.afterStart(span); DECORATE.onRequest(span, request); - - if (request != null) { - DECORATE.injectContext(getCurrentContext().with(span), request, headers); - // Request is immutable, so we have to assign new value once we update headers - request = headers.getRequest(); - } return activateSpan(span); } @@ -107,4 +108,22 @@ public static void methodExit( scope.close(); } } + + @AppliesOn(CONTEXT_TRACKING) + public static class SingleRequestContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void methodEnter( + @Advice.Argument(value = 0, readOnly = false) HttpRequest request) { + final PekkoHttpHeaders headers = new PekkoHttpHeaders(request); + if (headers.hadSpan()) { + return; + } + AgentSpan span = activeSpan(); + if (span == null) { + return; + } + DECORATE.injectContext(getCurrentContext().with(span), request, headers); + request = headers.getRequest(); + } + } } From 961089cc82ad8235b9f6279343b186bdb12dc5e4 Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Tue, 10 Mar 2026 11:20:50 +0100 Subject: [PATCH 03/12] wip --- .../client/ClientCallImplInstrumentation.java | 5 +-- .../AsyncHttpClientInstrumentation.java | 40 +++++++++++++++++-- .../playws1/PlayWSClientInstrumentation.java | 23 ++++++----- .../playws2/PlayWSClientInstrumentation.java | 23 ++++++----- .../playws21/PlayWSClientInstrumentation.java | 23 ++++++----- .../BasePlayWSClientInstrumentation.java | 26 +++++++++++- 6 files changed, 101 insertions(+), 39 deletions(-) diff --git a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/ClientCallImplInstrumentation.java b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/ClientCallImplInstrumentation.java index 27d8c46b936..0a459d91e5d 100644 --- a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/ClientCallImplInstrumentation.java +++ b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/ClientCallImplInstrumentation.java @@ -126,9 +126,8 @@ public static void after( @AppliesOn(CONTEXT_TRACKING) public static final class StartContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void before( - @Advice.This ClientCall call, @Advice.Argument(1) Metadata headers) { - AgentSpan span = InstrumentationContext.get(ClientCall.class, AgentSpan.class).get(call); + public static void before(@Advice.Argument(1) Metadata headers) { + AgentSpan span = activeSpan(); if (span == null) { return; } diff --git a/dd-java-agent/instrumentation/grizzly/grizzly-client-1.9/src/main/java/datadog/trace/instrumentation/grizzly/client/AsyncHttpClientInstrumentation.java b/dd-java-agent/instrumentation/grizzly/grizzly-client-1.9/src/main/java/datadog/trace/instrumentation/grizzly/client/AsyncHttpClientInstrumentation.java index 92bdac88d09..c0e1c583669 100644 --- a/dd-java-agent/instrumentation/grizzly/grizzly-client-1.9/src/main/java/datadog/trace/instrumentation/grizzly/client/AsyncHttpClientInstrumentation.java +++ b/dd-java-agent/instrumentation/grizzly/grizzly-client-1.9/src/main/java/datadog/trace/instrumentation/grizzly/client/AsyncHttpClientInstrumentation.java @@ -1,6 +1,8 @@ package datadog.trace.instrumentation.grizzly.client; +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; @@ -13,6 +15,8 @@ import com.ning.http.client.AsyncHandler; import com.ning.http.client.Request; import datadog.trace.agent.tooling.Instrumenter; +import datadog.trace.agent.tooling.annotation.AppliesOn; +import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import net.bytebuddy.asm.Advice; @@ -26,26 +30,54 @@ public String instrumentedType() { @Override public void methodAdvice(MethodTransformer transformer) { - transformer.applyAdvice( + transformer.applyAdvices( named("executeRequest") .and(takesArgument(0, named("com.ning.http.client.Request"))) .and(takesArgument(1, named("com.ning.http.client.AsyncHandler"))) .and(isPublic()), - getClass().getName() + "$ExecuteRequest"); + getClass().getName() + "$ExecuteRequest", + getClass().getName() + "$ExecuteContextPropagationAdvice"); } public static class ExecuteRequest { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( + public static AgentScope onEnter( @Advice.Argument(0) final Request request, @Advice.Argument(value = 1, readOnly = false) AsyncHandler handler) { AgentSpan parentSpan = activeSpan(); AgentSpan span = startSpan(HTTP_REQUEST); DECORATE.afterStart(span); DECORATE.onRequest(span, request); - DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); handler = new AsyncHandlerAdapter<>(span, parentSpan, handler); + return activateSpan(span); + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void onExit( + @Advice.Enter final AgentScope scope, @Advice.Thrown final Throwable throwable) { + if (scope == null) { + return; + } + if (throwable != null) { + AgentSpan span = scope.span(); + DECORATE.onError(span, throwable); + DECORATE.beforeFinish(span); + span.finish(); + } + scope.close(); + } + } + + @AppliesOn(CONTEXT_TRACKING) + public static class ExecuteContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void onEnter(@Advice.Argument(0) final Request request) { + AgentSpan span = activeSpan(); + if (span == null) { + return; + } + DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); } } } diff --git a/dd-java-agent/instrumentation/play-ws/play-ws-1.0/src/main/java/datadog/trace/instrumentation/playws1/PlayWSClientInstrumentation.java b/dd-java-agent/instrumentation/play-ws/play-ws-1.0/src/main/java/datadog/trace/instrumentation/playws1/PlayWSClientInstrumentation.java index 82b8fa40799..6cec1300f48 100644 --- a/dd-java-agent/instrumentation/play-ws/play-ws-1.0/src/main/java/datadog/trace/instrumentation/playws1/PlayWSClientInstrumentation.java +++ b/dd-java-agent/instrumentation/play-ws/play-ws-1.0/src/main/java/datadog/trace/instrumentation/playws1/PlayWSClientInstrumentation.java @@ -1,13 +1,13 @@ package datadog.trace.instrumentation.playws1; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; -import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; -import static datadog.trace.instrumentation.playws.HeadersInjectAdapter.SETTER; import static datadog.trace.instrumentation.playws.PlayWSClientDecorator.DECORATE; import static datadog.trace.instrumentation.playws.PlayWSClientDecorator.PLAY_WS_REQUEST; import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.instrumentation.playws.BasePlayWSClientInstrumentation; import net.bytebuddy.asm.Advice; @@ -20,7 +20,7 @@ public class PlayWSClientInstrumentation extends BasePlayWSClientInstrumentation { public static class ClientAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static AgentSpan methodEnter( + public static AgentScope methodEnter( @Advice.Argument(0) final Request request, @Advice.Argument(value = 1, readOnly = false) AsyncHandler asyncHandler) { @@ -28,7 +28,6 @@ public static AgentSpan methodEnter( DECORATE.afterStart(span); DECORATE.onRequest(span, request); - DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); if (asyncHandler instanceof StreamedAsyncHandler) { asyncHandler = new StreamedAsyncHandlerWrapper((StreamedAsyncHandler) asyncHandler, span); @@ -37,18 +36,22 @@ public static AgentSpan methodEnter( asyncHandler = new AsyncHandlerWrapper(asyncHandler, span); } - return span; + return activateSpan(span); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void methodExit( - @Advice.Enter final AgentSpan clientSpan, @Advice.Thrown final Throwable throwable) { - + @Advice.Enter final AgentScope scope, @Advice.Thrown final Throwable throwable) { + if (scope == null) { + return; + } if (throwable != null) { - DECORATE.onError(clientSpan, throwable); - DECORATE.beforeFinish(clientSpan); - clientSpan.finish(); + final AgentSpan span = scope.span(); + DECORATE.onError(span, throwable); + DECORATE.beforeFinish(span); + span.finish(); } + scope.close(); } } } diff --git a/dd-java-agent/instrumentation/play-ws/play-ws-2.0/src/main/java/datadog/trace/instrumentation/playws2/PlayWSClientInstrumentation.java b/dd-java-agent/instrumentation/play-ws/play-ws-2.0/src/main/java/datadog/trace/instrumentation/playws2/PlayWSClientInstrumentation.java index f48ba53e31b..2d97250348a 100644 --- a/dd-java-agent/instrumentation/play-ws/play-ws-2.0/src/main/java/datadog/trace/instrumentation/playws2/PlayWSClientInstrumentation.java +++ b/dd-java-agent/instrumentation/play-ws/play-ws-2.0/src/main/java/datadog/trace/instrumentation/playws2/PlayWSClientInstrumentation.java @@ -1,13 +1,13 @@ package datadog.trace.instrumentation.playws2; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; -import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; -import static datadog.trace.instrumentation.playws.HeadersInjectAdapter.SETTER; import static datadog.trace.instrumentation.playws.PlayWSClientDecorator.DECORATE; import static datadog.trace.instrumentation.playws.PlayWSClientDecorator.PLAY_WS_REQUEST; import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.instrumentation.playws.BasePlayWSClientInstrumentation; import net.bytebuddy.asm.Advice; @@ -20,7 +20,7 @@ public class PlayWSClientInstrumentation extends BasePlayWSClientInstrumentation { public static class ClientAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static AgentSpan methodEnter( + public static AgentScope methodEnter( @Advice.Argument(0) final Request request, @Advice.Argument(value = 1, readOnly = false) AsyncHandler asyncHandler) { @@ -28,7 +28,6 @@ public static AgentSpan methodEnter( DECORATE.afterStart(span); DECORATE.onRequest(span, request); - DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); if (asyncHandler instanceof StreamedAsyncHandler) { asyncHandler = new StreamedAsyncHandlerWrapper((StreamedAsyncHandler) asyncHandler, span); @@ -37,18 +36,22 @@ public static AgentSpan methodEnter( asyncHandler = new AsyncHandlerWrapper(asyncHandler, span); } - return span; + return activateSpan(span); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void methodExit( - @Advice.Enter final AgentSpan clientSpan, @Advice.Thrown final Throwable throwable) { - + @Advice.Enter final AgentScope scope, @Advice.Thrown final Throwable throwable) { + if (scope == null) { + return; + } if (throwable != null) { - DECORATE.onError(clientSpan, throwable); - DECORATE.beforeFinish(clientSpan); - clientSpan.finish(); + final AgentSpan span = scope.span(); + DECORATE.onError(span, throwable); + DECORATE.beforeFinish(span); + span.finish(); } + scope.close(); } } } diff --git a/dd-java-agent/instrumentation/play-ws/play-ws-2.1/src/main/java/datadog/trace/instrumentation/playws21/PlayWSClientInstrumentation.java b/dd-java-agent/instrumentation/play-ws/play-ws-2.1/src/main/java/datadog/trace/instrumentation/playws21/PlayWSClientInstrumentation.java index d7f59046e06..0187a6e17e9 100644 --- a/dd-java-agent/instrumentation/play-ws/play-ws-2.1/src/main/java/datadog/trace/instrumentation/playws21/PlayWSClientInstrumentation.java +++ b/dd-java-agent/instrumentation/play-ws/play-ws-2.1/src/main/java/datadog/trace/instrumentation/playws21/PlayWSClientInstrumentation.java @@ -1,13 +1,13 @@ package datadog.trace.instrumentation.playws21; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; -import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; -import static datadog.trace.instrumentation.playws.HeadersInjectAdapter.SETTER; import static datadog.trace.instrumentation.playws.PlayWSClientDecorator.DECORATE; import static datadog.trace.instrumentation.playws.PlayWSClientDecorator.PLAY_WS_REQUEST; import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.instrumentation.playws.BasePlayWSClientInstrumentation; import net.bytebuddy.asm.Advice; @@ -20,7 +20,7 @@ public class PlayWSClientInstrumentation extends BasePlayWSClientInstrumentation { public static class ClientAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static AgentSpan methodEnter( + public static AgentScope methodEnter( @Advice.Argument(0) final Request request, @Advice.Argument(value = 1, readOnly = false) AsyncHandler asyncHandler) { @@ -28,7 +28,6 @@ public static AgentSpan methodEnter( DECORATE.afterStart(span); DECORATE.onRequest(span, request); - DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); if (asyncHandler instanceof StreamedAsyncHandler) { asyncHandler = new StreamedAsyncHandlerWrapper((StreamedAsyncHandler) asyncHandler, span); @@ -37,18 +36,22 @@ public static AgentSpan methodEnter( asyncHandler = new AsyncHandlerWrapper(asyncHandler, span); } - return span; + return activateSpan(span); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void methodExit( - @Advice.Enter final AgentSpan clientSpan, @Advice.Thrown final Throwable throwable) { - + @Advice.Enter final AgentScope scope, @Advice.Thrown final Throwable throwable) { + if (scope == null) { + return; + } if (throwable != null) { - DECORATE.onError(clientSpan, throwable); - DECORATE.beforeFinish(clientSpan); - clientSpan.finish(); + final AgentSpan span = scope.span(); + DECORATE.onError(span, throwable); + DECORATE.beforeFinish(span); + span.finish(); } + scope.close(); } } } diff --git a/dd-java-agent/instrumentation/play-ws/play-ws-common/src/main/java/datadog/trace/instrumentation/playws/BasePlayWSClientInstrumentation.java b/dd-java-agent/instrumentation/play-ws/play-ws-common/src/main/java/datadog/trace/instrumentation/playws/BasePlayWSClientInstrumentation.java index 29770b841c3..2850c2dcbe6 100644 --- a/dd-java-agent/instrumentation/play-ws/play-ws-common/src/main/java/datadog/trace/instrumentation/playws/BasePlayWSClientInstrumentation.java +++ b/dd-java-agent/instrumentation/play-ws/play-ws-common/src/main/java/datadog/trace/instrumentation/playws/BasePlayWSClientInstrumentation.java @@ -1,8 +1,13 @@ package datadog.trace.instrumentation.playws; +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.implementsInterface; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.nameStartsWith; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; +import static datadog.trace.instrumentation.playws.HeadersInjectAdapter.SETTER; +import static datadog.trace.instrumentation.playws.PlayWSClientDecorator.DECORATE; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.not; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; @@ -10,8 +15,12 @@ import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.agent.tooling.annotation.AppliesOn; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; +import play.shaded.ahc.org.asynchttpclient.Request; public abstract class BasePlayWSClientInstrumentation extends InstrumenterModule.Tracing implements Instrumenter.ForTypeHierarchy, Instrumenter.HasMethodAdvice { @@ -36,13 +45,14 @@ public ElementMatcher hierarchyMatcher() { @Override public void methodAdvice(MethodTransformer transformer) { - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("execute")) .and(takesArguments(2)) .and(takesArgument(0, named("play.shaded.ahc.org.asynchttpclient.Request"))) .and(takesArgument(1, named("play.shaded.ahc.org.asynchttpclient.AsyncHandler"))), - getClass().getName() + "$ClientAdvice"); + getClass().getName() + "$ClientAdvice", + BasePlayWSClientInstrumentation.class.getName() + "$ClientContextPropagationAdvice"); } @Override @@ -54,4 +64,16 @@ public String[] helperClassNames() { packageName + ".StreamedAsyncHandlerWrapper" }; } + + @AppliesOn(CONTEXT_TRACKING) + public static class ClientContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void methodEnter(@Advice.Argument(0) final Request request) { + AgentSpan span = activeSpan(); + if (span == null) { + return; + } + DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); + } + } } From ecd2ae2334c0993e18b0b81664a7e808aa6a07b2 Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Tue, 10 Mar 2026 11:52:35 +0100 Subject: [PATCH 04/12] more clients --- .../GoogleHttpClientDecorator.java | 4 --- .../GoogleHttpClientInstrumentation.java | 28 ++++++++++++++++--- .../HttpHeadersInstrumentation.java | 2 +- .../httpclient/HeadersAdvice.java | 3 ++ .../v1/JaxRsClientV1Instrumentation.java | 21 ++++++++++++-- 5 files changed, 46 insertions(+), 12 deletions(-) diff --git a/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientDecorator.java b/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientDecorator.java index 5847efc3f1b..6204dfda7ae 100644 --- a/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientDecorator.java +++ b/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientDecorator.java @@ -1,8 +1,5 @@ package datadog.trace.instrumentation.googlehttpclient; -import static datadog.context.Context.current; -import static datadog.trace.instrumentation.googlehttpclient.HeadersInjectAdapter.SETTER; - import com.google.api.client.http.HttpRequest; import com.google.api.client.http.HttpResponse; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; @@ -37,7 +34,6 @@ protected URI url(final HttpRequest httpRequest) throws URISyntaxException { public AgentSpan prepareSpan(AgentSpan span, HttpRequest request) { DECORATE.afterStart(span); DECORATE.onRequest(span, request); - DECORATE.injectContext(current().with(span), request, SETTER); return span; } diff --git a/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java b/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java index 870941a60d6..d9dc8c6aef5 100644 --- a/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java +++ b/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java @@ -1,11 +1,14 @@ package datadog.trace.instrumentation.googlehttpclient; +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; import static datadog.trace.instrumentation.googlehttpclient.GoogleHttpClientDecorator.DECORATE; import static datadog.trace.instrumentation.googlehttpclient.GoogleHttpClientDecorator.HTTP_REQUEST; +import static datadog.trace.instrumentation.googlehttpclient.HeadersInjectAdapter.SETTER; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.isPublic; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; @@ -16,6 +19,7 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.agent.tooling.annotation.AppliesOn; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import net.bytebuddy.asm.Advice; @@ -44,17 +48,21 @@ public String[] helperClassNames() { @Override public void methodAdvice(MethodTransformer transformer) { - transformer.applyAdvice( + transformer.applyAdvices( isMethod().and(isPublic()).and(named("execute")).and(takesArguments(0)), - GoogleHttpClientInstrumentation.class.getName() + "$GoogleHttpClientAdvice"); + GoogleHttpClientInstrumentation.class.getName() + "$GoogleHttpClientAdvice", + GoogleHttpClientInstrumentation.class.getName() + + "$GoogleHttpClientContextPropagationAdvice"); - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(isPublic()) .and(named("executeAsync")) .and(takesArguments(1)) .and(takesArgument(0, (named("java.util.concurrent.Executor")))), - GoogleHttpClientInstrumentation.class.getName() + "$GoogleHttpClientAsyncAdvice"); + GoogleHttpClientInstrumentation.class.getName() + "$GoogleHttpClientAsyncAdvice", + GoogleHttpClientInstrumentation.class.getName() + + "$GoogleHttpClientContextPropagationAdvice"); } public static class GoogleHttpClientAdvice { @@ -118,4 +126,16 @@ public static void methodExit( } } } + + @AppliesOn(CONTEXT_TRACKING) + public static class GoogleHttpClientContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void methodEnter(@Advice.This HttpRequest request) { + AgentSpan span = activeSpan(); + if (span == null) { + return; + } + DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); + } + } } diff --git a/dd-java-agent/instrumentation/java/java-net/java-net-11.0/src/main/java/datadog/trace/instrumentation/httpclient/HttpHeadersInstrumentation.java b/dd-java-agent/instrumentation/java/java-net/java-net-11.0/src/main/java/datadog/trace/instrumentation/httpclient/HttpHeadersInstrumentation.java index 82b802d70a8..1cd09452d12 100644 --- a/dd-java-agent/instrumentation/java/java-net/java-net-11.0/src/main/java/datadog/trace/instrumentation/httpclient/HttpHeadersInstrumentation.java +++ b/dd-java-agent/instrumentation/java/java-net/java-net-11.0/src/main/java/datadog/trace/instrumentation/httpclient/HttpHeadersInstrumentation.java @@ -54,6 +54,6 @@ public String[] helperClassNames() { @Override public void methodAdvice(MethodTransformer transformer) { - transformer.applyAdvice(isMethod().and(named("headers")), packageName + ".HeadersAdvice"); + transformer.applyAdvices(isMethod().and(named("headers")), packageName + ".HeadersAdvice"); } } diff --git a/dd-java-agent/instrumentation/java/java-net/java-net-11.0/src/main/java11/datadog/trace/instrumentation/httpclient/HeadersAdvice.java b/dd-java-agent/instrumentation/java/java-net/java-net-11.0/src/main/java11/datadog/trace/instrumentation/httpclient/HeadersAdvice.java index 493eec8bf3e..0657b3f44f5 100644 --- a/dd-java-agent/instrumentation/java/java-net/java-net-11.0/src/main/java11/datadog/trace/instrumentation/httpclient/HeadersAdvice.java +++ b/dd-java-agent/instrumentation/java/java-net/java-net-11.0/src/main/java11/datadog/trace/instrumentation/httpclient/HeadersAdvice.java @@ -1,17 +1,20 @@ package datadog.trace.instrumentation.httpclient; +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; import static datadog.trace.instrumentation.httpclient.HttpHeadersInjectAdapter.KEEP; import static datadog.trace.instrumentation.httpclient.HttpHeadersInjectAdapter.SETTER; import static datadog.trace.instrumentation.httpclient.JavaNetClientDecorator.DECORATE; import static java.lang.String.CASE_INSENSITIVE_ORDER; +import datadog.trace.agent.tooling.annotation.AppliesOn; import java.net.http.HttpHeaders; import java.util.List; import java.util.Map; import java.util.TreeMap; import net.bytebuddy.asm.Advice; +@AppliesOn(CONTEXT_TRACKING) public class HeadersAdvice { @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void methodExit(@Advice.Return(readOnly = false) HttpHeaders headers) { diff --git a/dd-java-agent/instrumentation/rs/jax-rs/jax-rs-client/jax-rs-client-1.1/src/main/java/datadog/trace/instrumentation/jaxrs/v1/JaxRsClientV1Instrumentation.java b/dd-java-agent/instrumentation/rs/jax-rs/jax-rs-client/jax-rs-client-1.1/src/main/java/datadog/trace/instrumentation/jaxrs/v1/JaxRsClientV1Instrumentation.java index 63f1e9a1de5..8b6c9db5f86 100644 --- a/dd-java-agent/instrumentation/rs/jax-rs/jax-rs-client/jax-rs-client-1.1/src/main/java/datadog/trace/instrumentation/jaxrs/v1/JaxRsClientV1Instrumentation.java +++ b/dd-java-agent/instrumentation/rs/jax-rs/jax-rs-client/jax-rs-client-1.1/src/main/java/datadog/trace/instrumentation/jaxrs/v1/JaxRsClientV1Instrumentation.java @@ -1,9 +1,11 @@ package datadog.trace.instrumentation.jaxrs.v1; +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.extendsClass; import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.implementsInterface; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; +import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; import static datadog.trace.bootstrap.instrumentation.decorator.HttpServerDecorator.DD_CONTEXT_ATTRIBUTE; @@ -19,6 +21,7 @@ import com.sun.jersey.api.client.ClientResponse; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.agent.tooling.annotation.AppliesOn; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import net.bytebuddy.asm.Advice; @@ -52,11 +55,12 @@ public String[] helperClassNames() { @Override public void methodAdvice(MethodTransformer transformer) { - transformer.applyAdvice( + transformer.applyAdvices( named("handle") .and(takesArgument(0, extendsClass(named("com.sun.jersey.api.client.ClientRequest")))) .and(returns(extendsClass(named("com.sun.jersey.api.client.ClientResponse")))), - JaxRsClientV1Instrumentation.class.getName() + "$HandleAdvice"); + JaxRsClientV1Instrumentation.class.getName() + "$HandleAdvice", + JaxRsClientV1Instrumentation.class.getName() + "$HandleContextPropagationAdvice"); } public static class HandleAdvice { @@ -73,7 +77,6 @@ public static AgentScope onEnter( DECORATE.afterStart(span); DECORATE.onRequest(span, request); request.getProperties().put(DD_CONTEXT_ATTRIBUTE, span); - DECORATE.injectContext(getCurrentContext().with(span), request.getHeaders(), SETTER); return activateSpan(span); } return null; @@ -95,4 +98,16 @@ public static void onExit( scope.span().finish(); } } + + @AppliesOn(CONTEXT_TRACKING) + public static class HandleContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void onEnter(@Advice.Argument(0) final ClientRequest request) { + AgentSpan span = activeSpan(); + if (span == null) { + return; + } + DECORATE.injectContext(getCurrentContext().with(span), request.getHeaders(), SETTER); + } + } } From af4266db4090362894d32c536964d0c782e57962 Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Tue, 10 Mar 2026 12:13:34 +0100 Subject: [PATCH 05/12] migrate httpclient5 --- .../ApacheHttpAsyncClientInstrumentation.java | 17 +++++++++++++++-- .../DelegatingRequestProducer.java | 9 ++++++++- .../ApacheHttpAsyncClientInstrumentation.java | 17 +++++++++++++++-- .../DelegatingRequestChannel.java | 9 +++++++-- .../DelegatingRequestProducer.java | 8 +++++++- 5 files changed, 52 insertions(+), 8 deletions(-) diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientInstrumentation.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientInstrumentation.java index 525761c110a..eaca4b863f0 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientInstrumentation.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientInstrumentation.java @@ -1,5 +1,6 @@ package datadog.trace.instrumentation.apachehttpasyncclient; +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.implementsInterface; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.captureActiveSpan; @@ -12,6 +13,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import datadog.trace.agent.tooling.Instrumenter; +import datadog.trace.agent.tooling.annotation.AppliesOn; import datadog.trace.api.InstrumenterConfig; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; @@ -61,7 +63,7 @@ public ElementMatcher hierarchyMatcher() { @Override public void methodAdvice(MethodTransformer transformer) { - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("execute")) .and(takesArguments(4)) @@ -69,7 +71,8 @@ public void methodAdvice(MethodTransformer transformer) { .and(takesArgument(1, named("org.apache.http.nio.protocol.HttpAsyncResponseConsumer"))) .and(takesArgument(2, named("org.apache.http.protocol.HttpContext"))) .and(takesArgument(3, named("org.apache.http.concurrent.FutureCallback"))), - ApacheHttpAsyncClientInstrumentation.class.getName() + "$ClientAdvice"); + ApacheHttpAsyncClientInstrumentation.class.getName() + "$ClientAdvice", + ApacheHttpAsyncClientInstrumentation.class.getName() + "$ClientContextPropagationAdvice"); } public static class ClientAdvice { @@ -104,4 +107,14 @@ public static void methodExit( } } } + + @AppliesOn(CONTEXT_TRACKING) + public static class ClientContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void onEnter(@Advice.Argument(0) final HttpAsyncRequestProducer requestProducer) { + if (requestProducer instanceof DelegatingRequestProducer) { + ((DelegatingRequestProducer) requestProducer).setInjectContext(true); + } + } + } } diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/DelegatingRequestProducer.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/DelegatingRequestProducer.java index cc4aee9342e..5116a2e12e8 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/DelegatingRequestProducer.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/DelegatingRequestProducer.java @@ -17,12 +17,17 @@ public class DelegatingRequestProducer implements HttpAsyncRequestProducer { final AgentSpan span; final HttpAsyncRequestProducer delegate; + boolean injectContext = false; public DelegatingRequestProducer(final AgentSpan span, final HttpAsyncRequestProducer delegate) { this.span = span; this.delegate = delegate; } + public void setInjectContext(boolean injectContext) { + this.injectContext = injectContext; + } + @Override public HttpHost getTarget() { return delegate.getTarget(); @@ -32,7 +37,9 @@ public HttpHost getTarget() { public HttpRequest generateRequest() throws IOException, HttpException { final HttpRequest request = delegate.generateRequest(); DECORATE.onRequest(span, new HostAndRequestAsHttpUriRequest(delegate.getTarget(), request)); - DECORATE.injectContext(current().with(span), request, SETTER); + if (injectContext) { + DECORATE.injectContext(current().with(span), request, SETTER); + } return request; } diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpAsyncClientInstrumentation.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpAsyncClientInstrumentation.java index 6249819dee0..3ac7bb854eb 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpAsyncClientInstrumentation.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpAsyncClientInstrumentation.java @@ -1,5 +1,6 @@ package datadog.trace.instrumentation.apachehttpclient5; +import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.implementsInterface; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; @@ -14,6 +15,7 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import datadog.trace.agent.tooling.annotation.AppliesOn; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -76,7 +78,7 @@ public String[] helperClassNames() { @Override public void methodAdvice(MethodTransformer transformer) { - transformer.applyAdvice( + transformer.applyAdvices( isMethod() .and(named("execute")) .and(takesArguments(5)) @@ -85,7 +87,8 @@ public void methodAdvice(MethodTransformer transformer) { .and(takesArgument(2, named("org.apache.hc.core5.http.nio.HandlerFactory"))) .and(takesArgument(3, named("org.apache.hc.core5.http.protocol.HttpContext"))) .and(takesArgument(4, named("org.apache.hc.core5.concurrent.FutureCallback"))), - this.getClass().getName() + "$ClientAdvice"); + this.getClass().getName() + "$ClientAdvice", + this.getClass().getName() + "$ClientContextPropagationAdvice"); } public static class ClientAdvice { @@ -133,4 +136,14 @@ public static void methodExit( } } } + + @AppliesOn(CONTEXT_TRACKING) + public static class ClientContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void onEnter(@Advice.Argument(0) final AsyncRequestProducer requestProducer) { + if (requestProducer instanceof DelegatingRequestProducer) { + ((DelegatingRequestProducer) requestProducer).setInjectContext(true); + } + } + } } diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/DelegatingRequestChannel.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/DelegatingRequestChannel.java index 2894796a149..367e3b45a84 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/DelegatingRequestChannel.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/DelegatingRequestChannel.java @@ -15,17 +15,22 @@ public class DelegatingRequestChannel implements RequestChannel { private final RequestChannel delegate; private final AgentSpan span; + private final boolean injectContext; - public DelegatingRequestChannel(RequestChannel requestChannel, AgentSpan span) { + public DelegatingRequestChannel( + RequestChannel requestChannel, AgentSpan span, boolean injectContext) { this.delegate = requestChannel; this.span = span; + this.injectContext = injectContext; } @Override public void sendRequest(HttpRequest request, EntityDetails entityDetails, HttpContext context) throws HttpException, IOException { DECORATE.onRequest(span, request); - DECORATE.injectContext(current().with(span), request, SETTER); + if (injectContext) { + DECORATE.injectContext(current().with(span), request, SETTER); + } delegate.sendRequest(request, entityDetails, context); } } diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/DelegatingRequestProducer.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/DelegatingRequestProducer.java index da09ec9687b..71143c22654 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/DelegatingRequestProducer.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/DelegatingRequestProducer.java @@ -11,12 +11,17 @@ public class DelegatingRequestProducer implements AsyncRequestProducer { final AgentSpan span; final AsyncRequestProducer delegate; + boolean injectContext = false; public DelegatingRequestProducer(final AgentSpan span, final AsyncRequestProducer delegate) { this.span = span; this.delegate = delegate; } + public void setInjectContext(boolean injectContext) { + this.injectContext = injectContext; + } + @Override public void failed(final Exception ex) { delegate.failed(ex); @@ -25,7 +30,8 @@ public void failed(final Exception ex) { @Override public void sendRequest(RequestChannel channel, HttpContext context) throws HttpException, IOException { - DelegatingRequestChannel requestChannel = new DelegatingRequestChannel(channel, span); + DelegatingRequestChannel requestChannel = + new DelegatingRequestChannel(channel, span, injectContext); delegate.sendRequest(requestChannel, context); } From 460265b8b9938c2b97827ce0bd6b4b906a507a19 Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Tue, 10 Mar 2026 12:32:13 +0100 Subject: [PATCH 06/12] spotless --- .../akkahttp106/AkkaHttpSingleRequestInstrumentation.java | 1 - 1 file changed, 1 deletion(-) diff --git a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java/datadog/trace/instrumentation/akkahttp106/AkkaHttpSingleRequestInstrumentation.java b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java/datadog/trace/instrumentation/akkahttp106/AkkaHttpSingleRequestInstrumentation.java index c4f3e185dc4..ee5b362437b 100644 --- a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java/datadog/trace/instrumentation/akkahttp106/AkkaHttpSingleRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java/datadog/trace/instrumentation/akkahttp106/AkkaHttpSingleRequestInstrumentation.java @@ -1,6 +1,5 @@ package datadog.trace.instrumentation.akkahttp106; -import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; From 6930b27c7289d98e7d5a0e095f7907fde1b6c61c Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Wed, 11 Mar 2026 11:39:37 +0100 Subject: [PATCH 07/12] fix bad ai stuff --- .../AkkaHttpSingleRequestInstrumentation.java | 14 +++----- .../akkahttp106/SingleRequestAdvice.java | 2 +- ...SingleRequestContextPropagationAdvice.java | 13 +++---- .../ApacheHttpAsyncClientInstrumentation.java | 34 +++++++++++-------- .../DelegatingRequestProducer.java | 16 ++++++--- .../apachehttpclient/HelperMethods.java | 16 ++------- .../ApacheHttpAsyncClientInstrumentation.java | 32 ++++++++++------- .../ApacheHttpClientInstrumentation.java | 14 ++++---- .../DelegatingRequestProducer.java | 9 +++-- .../apachehttpclient5/HelperMethods.java | 7 +--- .../client/ClientCallImplInstrumentation.java | 7 ++-- .../CommonsHttpClientInstrumentation.java | 5 --- .../GoogleHttpClientInstrumentation.java | 4 --- .../AsyncHttpClientInstrumentation.java | 6 +--- .../SendContextPropagationAdvice.java | 8 +---- .../JettyClientInstrumentation.java | 6 +--- ...PekkoHttpSingleRequestInstrumentation.java | 10 +----- .../playws1/PlayWSClientInstrumentation.java | 12 +++---- .../playws2/PlayWSClientInstrumentation.java | 12 +++---- .../playws21/PlayWSClientInstrumentation.java | 12 +++---- .../BasePlayWSClientInstrumentation.java | 8 +---- .../v1/JaxRsClientV1Instrumentation.java | 7 +--- 22 files changed, 102 insertions(+), 152 deletions(-) diff --git a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/AkkaHttpSingleRequestInstrumentation.java b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/AkkaHttpSingleRequestInstrumentation.java index f72034e75a8..cff65c5f4c7 100644 --- a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/AkkaHttpSingleRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/AkkaHttpSingleRequestInstrumentation.java @@ -3,7 +3,6 @@ import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; import static datadog.trace.instrumentation.akkahttp.AkkaHttpClientDecorator.AKKA_CLIENT_REQUEST; @@ -66,8 +65,7 @@ public void methodAdvice(MethodTransformer transformer) { public static class SingleRequestAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static AgentScope methodEnter( - @Advice.Argument(value = 0, readOnly = false) HttpRequest request) { + public static AgentScope methodEnter(@Advice.Argument(value = 0) final HttpRequest request) { /* Versions 10.0 and 10.1 have slightly different structure that is hard to distinguish so here we cast 'wider net' and avoid instrumenting twice. @@ -113,15 +111,11 @@ public static class SingleRequestContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void methodEnter( @Advice.Argument(value = 0, readOnly = false) HttpRequest request) { - final AkkaHttpHeaders headers = new AkkaHttpHeaders(request); - if (headers.hadSpan()) { + if (request == null) { return; } - AgentSpan span = activeSpan(); - if (span == null) { - return; - } - DECORATE.injectContext(getCurrentContext().with(span), request, headers); + final AkkaHttpHeaders headers = new AkkaHttpHeaders(request); + DECORATE.injectContext(getCurrentContext(), request, headers); request = headers.getRequest(); } } diff --git a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestAdvice.java b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestAdvice.java index 77e10b5cfde..955ec074785 100644 --- a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestAdvice.java +++ b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestAdvice.java @@ -16,7 +16,7 @@ public class SingleRequestAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static AgentScope methodEnter( - @Advice.Argument(value = 0, readOnly = false) HttpRequest request) { + @Advice.Argument(value = 0) final HttpRequest request) { final AkkaHttpClientHelpers.AkkaHttpHeaders headers = new AkkaHttpClientHelpers.AkkaHttpHeaders(request); if (headers.hadSpan()) { diff --git a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestContextPropagationAdvice.java b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestContextPropagationAdvice.java index 78057b50480..b2aeb8cf715 100644 --- a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestContextPropagationAdvice.java +++ b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestContextPropagationAdvice.java @@ -15,16 +15,13 @@ public class SingleRequestContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void methodEnter( @Advice.Argument(value = 0, readOnly = false) HttpRequest request) { - final AkkaHttpClientHelpers.AkkaHttpHeaders headers = - new AkkaHttpClientHelpers.AkkaHttpHeaders(request); - if (headers.hadSpan()) { - return; - } - AgentSpan span = activeSpan(); - if (span == null) { + if (request == null) { return; } - DECORATE.injectContext(getCurrentContext().with(span), request, headers); + final AkkaHttpClientHelpers.AkkaHttpHeaders headers = + new AkkaHttpClientHelpers.AkkaHttpHeaders(request); + + DECORATE.injectContext(getCurrentContext(), request, headers); request = headers.getRequest(); } } diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientInstrumentation.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientInstrumentation.java index eaca4b863f0..735662886c6 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientInstrumentation.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientInstrumentation.java @@ -71,23 +71,37 @@ public void methodAdvice(MethodTransformer transformer) { .and(takesArgument(1, named("org.apache.http.nio.protocol.HttpAsyncResponseConsumer"))) .and(takesArgument(2, named("org.apache.http.protocol.HttpContext"))) .and(takesArgument(3, named("org.apache.http.concurrent.FutureCallback"))), - ApacheHttpAsyncClientInstrumentation.class.getName() + "$ClientAdvice", - ApacheHttpAsyncClientInstrumentation.class.getName() + "$ClientContextPropagationAdvice"); + ApacheHttpAsyncClientInstrumentation.class.getName() + "$ClientContextPropagationAdvice", + ApacheHttpAsyncClientInstrumentation.class.getName() + "$ClientAdvice"); } - public static class ClientAdvice { + @AppliesOn(CONTEXT_TRACKING) + public static class ClientContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void methodEnter( + @Advice.Argument(value = 0, readOnly = false) HttpAsyncRequestProducer requestProducer) { + final DelegatingRequestProducer delegatingRequestProducer = + new DelegatingRequestProducer(requestProducer); + delegatingRequestProducer.setInjectContext(true); + requestProducer = delegatingRequestProducer; + } + } + public static class ClientAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static AgentSpan methodEnter( @Advice.Argument(value = 0, readOnly = false) HttpAsyncRequestProducer requestProducer, @Advice.Argument(2) HttpContext context, @Advice.Argument(value = 3, readOnly = false) FutureCallback futureCallback) { + if (!(requestProducer instanceof DelegatingRequestProducer)) { + requestProducer = new DelegatingRequestProducer(requestProducer); + } + final AgentScope.Continuation parentContinuation = captureActiveSpan(); final AgentSpan clientSpan = startSpan(HTTP_REQUEST); DECORATE.afterStart(clientSpan); - - requestProducer = new DelegatingRequestProducer(clientSpan, requestProducer); + ((DelegatingRequestProducer) requestProducer).setSpan(clientSpan); futureCallback = new TraceContinuedFutureCallback<>( parentContinuation, clientSpan, context, futureCallback); @@ -107,14 +121,4 @@ public static void methodExit( } } } - - @AppliesOn(CONTEXT_TRACKING) - public static class ClientContextPropagationAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter(@Advice.Argument(0) final HttpAsyncRequestProducer requestProducer) { - if (requestProducer instanceof DelegatingRequestProducer) { - ((DelegatingRequestProducer) requestProducer).setInjectContext(true); - } - } - } } diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/DelegatingRequestProducer.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/DelegatingRequestProducer.java index 5116a2e12e8..21ab1157320 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/DelegatingRequestProducer.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/DelegatingRequestProducer.java @@ -4,6 +4,7 @@ import static datadog.trace.instrumentation.apachehttpasyncclient.ApacheHttpAsyncClientDecorator.DECORATE; import static datadog.trace.instrumentation.apachehttpasyncclient.HttpHeadersInjectAdapter.SETTER; +import datadog.context.Context; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import java.io.IOException; import org.apache.http.HttpException; @@ -15,12 +16,11 @@ import org.apache.http.protocol.HttpContext; public class DelegatingRequestProducer implements HttpAsyncRequestProducer { - final AgentSpan span; + AgentSpan span; final HttpAsyncRequestProducer delegate; boolean injectContext = false; - public DelegatingRequestProducer(final AgentSpan span, final HttpAsyncRequestProducer delegate) { - this.span = span; + public DelegatingRequestProducer(final HttpAsyncRequestProducer delegate) { this.delegate = delegate; } @@ -28,6 +28,10 @@ public void setInjectContext(boolean injectContext) { this.injectContext = injectContext; } + public void setSpan(final AgentSpan span) { + this.span = span; + } + @Override public HttpHost getTarget() { return delegate.getTarget(); @@ -38,7 +42,11 @@ public HttpRequest generateRequest() throws IOException, HttpException { final HttpRequest request = delegate.generateRequest(); DECORATE.onRequest(span, new HostAndRequestAsHttpUriRequest(delegate.getTarget(), request)); if (injectContext) { - DECORATE.injectContext(current().with(span), request, SETTER); + Context receiver = current(); + if (span != null) { + receiver = receiver.with(span); + } + DECORATE.injectContext(receiver, request, SETTER); } return request; } diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpclient/HelperMethods.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpclient/HelperMethods.java index e7eca09f24c..758edb5f754 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpclient/HelperMethods.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpclient/HelperMethods.java @@ -2,7 +2,6 @@ import static datadog.context.Context.current; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.instrumentation.apachehttpclient.ApacheHttpClientDecorator.DECORATE; import static datadog.trace.instrumentation.apachehttpclient.ApacheHttpClientDecorator.HTTP_REQUEST; @@ -49,11 +48,7 @@ public static void doInjectContext(final HttpUriRequest request) { if (request.containsHeader("amz-sdk-invocation-id")) { return; } - final AgentSpan span = activeSpan(); - if (span == null) { - return; - } - DECORATE.injectContext(current().with(span), request, SETTER); + DECORATE.injectContext(current(), request, SETTER); } public static void doInjectContext(final HttpHost host, final HttpRequest request) { @@ -63,14 +58,7 @@ public static void doInjectContext(final HttpHost host, final HttpRequest reques } else { uriRequest = new HostAndRequestAsHttpUriRequest(host, request); } - if (uriRequest.containsHeader("amz-sdk-invocation-id")) { - return; - } - final AgentSpan span = activeSpan(); - if (span == null) { - return; - } - DECORATE.injectContext(current().with(span), uriRequest, SETTER); + doInjectContext(uriRequest); } public static void doMethodExit( diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpAsyncClientInstrumentation.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpAsyncClientInstrumentation.java index 3ac7bb854eb..c2dc0bb7e90 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpAsyncClientInstrumentation.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpAsyncClientInstrumentation.java @@ -87,8 +87,20 @@ public void methodAdvice(MethodTransformer transformer) { .and(takesArgument(2, named("org.apache.hc.core5.http.nio.HandlerFactory"))) .and(takesArgument(3, named("org.apache.hc.core5.http.protocol.HttpContext"))) .and(takesArgument(4, named("org.apache.hc.core5.concurrent.FutureCallback"))), - this.getClass().getName() + "$ClientAdvice", - this.getClass().getName() + "$ClientContextPropagationAdvice"); + this.getClass().getName() + "$ClientContextPropagationAdvice", + this.getClass().getName() + "$ClientAdvice"); + } + + @AppliesOn(CONTEXT_TRACKING) + public static class ClientContextPropagationAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void onEnter( + @Advice.Argument(value = 0, readOnly = false) AsyncRequestProducer requestProducer) { + final DelegatingRequestProducer delegatingRequestProducer = + new DelegatingRequestProducer(requestProducer); + delegatingRequestProducer.setInjectContext(true); + requestProducer = delegatingRequestProducer; + } } public static class ClientAdvice { @@ -108,7 +120,11 @@ public static AgentScope methodEnter( context = new BasicHttpContext(); } - requestProducer = new DelegatingRequestProducer(clientSpan, requestProducer); + if (!(requestProducer instanceof DelegatingRequestProducer)) { + requestProducer = new DelegatingRequestProducer(requestProducer); + } + + ((DelegatingRequestProducer) requestProducer).setSpan(clientSpan); futureCallback = new TraceContinuedFutureCallback<>( parentContinuation, clientSpan, context, futureCallback); @@ -136,14 +152,4 @@ public static void methodExit( } } } - - @AppliesOn(CONTEXT_TRACKING) - public static class ClientContextPropagationAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter(@Advice.Argument(0) final AsyncRequestProducer requestProducer) { - if (requestProducer instanceof DelegatingRequestProducer) { - ((DelegatingRequestProducer) requestProducer).setInjectContext(true); - } - } - } } diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpClientInstrumentation.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpClientInstrumentation.java index 64b783b7d41..d1e1d2752a7 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpClientInstrumentation.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpClientInstrumentation.java @@ -78,7 +78,7 @@ public void methodAdvice(MethodTransformer transformer) { .and(takesArguments(1)) .and(takesArgument(0, named("org.apache.hc.core5.http.ClassicHttpRequest"))), ApacheHttpClientInstrumentation.class.getName() + "$RequestAdvice", - ApacheHttpClientInstrumentation.class.getName() + "$RequestContextPropagationAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$ContextPropagationAdviceArg0"); transformer.applyAdvices( isMethod() @@ -87,7 +87,7 @@ public void methodAdvice(MethodTransformer transformer) { .and(takesArgument(0, named("org.apache.hc.core5.http.ClassicHttpRequest"))) .and(takesArgument(1, named("org.apache.hc.core5.http.protocol.HttpContext"))), ApacheHttpClientInstrumentation.class.getName() + "$RequestAdvice", - ApacheHttpClientInstrumentation.class.getName() + "$RequestContextPropagationAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$ContextPropagationAdviceArg0"); transformer.applyAdvices( isMethod() @@ -97,7 +97,7 @@ public void methodAdvice(MethodTransformer transformer) { .and(takesArgument(1, named("org.apache.hc.core5.http.ClassicHttpRequest"))) .and(takesArgument(2, named("org.apache.hc.core5.http.protocol.HttpContext"))), ApacheHttpClientInstrumentation.class.getName() + "$HostRequestAdvice", - ApacheHttpClientInstrumentation.class.getName() + "$HostRequestContextPropagationAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$ContextPropagationAdviceArg1"); transformer.applyAdvices( isMethod() @@ -106,7 +106,7 @@ public void methodAdvice(MethodTransformer transformer) { .and(takesArgument(0, named("org.apache.hc.core5.http.HttpHost"))) .and(takesArgument(1, named("org.apache.hc.core5.http.ClassicHttpRequest"))), ApacheHttpClientInstrumentation.class.getName() + "$HostRequestAdvice", - ApacheHttpClientInstrumentation.class.getName() + "$HostRequestContextPropagationAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$ContextPropagationAdviceArg1"); transformer.applyAdvices( isMethod() @@ -117,7 +117,7 @@ public void methodAdvice(MethodTransformer transformer) { .and(takesArgument(2, named("org.apache.hc.core5.http.protocol.HttpContext"))) .and(takesArgument(3, named("org.apache.hc.core5.http.io.HttpClientResponseHandler"))), ApacheHttpClientInstrumentation.class.getName() + "$ResponseHandlerAdvice", - ApacheHttpClientInstrumentation.class.getName() + "$HostRequestContextPropagationAdvice"); + ApacheHttpClientInstrumentation.class.getName() + "$ContextPropagationAdviceArg1"); } public static class RequestAdvice { @@ -203,7 +203,7 @@ public static void methodExit( } @AppliesOn(CONTEXT_TRACKING) - public static class RequestContextPropagationAdvice { + public static class ContextPropagationAdviceArg0 { @Advice.OnMethodEnter(suppress = Throwable.class) public static void methodEnter(@Advice.Argument(0) final ClassicHttpRequest request) { HelperMethods.doInjectContext(request); @@ -211,7 +211,7 @@ public static void methodEnter(@Advice.Argument(0) final ClassicHttpRequest requ } @AppliesOn(CONTEXT_TRACKING) - public static class HostRequestContextPropagationAdvice { + public static class ContextPropagationAdviceArg1 { @Advice.OnMethodEnter(suppress = Throwable.class) public static void methodEnter(@Advice.Argument(1) final ClassicHttpRequest request) { HelperMethods.doInjectContext(request); diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/DelegatingRequestProducer.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/DelegatingRequestProducer.java index 71143c22654..50ecf1b729b 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/DelegatingRequestProducer.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/DelegatingRequestProducer.java @@ -9,15 +9,18 @@ import org.apache.hc.core5.http.protocol.HttpContext; public class DelegatingRequestProducer implements AsyncRequestProducer { - final AgentSpan span; + AgentSpan span; final AsyncRequestProducer delegate; boolean injectContext = false; - public DelegatingRequestProducer(final AgentSpan span, final AsyncRequestProducer delegate) { - this.span = span; + public DelegatingRequestProducer(final AsyncRequestProducer delegate) { this.delegate = delegate; } + public void setSpan(AgentSpan span) { + this.span = span; + } + public void setInjectContext(boolean injectContext) { this.injectContext = injectContext; } diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/HelperMethods.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/HelperMethods.java index 8cc80661c65..e30233b65da 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/HelperMethods.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/HelperMethods.java @@ -2,7 +2,6 @@ import static datadog.context.Context.current; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.instrumentation.apachehttpclient5.ApacheHttpClientDecorator.DECORATE; import static datadog.trace.instrumentation.apachehttpclient5.ApacheHttpClientDecorator.HTTP_REQUEST; @@ -49,11 +48,7 @@ public static void doInjectContext(final HttpRequest request) { if (request.containsHeader("amz-sdk-invocation-id")) { return; } - final AgentSpan span = activeSpan(); - if (span == null) { - return; - } - DECORATE.injectContext(current().with(span), request, SETTER); + DECORATE.injectContext(current(), request, SETTER); } public static void doMethodExit( diff --git a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/ClientCallImplInstrumentation.java b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/ClientCallImplInstrumentation.java index 0a459d91e5d..5809e6c005c 100644 --- a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/ClientCallImplInstrumentation.java +++ b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/ClientCallImplInstrumentation.java @@ -20,6 +20,7 @@ import datadog.trace.bootstrap.InstrumentationContext; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge; import io.grpc.ClientCall; import io.grpc.Metadata; import io.grpc.MethodDescriptor; @@ -127,11 +128,7 @@ public static void after( public static final class StartContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void before(@Advice.Argument(1) Metadata headers) { - AgentSpan span = activeSpan(); - if (span == null) { - return; - } - DECORATE.injectContext(span, headers, SETTER); + DECORATE.injectContext(Java8BytecodeBridge.getCurrentContext(), headers, SETTER); } } diff --git a/dd-java-agent/instrumentation/commons-httpclient-2.0/src/main/java/datadog/trace/instrumentation/commonshttpclient/CommonsHttpClientInstrumentation.java b/dd-java-agent/instrumentation/commons-httpclient-2.0/src/main/java/datadog/trace/instrumentation/commonshttpclient/CommonsHttpClientInstrumentation.java index 6edd7a93010..db907e4de08 100644 --- a/dd-java-agent/instrumentation/commons-httpclient-2.0/src/main/java/datadog/trace/instrumentation/commonshttpclient/CommonsHttpClientInstrumentation.java +++ b/dd-java-agent/instrumentation/commons-httpclient-2.0/src/main/java/datadog/trace/instrumentation/commonshttpclient/CommonsHttpClientInstrumentation.java @@ -3,7 +3,6 @@ import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; import static datadog.trace.instrumentation.commonshttpclient.CommonsHttpClientDecorator.DECORATE; @@ -106,10 +105,6 @@ public static void methodExit( public static class ContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void methodEnter(@Advice.Argument(1) final HttpMethod httpMethod) { - AgentSpan span = activeSpan(); - if (span == null) { - return; - } DECORATE.injectContext(getCurrentContext().with(span), httpMethod, SETTER); } } diff --git a/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java b/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java index d9dc8c6aef5..7eb41b19b46 100644 --- a/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java +++ b/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java @@ -131,10 +131,6 @@ public static void methodExit( public static class GoogleHttpClientContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void methodEnter(@Advice.This HttpRequest request) { - AgentSpan span = activeSpan(); - if (span == null) { - return; - } DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); } } diff --git a/dd-java-agent/instrumentation/grizzly/grizzly-client-1.9/src/main/java/datadog/trace/instrumentation/grizzly/client/AsyncHttpClientInstrumentation.java b/dd-java-agent/instrumentation/grizzly/grizzly-client-1.9/src/main/java/datadog/trace/instrumentation/grizzly/client/AsyncHttpClientInstrumentation.java index c0e1c583669..a8b87193d1c 100644 --- a/dd-java-agent/instrumentation/grizzly/grizzly-client-1.9/src/main/java/datadog/trace/instrumentation/grizzly/client/AsyncHttpClientInstrumentation.java +++ b/dd-java-agent/instrumentation/grizzly/grizzly-client-1.9/src/main/java/datadog/trace/instrumentation/grizzly/client/AsyncHttpClientInstrumentation.java @@ -73,11 +73,7 @@ public static void onExit( public static class ExecuteContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void onEnter(@Advice.Argument(0) final Request request) { - AgentSpan span = activeSpan(); - if (span == null) { - return; - } - DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); + DECORATE.injectContext(getCurrentContext(), request, SETTER); } } } diff --git a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java11/datadog/trace/instrumentation/jetty_client10/SendContextPropagationAdvice.java b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java11/datadog/trace/instrumentation/jetty_client10/SendContextPropagationAdvice.java index 73b2c8cea62..7348b9da47d 100644 --- a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java11/datadog/trace/instrumentation/jetty_client10/SendContextPropagationAdvice.java +++ b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java11/datadog/trace/instrumentation/jetty_client10/SendContextPropagationAdvice.java @@ -6,8 +6,6 @@ import static datadog.trace.instrumentation.jetty_client10.JettyClientDecorator.DECORATE; import datadog.trace.agent.tooling.annotation.AppliesOn; -import datadog.trace.bootstrap.InstrumentationContext; -import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import net.bytebuddy.asm.Advice; import org.eclipse.jetty.client.api.Request; @@ -15,10 +13,6 @@ public class SendContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void methodEnter(@Advice.Argument(0) final Request request) { - AgentSpan span = InstrumentationContext.get(Request.class, AgentSpan.class).get(request); - if (span == null) { - return; - } - DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); + DECORATE.injectContext(getCurrentContext(), request, SETTER); } } diff --git a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-9.1/src/main/java/datadog/trace/instrumentation/jetty_client91/JettyClientInstrumentation.java b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-9.1/src/main/java/datadog/trace/instrumentation/jetty_client91/JettyClientInstrumentation.java index 6ce36afd159..808dd9f35b8 100644 --- a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-9.1/src/main/java/datadog/trace/instrumentation/jetty_client91/JettyClientInstrumentation.java +++ b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-9.1/src/main/java/datadog/trace/instrumentation/jetty_client91/JettyClientInstrumentation.java @@ -111,11 +111,7 @@ public static void methodExit( public static class ContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void methodEnter(@Advice.Argument(0) final Request request) { - AgentSpan span = InstrumentationContext.get(Request.class, AgentSpan.class).get(request); - if (span == null) { - return; - } - DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); + DECORATE.injectContext(getCurrentContext(), request, SETTER); } } } diff --git a/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/PekkoHttpSingleRequestInstrumentation.java b/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/PekkoHttpSingleRequestInstrumentation.java index 3e3ad0678ac..e286100db94 100644 --- a/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/PekkoHttpSingleRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/PekkoHttpSingleRequestInstrumentation.java @@ -3,7 +3,6 @@ import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; import static datadog.trace.instrumentation.pekkohttp.PekkoHttpClientDecorator.DECORATE; @@ -115,14 +114,7 @@ public static class SingleRequestContextPropagationAdvice { public static void methodEnter( @Advice.Argument(value = 0, readOnly = false) HttpRequest request) { final PekkoHttpHeaders headers = new PekkoHttpHeaders(request); - if (headers.hadSpan()) { - return; - } - AgentSpan span = activeSpan(); - if (span == null) { - return; - } - DECORATE.injectContext(getCurrentContext().with(span), request, headers); + DECORATE.injectContext(getCurrentContext(), request, headers); request = headers.getRequest(); } } diff --git a/dd-java-agent/instrumentation/play-ws/play-ws-1.0/src/main/java/datadog/trace/instrumentation/playws1/PlayWSClientInstrumentation.java b/dd-java-agent/instrumentation/play-ws/play-ws-1.0/src/main/java/datadog/trace/instrumentation/playws1/PlayWSClientInstrumentation.java index 6cec1300f48..154ff59edb0 100644 --- a/dd-java-agent/instrumentation/play-ws/play-ws-1.0/src/main/java/datadog/trace/instrumentation/playws1/PlayWSClientInstrumentation.java +++ b/dd-java-agent/instrumentation/play-ws/play-ws-1.0/src/main/java/datadog/trace/instrumentation/playws1/PlayWSClientInstrumentation.java @@ -1,14 +1,14 @@ package datadog.trace.instrumentation.playws1; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.instrumentation.playws.PlayWSClientDecorator.DECORATE; import static datadog.trace.instrumentation.playws.PlayWSClientDecorator.PLAY_WS_REQUEST; import com.google.auto.service.AutoService; +import datadog.context.ContextScope; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge; import datadog.trace.instrumentation.playws.BasePlayWSClientInstrumentation; import net.bytebuddy.asm.Advice; import play.shaded.ahc.org.asynchttpclient.AsyncHandler; @@ -20,7 +20,7 @@ public class PlayWSClientInstrumentation extends BasePlayWSClientInstrumentation { public static class ClientAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static AgentScope methodEnter( + public static ContextScope methodEnter( @Advice.Argument(0) final Request request, @Advice.Argument(value = 1, readOnly = false) AsyncHandler asyncHandler) { @@ -36,17 +36,17 @@ public static AgentScope methodEnter( asyncHandler = new AsyncHandlerWrapper(asyncHandler, span); } - return activateSpan(span); + return Java8BytecodeBridge.getCurrentContext().with(span).attach(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void methodExit( - @Advice.Enter final AgentScope scope, @Advice.Thrown final Throwable throwable) { + @Advice.Enter final ContextScope scope, @Advice.Thrown final Throwable throwable) { if (scope == null) { return; } if (throwable != null) { - final AgentSpan span = scope.span(); + final AgentSpan span = Java8BytecodeBridge.spanFromContext(scope.context()); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); span.finish(); diff --git a/dd-java-agent/instrumentation/play-ws/play-ws-2.0/src/main/java/datadog/trace/instrumentation/playws2/PlayWSClientInstrumentation.java b/dd-java-agent/instrumentation/play-ws/play-ws-2.0/src/main/java/datadog/trace/instrumentation/playws2/PlayWSClientInstrumentation.java index 2d97250348a..08ea1c509f2 100644 --- a/dd-java-agent/instrumentation/play-ws/play-ws-2.0/src/main/java/datadog/trace/instrumentation/playws2/PlayWSClientInstrumentation.java +++ b/dd-java-agent/instrumentation/play-ws/play-ws-2.0/src/main/java/datadog/trace/instrumentation/playws2/PlayWSClientInstrumentation.java @@ -1,14 +1,14 @@ package datadog.trace.instrumentation.playws2; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.instrumentation.playws.PlayWSClientDecorator.DECORATE; import static datadog.trace.instrumentation.playws.PlayWSClientDecorator.PLAY_WS_REQUEST; import com.google.auto.service.AutoService; +import datadog.context.ContextScope; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge; import datadog.trace.instrumentation.playws.BasePlayWSClientInstrumentation; import net.bytebuddy.asm.Advice; import play.shaded.ahc.org.asynchttpclient.AsyncHandler; @@ -20,7 +20,7 @@ public class PlayWSClientInstrumentation extends BasePlayWSClientInstrumentation { public static class ClientAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static AgentScope methodEnter( + public static ContextScope methodEnter( @Advice.Argument(0) final Request request, @Advice.Argument(value = 1, readOnly = false) AsyncHandler asyncHandler) { @@ -36,17 +36,17 @@ public static AgentScope methodEnter( asyncHandler = new AsyncHandlerWrapper(asyncHandler, span); } - return activateSpan(span); + return Java8BytecodeBridge.getCurrentContext().with(span).attach(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void methodExit( - @Advice.Enter final AgentScope scope, @Advice.Thrown final Throwable throwable) { + @Advice.Enter final ContextScope scope, @Advice.Thrown final Throwable throwable) { if (scope == null) { return; } if (throwable != null) { - final AgentSpan span = scope.span(); + final AgentSpan span = Java8BytecodeBridge.spanFromContext(scope.context()); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); span.finish(); diff --git a/dd-java-agent/instrumentation/play-ws/play-ws-2.1/src/main/java/datadog/trace/instrumentation/playws21/PlayWSClientInstrumentation.java b/dd-java-agent/instrumentation/play-ws/play-ws-2.1/src/main/java/datadog/trace/instrumentation/playws21/PlayWSClientInstrumentation.java index 0187a6e17e9..a28952016ff 100644 --- a/dd-java-agent/instrumentation/play-ws/play-ws-2.1/src/main/java/datadog/trace/instrumentation/playws21/PlayWSClientInstrumentation.java +++ b/dd-java-agent/instrumentation/play-ws/play-ws-2.1/src/main/java/datadog/trace/instrumentation/playws21/PlayWSClientInstrumentation.java @@ -1,14 +1,14 @@ package datadog.trace.instrumentation.playws21; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.instrumentation.playws.PlayWSClientDecorator.DECORATE; import static datadog.trace.instrumentation.playws.PlayWSClientDecorator.PLAY_WS_REQUEST; import com.google.auto.service.AutoService; +import datadog.context.ContextScope; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge; import datadog.trace.instrumentation.playws.BasePlayWSClientInstrumentation; import net.bytebuddy.asm.Advice; import play.shaded.ahc.org.asynchttpclient.AsyncHandler; @@ -20,7 +20,7 @@ public class PlayWSClientInstrumentation extends BasePlayWSClientInstrumentation { public static class ClientAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static AgentScope methodEnter( + public static ContextScope methodEnter( @Advice.Argument(0) final Request request, @Advice.Argument(value = 1, readOnly = false) AsyncHandler asyncHandler) { @@ -36,17 +36,17 @@ public static AgentScope methodEnter( asyncHandler = new AsyncHandlerWrapper(asyncHandler, span); } - return activateSpan(span); + return Java8BytecodeBridge.getCurrentContext().with(span).attach(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void methodExit( - @Advice.Enter final AgentScope scope, @Advice.Thrown final Throwable throwable) { + @Advice.Enter final ContextScope scope, @Advice.Thrown final Throwable throwable) { if (scope == null) { return; } if (throwable != null) { - final AgentSpan span = scope.span(); + final AgentSpan span = Java8BytecodeBridge.spanFromContext(scope.context()); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); span.finish(); diff --git a/dd-java-agent/instrumentation/play-ws/play-ws-common/src/main/java/datadog/trace/instrumentation/playws/BasePlayWSClientInstrumentation.java b/dd-java-agent/instrumentation/play-ws/play-ws-common/src/main/java/datadog/trace/instrumentation/playws/BasePlayWSClientInstrumentation.java index 2850c2dcbe6..fcf90c9088d 100644 --- a/dd-java-agent/instrumentation/play-ws/play-ws-common/src/main/java/datadog/trace/instrumentation/playws/BasePlayWSClientInstrumentation.java +++ b/dd-java-agent/instrumentation/play-ws/play-ws-common/src/main/java/datadog/trace/instrumentation/playws/BasePlayWSClientInstrumentation.java @@ -4,7 +4,6 @@ import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.implementsInterface; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.nameStartsWith; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; import static datadog.trace.instrumentation.playws.HeadersInjectAdapter.SETTER; import static datadog.trace.instrumentation.playws.PlayWSClientDecorator.DECORATE; @@ -16,7 +15,6 @@ import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.annotation.AppliesOn; -import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -69,11 +67,7 @@ public String[] helperClassNames() { public static class ClientContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void methodEnter(@Advice.Argument(0) final Request request) { - AgentSpan span = activeSpan(); - if (span == null) { - return; - } - DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); + DECORATE.injectContext(getCurrentContext(), request, SETTER); } } } diff --git a/dd-java-agent/instrumentation/rs/jax-rs/jax-rs-client/jax-rs-client-1.1/src/main/java/datadog/trace/instrumentation/jaxrs/v1/JaxRsClientV1Instrumentation.java b/dd-java-agent/instrumentation/rs/jax-rs/jax-rs-client/jax-rs-client-1.1/src/main/java/datadog/trace/instrumentation/jaxrs/v1/JaxRsClientV1Instrumentation.java index 8b6c9db5f86..5db42c50be8 100644 --- a/dd-java-agent/instrumentation/rs/jax-rs/jax-rs-client/jax-rs-client-1.1/src/main/java/datadog/trace/instrumentation/jaxrs/v1/JaxRsClientV1Instrumentation.java +++ b/dd-java-agent/instrumentation/rs/jax-rs/jax-rs-client/jax-rs-client-1.1/src/main/java/datadog/trace/instrumentation/jaxrs/v1/JaxRsClientV1Instrumentation.java @@ -5,7 +5,6 @@ import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.implementsInterface; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; import static datadog.trace.bootstrap.instrumentation.decorator.HttpServerDecorator.DD_CONTEXT_ATTRIBUTE; @@ -103,11 +102,7 @@ public static void onExit( public static class HandleContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void onEnter(@Advice.Argument(0) final ClientRequest request) { - AgentSpan span = activeSpan(); - if (span == null) { - return; - } - DECORATE.injectContext(getCurrentContext().with(span), request.getHeaders(), SETTER); + DECORATE.injectContext(getCurrentContext(), request.getHeaders(), SETTER); } } } From c0cf2fc6d98ff260297a8d28c35b49f9eb6cba2e Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Wed, 11 Mar 2026 12:33:14 +0100 Subject: [PATCH 08/12] Fix compile --- .../commonshttpclient/CommonsHttpClientInstrumentation.java | 2 +- .../googlehttpclient/GoogleHttpClientInstrumentation.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dd-java-agent/instrumentation/commons-httpclient-2.0/src/main/java/datadog/trace/instrumentation/commonshttpclient/CommonsHttpClientInstrumentation.java b/dd-java-agent/instrumentation/commons-httpclient-2.0/src/main/java/datadog/trace/instrumentation/commonshttpclient/CommonsHttpClientInstrumentation.java index db907e4de08..db4b5d4d37f 100644 --- a/dd-java-agent/instrumentation/commons-httpclient-2.0/src/main/java/datadog/trace/instrumentation/commonshttpclient/CommonsHttpClientInstrumentation.java +++ b/dd-java-agent/instrumentation/commons-httpclient-2.0/src/main/java/datadog/trace/instrumentation/commonshttpclient/CommonsHttpClientInstrumentation.java @@ -105,7 +105,7 @@ public static void methodExit( public static class ContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void methodEnter(@Advice.Argument(1) final HttpMethod httpMethod) { - DECORATE.injectContext(getCurrentContext().with(span), httpMethod, SETTER); + DECORATE.injectContext(getCurrentContext(), httpMethod, SETTER); } } } diff --git a/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java b/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java index 7eb41b19b46..93edb10af51 100644 --- a/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java +++ b/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java @@ -131,7 +131,7 @@ public static void methodExit( public static class GoogleHttpClientContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void methodEnter(@Advice.This HttpRequest request) { - DECORATE.injectContext(getCurrentContext().with(span), request, SETTER); + DECORATE.injectContext(getCurrentContext(), request, SETTER); } } } From 016c0e2c4deb9203f8f2c99dd10f36629930e1be Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Wed, 11 Mar 2026 12:36:48 +0100 Subject: [PATCH 09/12] spotless --- .../trace/instrumentation/akkahttp106/SingleRequestAdvice.java | 3 +-- .../akkahttp106/SingleRequestContextPropagationAdvice.java | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestAdvice.java b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestAdvice.java index 955ec074785..9ab8e3a3cce 100644 --- a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestAdvice.java +++ b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestAdvice.java @@ -15,8 +15,7 @@ public class SingleRequestAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static AgentScope methodEnter( - @Advice.Argument(value = 0) final HttpRequest request) { + public static AgentScope methodEnter(@Advice.Argument(value = 0) final HttpRequest request) { final AkkaHttpClientHelpers.AkkaHttpHeaders headers = new AkkaHttpClientHelpers.AkkaHttpHeaders(request); if (headers.hadSpan()) { diff --git a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestContextPropagationAdvice.java b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestContextPropagationAdvice.java index b2aeb8cf715..49f9ce99e7b 100644 --- a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestContextPropagationAdvice.java +++ b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestContextPropagationAdvice.java @@ -1,13 +1,11 @@ package datadog.trace.instrumentation.akkahttp106; import static datadog.trace.agent.tooling.InstrumenterModule.TargetSystem.CONTEXT_TRACKING; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan; import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext; import static datadog.trace.instrumentation.akkahttp106.AkkaHttpClientDecorator.DECORATE; import akka.http.scaladsl.model.HttpRequest; import datadog.trace.agent.tooling.annotation.AppliesOn; -import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import net.bytebuddy.asm.Advice; @AppliesOn(CONTEXT_TRACKING) From 1e0d872f1a2daa6808801be090763bf7845a0283 Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Wed, 11 Mar 2026 17:46:09 +0100 Subject: [PATCH 10/12] Use blackhole for grpc ignored methods --- .../armeria/grpc/client/GrpcClientDecorator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcClientDecorator.java b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcClientDecorator.java index de52229988d..519b8dba427 100644 --- a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcClientDecorator.java +++ b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/GrpcClientDecorator.java @@ -15,6 +15,7 @@ import datadog.trace.api.datastreams.DataStreamsTags; import datadog.trace.api.naming.SpanNaming; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.api.AgentTracer; import datadog.trace.bootstrap.instrumentation.api.InternalSpanTypes; import datadog.trace.bootstrap.instrumentation.api.Tags; import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString; @@ -90,7 +91,7 @@ protected String service() { public AgentSpan startCall(MethodDescriptor method) { if (IGNORED_METHODS.contains(method.getFullMethodName())) { - return null; + return AgentTracer.blackholeSpan(); } AgentSpan span = startSpan("grpc", OPERATION_NAME) From 537ab4d659d9a573e5d763b0ed9c19e3adf65c38 Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Wed, 11 Mar 2026 18:20:48 +0100 Subject: [PATCH 11/12] final fixes --- .../ApacheHttpAsyncClientInstrumentation.java | 3 +++ .../ApacheHttpAsyncClientInstrumentation.java | 1 + .../jetty_client91/JettyClientInstrumentation.java | 9 ++++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientInstrumentation.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientInstrumentation.java index 735662886c6..316cf60f6f5 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientInstrumentation.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientInstrumentation.java @@ -17,6 +17,7 @@ import datadog.trace.api.InstrumenterConfig; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -76,6 +77,7 @@ public void methodAdvice(MethodTransformer transformer) { } @AppliesOn(CONTEXT_TRACKING) + @SuppressFBWarnings("UC_USELESS_OBJECT") public static class ClientContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void methodEnter( @@ -87,6 +89,7 @@ public static void methodEnter( } } + @SuppressFBWarnings("UC_USELESS_OBJECT") public static class ClientAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static AgentSpan methodEnter( diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpAsyncClientInstrumentation.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpAsyncClientInstrumentation.java index c2dc0bb7e90..3bc8441f2f5 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpAsyncClientInstrumentation.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpAsyncClientInstrumentation.java @@ -92,6 +92,7 @@ public void methodAdvice(MethodTransformer transformer) { } @AppliesOn(CONTEXT_TRACKING) + @SuppressFBWarnings("UC_USELESS_OBJECT") public static class ClientContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void onEnter( diff --git a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-9.1/src/main/java/datadog/trace/instrumentation/jetty_client91/JettyClientInstrumentation.java b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-9.1/src/main/java/datadog/trace/instrumentation/jetty_client91/JettyClientInstrumentation.java index 808dd9f35b8..ccdfad18391 100644 --- a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-9.1/src/main/java/datadog/trace/instrumentation/jetty_client91/JettyClientInstrumentation.java +++ b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-9.1/src/main/java/datadog/trace/instrumentation/jetty_client91/JettyClientInstrumentation.java @@ -15,6 +15,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import com.google.auto.service.AutoService; +import datadog.context.Context; import datadog.trace.agent.tooling.ExcludeFilterProvider; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; @@ -111,7 +112,13 @@ public static void methodExit( public static class ContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void methodEnter(@Advice.Argument(0) final Request request) { - DECORATE.injectContext(getCurrentContext(), request, SETTER); + final AgentSpan span = + InstrumentationContext.get(Request.class, AgentSpan.class).get(request); + Context destination = getCurrentContext(); + if (span != null) { + destination = destination.with(span); + } + DECORATE.injectContext(destination, request, SETTER); } } } From 3037d71fb2e46c6e278221bf9878eaea7cf0ffc0 Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Thu, 12 Mar 2026 08:44:23 +0100 Subject: [PATCH 12/12] fix jetty client --- .../jetty_client10/SendContextPropagationAdvice.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java11/datadog/trace/instrumentation/jetty_client10/SendContextPropagationAdvice.java b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java11/datadog/trace/instrumentation/jetty_client10/SendContextPropagationAdvice.java index 7348b9da47d..8a0f4846f1e 100644 --- a/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java11/datadog/trace/instrumentation/jetty_client10/SendContextPropagationAdvice.java +++ b/dd-java-agent/instrumentation/jetty/jetty-client/jetty-client-10.0/src/main/java11/datadog/trace/instrumentation/jetty_client10/SendContextPropagationAdvice.java @@ -5,7 +5,10 @@ import static datadog.trace.instrumentation.jetty_client.HeadersInjectAdapter.SETTER; import static datadog.trace.instrumentation.jetty_client10.JettyClientDecorator.DECORATE; +import datadog.context.Context; import datadog.trace.agent.tooling.annotation.AppliesOn; +import datadog.trace.bootstrap.InstrumentationContext; +import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import net.bytebuddy.asm.Advice; import org.eclipse.jetty.client.api.Request; @@ -13,6 +16,11 @@ public class SendContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void methodEnter(@Advice.Argument(0) final Request request) { - DECORATE.injectContext(getCurrentContext(), request, SETTER); + final AgentSpan span = InstrumentationContext.get(Request.class, AgentSpan.class).get(request); + Context destination = getCurrentContext(); + if (span != null) { + destination = destination.with(span); + } + DECORATE.injectContext(destination, request, SETTER); } }