Skip to content

Commit f7a6771

Browse files
Implement code origin support for grpc server entry spans (#7942)
* Add code origin support to the grpc server integration --------- Co-authored-by: Andrea Marziali <[email protected]>
1 parent ad94ba0 commit f7a6771

File tree

6 files changed

+403
-0
lines changed

6 files changed

+403
-0
lines changed

dd-java-agent/agent-bootstrap/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ dependencies {
2121
api project(':internal-api')
2222
api project(':internal-api:internal-api-9')
2323
api project(':dd-java-agent:agent-logging')
24+
api project(':dd-java-agent:agent-debugger:debugger-bootstrap')
2425
api libs.slf4j
2526
// ^ Generally a bad idea for libraries, but we're shadowing.
2627

dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/agent/CapturingTestBase.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ public static LogProbe.Builder createProbeBuilder(
351351

352352
protected TestSnapshotListener installProbes(
353353
Configuration configuration, ProbeDefinition... probes) {
354+
354355
config = mock(Config.class);
355356
when(config.isDebuggerEnabled()).thenReturn(true);
356357
when(config.isDebuggerClassFileDumpEnabled()).thenReturn(true);

dd-java-agent/instrumentation/grpc-1.5/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ dependencies {
3939
testImplementation group: 'io.grpc', name: 'grpc-protobuf', version: grpcVersion
4040
testImplementation group: 'io.grpc', name: 'grpc-stub', version: grpcVersion
4141
testImplementation group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2'
42+
testImplementation project(':dd-java-agent:agent-debugger')
43+
testImplementation libs.bundles.mockito
4244

4345
latestDepTestImplementation sourceSets.test.output // include the protobuf generated classes
4446
latestDepTestCompileOnly group: 'io.grpc', name: 'grpc-core', version: '1.+'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package datadog.trace.instrumentation.grpc.server;
2+
3+
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.nameEndsWith;
4+
import static datadog.trace.bootstrap.debugger.spanorigin.CodeOriginInfo.entry;
5+
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
6+
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
7+
8+
import com.google.auto.service.AutoService;
9+
import datadog.trace.agent.tooling.Instrumenter.ForTypeHierarchy;
10+
import datadog.trace.agent.tooling.InstrumenterModule;
11+
import datadog.trace.api.Platform;
12+
import java.lang.reflect.Method;
13+
import net.bytebuddy.asm.Advice;
14+
import net.bytebuddy.description.type.TypeDescription;
15+
import net.bytebuddy.matcher.ElementMatcher;
16+
17+
@AutoService(InstrumenterModule.class)
18+
public class MethodHandlersInstrumentation extends InstrumenterModule.Tracing
19+
implements ForTypeHierarchy {
20+
private static final ElementMatcher<TypeDescription> METHOD_HANDLERS =
21+
nameEndsWith("$MethodHandlers");
22+
23+
public MethodHandlersInstrumentation() {
24+
super("grpc", "grpc-server", "grpc-server-code-origin");
25+
}
26+
27+
@Override
28+
public String hierarchyMarkerType() {
29+
return "io.grpc.MethodDescriptor";
30+
}
31+
32+
@Override
33+
public ElementMatcher<TypeDescription> hierarchyMatcher() {
34+
return METHOD_HANDLERS;
35+
}
36+
37+
@Override
38+
public boolean isEnabled() {
39+
return super.isEnabled() && !Platform.isGraalVM();
40+
}
41+
42+
@Override
43+
public void methodAdvice(MethodTransformer transformer) {
44+
transformer.applyAdvice(
45+
isConstructor().and(takesArguments(2)),
46+
MethodHandlersInstrumentation.class.getName() + "$BuildAdvice");
47+
}
48+
49+
public static class BuildAdvice {
50+
51+
@Advice.OnMethodEnter(suppress = Throwable.class)
52+
public static void onEnter(@Advice.Argument(0) Object serviceImpl) {
53+
try {
54+
Class<?> serviceClass = serviceImpl.getClass();
55+
Class<?> superclass = serviceClass.getSuperclass();
56+
if (superclass != null) {
57+
for (Method method : superclass.getDeclaredMethods()) {
58+
try {
59+
entry(serviceClass.getDeclaredMethod(method.getName(), method.getParameterTypes()));
60+
} catch (Throwable e) {
61+
// service method not overridden on the impl. skipping instrumentation.
62+
}
63+
}
64+
}
65+
} catch (Throwable e) {
66+
// this should be logged somehow
67+
}
68+
}
69+
}
70+
}

0 commit comments

Comments
 (0)