Skip to content

Commit

Permalink
Implement code origin support for grpc server entry spans (#7942)
Browse files Browse the repository at this point in the history
* Add code origin support to the grpc server integration

---------

Co-authored-by: Andrea Marziali <[email protected]>
  • Loading branch information
evanchooly and amarziali authored Nov 27, 2024
1 parent ad94ba0 commit f7a6771
Show file tree
Hide file tree
Showing 6 changed files with 403 additions and 0 deletions.
1 change: 1 addition & 0 deletions dd-java-agent/agent-bootstrap/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ dependencies {
api project(':internal-api')
api project(':internal-api:internal-api-9')
api project(':dd-java-agent:agent-logging')
api project(':dd-java-agent:agent-debugger:debugger-bootstrap')
api libs.slf4j
// ^ Generally a bad idea for libraries, but we're shadowing.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ public static LogProbe.Builder createProbeBuilder(

protected TestSnapshotListener installProbes(
Configuration configuration, ProbeDefinition... probes) {

config = mock(Config.class);
when(config.isDebuggerEnabled()).thenReturn(true);
when(config.isDebuggerClassFileDumpEnabled()).thenReturn(true);
Expand Down
2 changes: 2 additions & 0 deletions dd-java-agent/instrumentation/grpc-1.5/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ dependencies {
testImplementation group: 'io.grpc', name: 'grpc-protobuf', version: grpcVersion
testImplementation group: 'io.grpc', name: 'grpc-stub', version: grpcVersion
testImplementation group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2'
testImplementation project(':dd-java-agent:agent-debugger')
testImplementation libs.bundles.mockito

latestDepTestImplementation sourceSets.test.output // include the protobuf generated classes
latestDepTestCompileOnly group: 'io.grpc', name: 'grpc-core', version: '1.+'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package datadog.trace.instrumentation.grpc.server;

import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.nameEndsWith;
import static datadog.trace.bootstrap.debugger.spanorigin.CodeOriginInfo.entry;
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;

import com.google.auto.service.AutoService;
import datadog.trace.agent.tooling.Instrumenter.ForTypeHierarchy;
import datadog.trace.agent.tooling.InstrumenterModule;
import datadog.trace.api.Platform;
import java.lang.reflect.Method;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;

@AutoService(InstrumenterModule.class)
public class MethodHandlersInstrumentation extends InstrumenterModule.Tracing
implements ForTypeHierarchy {
private static final ElementMatcher<TypeDescription> METHOD_HANDLERS =
nameEndsWith("$MethodHandlers");

public MethodHandlersInstrumentation() {
super("grpc", "grpc-server", "grpc-server-code-origin");
}

@Override
public String hierarchyMarkerType() {
return "io.grpc.MethodDescriptor";
}

@Override
public ElementMatcher<TypeDescription> hierarchyMatcher() {
return METHOD_HANDLERS;
}

@Override
public boolean isEnabled() {
return super.isEnabled() && !Platform.isGraalVM();
}

@Override
public void methodAdvice(MethodTransformer transformer) {
transformer.applyAdvice(
isConstructor().and(takesArguments(2)),
MethodHandlersInstrumentation.class.getName() + "$BuildAdvice");
}

public static class BuildAdvice {

@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(@Advice.Argument(0) Object serviceImpl) {
try {
Class<?> serviceClass = serviceImpl.getClass();
Class<?> superclass = serviceClass.getSuperclass();
if (superclass != null) {
for (Method method : superclass.getDeclaredMethods()) {
try {
entry(serviceClass.getDeclaredMethod(method.getName(), method.getParameterTypes()));
} catch (Throwable e) {
// service method not overridden on the impl. skipping instrumentation.
}
}
}
} catch (Throwable e) {
// this should be logged somehow
}
}
}
}
Loading

0 comments on commit f7a6771

Please sign in to comment.