Switch gRPC instrumentation to instrument public ServerBuilder class. (#1839)

* Switch gRPC instrumentation to instrument public ServerBuilder class.

* A bit more readability (hopefully)

* hack

* Remove library dedupe for now since we need a better story.
This commit is contained in:
Anuraag Agrawal 2020-12-07 16:24:10 +09:00 committed by GitHub
parent 4cbfb361e1
commit 7199595730
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 26 deletions

View File

@ -20,7 +20,7 @@ muzzle {
pass { pass {
group = "io.grpc" group = "io.grpc"
module = "grpc-core" module = "grpc-core"
versions = "[1.5.0, 1.33.0)" // see https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/1453 versions = "[1.5.0,)"
} }
} }
@ -35,11 +35,5 @@ dependencies {
testLibrary group: 'io.grpc', name: 'grpc-protobuf', version: grpcVersion testLibrary group: 'io.grpc', name: 'grpc-protobuf', version: grpcVersion
testLibrary group: 'io.grpc', name: 'grpc-stub', version: grpcVersion testLibrary group: 'io.grpc', name: 'grpc-stub', version: grpcVersion
// see https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/1453
latestDepTestLibrary group: 'io.grpc', name: 'grpc-core', version: '1.32.+'
latestDepTestLibrary group: 'io.grpc', name: 'grpc-netty', version: '1.32.+'
latestDepTestLibrary group: 'io.grpc', name: 'grpc-protobuf', version: '1.32.+'
latestDepTestLibrary group: 'io.grpc', name: 'grpc-stub', version: '1.32.+'
testImplementation project(':instrumentation:grpc-1.5:testing') testImplementation project(':instrumentation:grpc-1.5:testing')
} }

View File

@ -5,14 +5,18 @@
package io.opentelemetry.javaagent.instrumentation.grpc.v1_5; package io.opentelemetry.javaagent.instrumentation.grpc.v1_5;
import static java.util.Collections.singletonMap; import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.safeHasSuperType;
import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import io.grpc.ServerInterceptor; import io.grpc.ServerBuilder;
import io.opentelemetry.instrumentation.grpc.v1_5.server.TracingServerInterceptor; import io.opentelemetry.instrumentation.grpc.v1_5.server.TracingServerInterceptor;
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List; import java.util.Collections;
import java.util.Map; import java.util.Map;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.method.MethodDescription;
@ -21,33 +25,36 @@ import net.bytebuddy.matcher.ElementMatcher;
public class GrpcServerBuilderInstrumentation implements TypeInstrumentation { public class GrpcServerBuilderInstrumentation implements TypeInstrumentation {
@Override
public ElementMatcher<ClassLoader> classLoaderOptimization() {
return hasClassesNamed("io.grpc.ServerBuilder");
}
@Override @Override
public ElementMatcher<TypeDescription> typeMatcher() { public ElementMatcher<TypeDescription> typeMatcher() {
return named("io.grpc.internal.AbstractServerImplBuilder"); return safeHasSuperType(named("io.grpc.ServerBuilder"));
} }
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return Collections.singletonMap(
isMethod().and(named("build")), isMethod().and(isPublic()).and(named("build")).and(takesArguments(0)),
GrpcServerBuilderInstrumentation.class.getName() + "$AddInterceptorAdvice"); GrpcServerBuilderInstrumentation.class.getName() + "$BuildAdvice");
} }
public static class AddInterceptorAdvice { public static class BuildAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class) @Advice.OnMethodEnter(suppress = Throwable.class)
public static void addInterceptor( public static void onEnter(@Advice.This ServerBuilder<?> serverBuilder) {
@Advice.FieldValue("interceptors") List<ServerInterceptor> interceptors) { int callDepth = CallDepthThreadLocalMap.incrementCallDepth(ServerBuilder.class);
boolean shouldRegister = true; if (callDepth == 0) {
for (ServerInterceptor interceptor : interceptors) { serverBuilder.intercept(TracingServerInterceptor.newInterceptor());
if (interceptor instanceof TracingServerInterceptor) {
shouldRegister = false;
break;
}
}
if (shouldRegister) {
interceptors.add(TracingServerInterceptor.newInterceptor());
} }
} }
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void onExit(@Advice.This ServerBuilder<?> serverBuilder) {
CallDepthThreadLocalMap.decrementCallDepth(ServerBuilder.class);
}
} }
} }