diff --git a/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/ClientCallImplInstrumentation.java b/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/ClientCallImplInstrumentation.java index 38fef363112..ea52721257d 100644 --- a/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/ClientCallImplInstrumentation.java +++ b/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/ClientCallImplInstrumentation.java @@ -5,7 +5,6 @@ import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.propagate; import static datadog.trace.instrumentation.grpc.client.GrpcClientDecorator.CLIENT_PATHWAY_EDGE_TAGS; import static datadog.trace.instrumentation.grpc.client.GrpcClientDecorator.DECORATE; -import static datadog.trace.instrumentation.grpc.client.GrpcClientDecorator.OPERATION_NAME; import static datadog.trace.instrumentation.grpc.client.GrpcInjectAdapter.SETTER; import static net.bytebuddy.matcher.ElementMatchers.isConstructor; import static net.bytebuddy.matcher.ElementMatchers.isMethod; @@ -16,9 +15,9 @@ 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.AgentTracer; import io.grpc.ClientCall; import io.grpc.Metadata; +import io.grpc.MethodDescriptor; import io.grpc.Status; import io.grpc.StatusException; import java.util.Collections; @@ -48,6 +47,14 @@ public void adviceTransformations(AdviceTransformation transformation) { transformation.applyAdvice(isConstructor(), getClass().getName() + "$Capture"); transformation.applyAdvice(named("start").and(isMethod()), getClass().getName() + "$Start"); transformation.applyAdvice(named("cancel").and(isMethod()), getClass().getName() + "$Cancel"); + transformation.applyAdvice( + named("request") + .and(isMethod()) + .and(takesArguments(int.class)) + .or(isMethod().and(named("halfClose").and(takesArguments(0)))), + getClass().getName() + "$ActivateSpan"); + transformation.applyAdvice( + named("sendMessage").and(isMethod()), getClass().getName() + "$SendMessage"); transformation.applyAdvice( named("closeObserver").and(takesArguments(3)), getClass().getName() + "$CloseObserver"); } @@ -63,10 +70,11 @@ public String[] helperClassNames() { public static final class Capture { @Advice.OnMethodExit - public static void capture(@Advice.This io.grpc.ClientCall call) { - AgentSpan span = AgentTracer.activeSpan(); - // embed the span in the call only if a grpc.client span is active - if (null != span && OPERATION_NAME.equals(span.getOperationName())) { + public static void capture( + @Advice.This io.grpc.ClientCall call, + @Advice.Argument(0) MethodDescriptor method) { + AgentSpan span = DECORATE.startCall(method); + if (null != span) { InstrumentationContext.get(ClientCall.class, AgentSpan.class).put(call, span); } } @@ -105,6 +113,43 @@ public static void after( } } + public static final class ActivateSpan { + @Advice.OnMethodEnter + public static AgentScope before(@Advice.This ClientCall call) { + AgentSpan span = InstrumentationContext.get(ClientCall.class, AgentSpan.class).get(call); + if (null != span) { + return activateSpan(span); + } + return null; + } + + @Advice.OnMethodExit(onThrowable = Throwable.class) + public static void after(@Advice.Enter AgentScope scope) { + if (null != scope) { + scope.close(); + } + } + } + + public static final class SendMessage { + @Advice.OnMethodEnter + public static AgentScope before(@Advice.This ClientCall call) { + // could create a message span here for the request + AgentSpan span = InstrumentationContext.get(ClientCall.class, AgentSpan.class).get(call); + if (span != null) { + return activateSpan(span); + } + return null; + } + + @Advice.OnMethodExit(onThrowable = Throwable.class) + public static void after(@Advice.Enter AgentScope scope) { + if (null != scope) { + scope.close(); + } + } + } + public static final class Cancel { @Advice.OnMethodEnter public static void before( diff --git a/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/ManagedChannelImplInstrumentation.java b/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/ManagedChannelImplInstrumentation.java deleted file mode 100644 index 1a19813c114..00000000000 --- a/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/ManagedChannelImplInstrumentation.java +++ /dev/null @@ -1,86 +0,0 @@ -package datadog.trace.instrumentation.grpc.client; - -import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; -import static datadog.trace.instrumentation.grpc.client.GrpcClientDecorator.DECORATE; -import static net.bytebuddy.matcher.ElementMatchers.isMethod; -import static net.bytebuddy.matcher.ElementMatchers.takesArgument; - -import com.google.auto.service.AutoService; -import datadog.trace.agent.tooling.Instrumenter; -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.AgentTracer; -import io.grpc.CallOptions; -import io.grpc.ClientCall; -import io.grpc.MethodDescriptor; -import java.util.Collections; -import java.util.Map; -import net.bytebuddy.asm.Advice; - -@AutoService(Instrumenter.class) -public class ManagedChannelImplInstrumentation extends Instrumenter.Tracing - implements Instrumenter.ForSingleType { - public ManagedChannelImplInstrumentation() { - super("grpc", "grpc-client"); - } - - @Override - public String instrumentedType() { - return "io.grpc.internal.ManagedChannelImpl"; - } - - @Override - public Map contextStore() { - return Collections.singletonMap("io.grpc.ClientCall", AgentSpan.class.getName()); - } - - @Override - public String[] helperClassNames() { - return new String[] { - packageName + ".GrpcClientDecorator", - packageName + ".GrpcClientDecorator$1", - packageName + ".GrpcInjectAdapter" - }; - } - - @Override - public void adviceTransformations(AdviceTransformation transformation) { - transformation.applyAdvice( - isMethod() - .and( - named("newCall") - .and(takesArgument(0, named("io.grpc.MethodDescriptor"))) - .and(takesArgument(1, named("io.grpc.CallOptions")))), - getClass().getName() + "$NewCall"); - } - - public static final class NewCall { - @Advice.OnMethodEnter - public static AgentScope enter( - @Advice.Argument(0) MethodDescriptor method, - @Advice.Argument(1) CallOptions callOptions, - @Advice.Local("$$ddSpan") AgentSpan span) { - // TODO could take some interesting attributes from the CallOptions here - // e.g. the deadline or compressor name - span = DECORATE.startCall(method); - if (span != null) { - return AgentTracer.activateSpan(span); - } - return null; - } - - @Advice.OnMethodExit - public static void exit( - @Advice.Enter AgentScope scope, - @Advice.Return ClientCall call, - @Advice.Local("$$ddSpan") AgentSpan span) { - if (span != null) { - InstrumentationContext.get(ClientCall.class, AgentSpan.class).put(call, span); - } - if (scope != null) { - scope.close(); - } - } - } -} diff --git a/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/MessagesAvailableInstrumentation.java b/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/MessagesAvailableInstrumentation.java index 2a90e34205a..1c78aefeaa1 100644 --- a/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/MessagesAvailableInstrumentation.java +++ b/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/MessagesAvailableInstrumentation.java @@ -7,11 +7,14 @@ import static datadog.trace.instrumentation.grpc.client.GrpcClientDecorator.DECORATE; import static datadog.trace.instrumentation.grpc.client.GrpcClientDecorator.GRPC_MESSAGE; import static datadog.trace.instrumentation.grpc.client.GrpcClientDecorator.OPERATION_NAME; +import static net.bytebuddy.matcher.ElementMatchers.isConstructor; import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; +import datadog.trace.bootstrap.InstrumentationContext; import datadog.trace.bootstrap.instrumentation.api.AgentScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; +import datadog.trace.bootstrap.instrumentation.java.concurrent.AdviceUtils; import datadog.trace.bootstrap.instrumentation.java.concurrent.State; import java.util.Collections; import java.util.Map; @@ -49,9 +52,17 @@ public Map contextStore() { @Override public void adviceTransformations(AdviceTransformation transformation) { + transformation.applyAdvice(isConstructor(), getClass().getName() + "$Capture"); transformation.applyAdvice(named("runInContext"), getClass().getName() + "$ReceiveMessages"); } + public static final class Capture { + @Advice.OnMethodExit + public static void capture(@Advice.This Runnable task) { + AdviceUtils.capture(InstrumentationContext.get(Runnable.class, State.class), task, true); + } + } + public static final class ReceiveMessages { @Advice.OnMethodEnter public static AgentScope before() { diff --git a/dd-java-agent/instrumentation/java-concurrent/src/main/java/datadog/trace/instrumentation/java/concurrent/AbstractExecutorInstrumentation.java b/dd-java-agent/instrumentation/java-concurrent/src/main/java/datadog/trace/instrumentation/java/concurrent/AbstractExecutorInstrumentation.java index 6fecd2cb1c6..79d99beb4c7 100644 --- a/dd-java-agent/instrumentation/java-concurrent/src/main/java/datadog/trace/instrumentation/java/concurrent/AbstractExecutorInstrumentation.java +++ b/dd-java-agent/instrumentation/java-concurrent/src/main/java/datadog/trace/instrumentation/java/concurrent/AbstractExecutorInstrumentation.java @@ -43,9 +43,7 @@ public String[] knownMatchingTypes() { "kotlinx.coroutines.scheduling.CoroutineScheduler", "play.api.libs.streams.Execution$trampoline$", "scala.concurrent.Future$InternalCallbackExecutor$", - "scala.concurrent.impl.ExecutionContextImpl", - "io.grpc.SynchronizationContext", - "io.grpc.internal.SerializingExecutor" + "scala.concurrent.impl.ExecutionContextImpl" }; } diff --git a/dd-java-agent/instrumentation/java-concurrent/src/main/java/datadog/trace/instrumentation/java/concurrent/AsyncPropagatingDisableInstrumentation.java b/dd-java-agent/instrumentation/java-concurrent/src/main/java/datadog/trace/instrumentation/java/concurrent/AsyncPropagatingDisableInstrumentation.java index 2e60d1d8440..1c1f96cb5f6 100644 --- a/dd-java-agent/instrumentation/java-concurrent/src/main/java/datadog/trace/instrumentation/java/concurrent/AsyncPropagatingDisableInstrumentation.java +++ b/dd-java-agent/instrumentation/java-concurrent/src/main/java/datadog/trace/instrumentation/java/concurrent/AsyncPropagatingDisableInstrumentation.java @@ -75,8 +75,7 @@ public String[] knownMatchingTypes() { "net.sf.ehcache.store.disk.DiskStorageFactory", "org.springframework.jms.listener.DefaultMessageListenerContainer", "org.apache.activemq.broker.TransactionBroker", - "com.mongodb.internal.connection.DefaultConnectionPool$AsyncWorkManager", - "io.grpc.internal.SerializingExecutor" + "com.mongodb.internal.connection.DefaultConnectionPool$AsyncWorkManager" }; } @@ -171,8 +170,6 @@ public void adviceTransformations(AdviceTransformation transformation) { advice); transformation.applyAdvice( isTypeInitializer().and(isDeclaredBy(REACTOR_DISABLED_TYPE_INITIALIZERS)), advice); - transformation.applyAdvice( - named("schedule").and(isDeclaredBy(named("io.grpc.internal.SerializingExecutor"))), advice); } public static class DisableAsyncAdvice {