Fix instrumentation for graphql-java-22.0 (#11142)
This commit is contained in:
parent
4325eb25a0
commit
1da8f5e9bd
|
@ -22,3 +22,9 @@ dependencies {
|
||||||
|
|
||||||
testImplementation(project(":instrumentation:graphql-java:graphql-java-common:testing"))
|
testImplementation(project(":instrumentation:graphql-java:graphql-java-common:testing"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (findProperty("testLatestDeps") as Boolean) {
|
||||||
|
otelJava {
|
||||||
|
minJavaVersionSupported.set(JavaVersion.VERSION_11)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,15 +7,25 @@ package io.opentelemetry.javaagent.instrumentation.graphql.v20_0;
|
||||||
|
|
||||||
import static io.opentelemetry.javaagent.instrumentation.graphql.v20_0.GraphqlSingletons.addInstrumentation;
|
import static io.opentelemetry.javaagent.instrumentation.graphql.v20_0.GraphqlSingletons.addInstrumentation;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.namedOneOf;
|
import static net.bytebuddy.matcher.ElementMatchers.none;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
|
||||||
|
|
||||||
|
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||||
import graphql.execution.instrumentation.Instrumentation;
|
import graphql.execution.instrumentation.Instrumentation;
|
||||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
|
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
|
||||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
|
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
|
import net.bytebuddy.asm.AsmVisitorWrapper;
|
||||||
|
import net.bytebuddy.description.field.FieldDescription;
|
||||||
|
import net.bytebuddy.description.field.FieldList;
|
||||||
|
import net.bytebuddy.description.method.MethodList;
|
||||||
import net.bytebuddy.description.type.TypeDescription;
|
import net.bytebuddy.description.type.TypeDescription;
|
||||||
|
import net.bytebuddy.implementation.Implementation;
|
||||||
import net.bytebuddy.matcher.ElementMatcher;
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
|
import net.bytebuddy.pool.TypePool;
|
||||||
|
import org.objectweb.asm.ClassVisitor;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
class GraphqlInstrumentation implements TypeInstrumentation {
|
class GraphqlInstrumentation implements TypeInstrumentation {
|
||||||
|
|
||||||
|
@ -27,15 +37,78 @@ class GraphqlInstrumentation implements TypeInstrumentation {
|
||||||
@Override
|
@Override
|
||||||
public void transform(TypeTransformer transformer) {
|
public void transform(TypeTransformer transformer) {
|
||||||
transformer.applyAdviceToMethod(
|
transformer.applyAdviceToMethod(
|
||||||
namedOneOf("checkInstrumentationDefaultState", "checkInstrumentation")
|
none(), this.getClass().getName() + "$AddInstrumentationAdvice");
|
||||||
.and(returns(named("graphql.execution.instrumentation.Instrumentation"))),
|
|
||||||
this.getClass().getName() + "$AddInstrumentationAdvice");
|
transformer.applyTransformer(
|
||||||
|
(builder, typeDescription, classLoader, javaModule, protectionDomain) ->
|
||||||
|
builder.visit(
|
||||||
|
new AsmVisitorWrapper() {
|
||||||
|
@Override
|
||||||
|
public int mergeWriter(int flags) {
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@CanIgnoreReturnValue
|
||||||
|
public int mergeReader(int flags) {
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassVisitor wrap(
|
||||||
|
TypeDescription instrumentedType,
|
||||||
|
ClassVisitor classVisitor,
|
||||||
|
Implementation.Context implementationContext,
|
||||||
|
TypePool typePool,
|
||||||
|
FieldList<FieldDescription.InDefinedShape> fields,
|
||||||
|
MethodList<?> methods,
|
||||||
|
int writerFlags,
|
||||||
|
int readerFlags) {
|
||||||
|
return new ClassVisitor(Opcodes.ASM9, classVisitor) {
|
||||||
|
@Override
|
||||||
|
public MethodVisitor visitMethod(
|
||||||
|
int access,
|
||||||
|
String name,
|
||||||
|
String descriptor,
|
||||||
|
String signature,
|
||||||
|
String[] exceptions) {
|
||||||
|
MethodVisitor mv =
|
||||||
|
super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||||
|
if ("<init>".equals(name)
|
||||||
|
&& "(Lgraphql/GraphQL$Builder;)V".equals(descriptor)) {
|
||||||
|
return new MethodVisitor(api, mv) {
|
||||||
|
@Override
|
||||||
|
public void visitFieldInsn(
|
||||||
|
int opcode, String owner, String name, String descriptor) {
|
||||||
|
// Call GraphqlSingletons.addInstrumentation on the value before it is
|
||||||
|
// written to the instrumentation field
|
||||||
|
if (opcode == Opcodes.PUTFIELD
|
||||||
|
&& "instrumentation".equals(name)
|
||||||
|
&& "Lgraphql/execution/instrumentation/Instrumentation;"
|
||||||
|
.equals(descriptor)) {
|
||||||
|
mv.visitMethodInsn(
|
||||||
|
Opcodes.INVOKESTATIC,
|
||||||
|
Type.getInternalName(GraphqlSingletons.class),
|
||||||
|
"addInstrumentation",
|
||||||
|
"(Lgraphql/execution/instrumentation/Instrumentation;)Lgraphql/execution/instrumentation/Instrumentation;",
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
super.visitFieldInsn(opcode, owner, name, descriptor);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return mv;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static class AddInstrumentationAdvice {
|
public static class AddInstrumentationAdvice {
|
||||||
@Advice.OnMethodExit(suppress = Throwable.class)
|
@Advice.OnMethodExit(suppress = Throwable.class)
|
||||||
public static void onExit(@Advice.Return(readOnly = false) Instrumentation instrumentation) {
|
public static void onExit(@Advice.Return(readOnly = false) Instrumentation instrumentation) {
|
||||||
|
// this advice is here only to get GraphqlSingletons injected and checked by muzzle
|
||||||
instrumentation = addInstrumentation(instrumentation);
|
instrumentation = addInstrumentation(instrumentation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,3 +8,9 @@ dependencies {
|
||||||
|
|
||||||
testImplementation(project(":instrumentation:graphql-java:graphql-java-common:testing"))
|
testImplementation(project(":instrumentation:graphql-java:graphql-java-common:testing"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (findProperty("testLatestDeps") as Boolean) {
|
||||||
|
otelJava {
|
||||||
|
minJavaVersionSupported.set(JavaVersion.VERSION_11)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue