From 294b6177e55396194ee7d7713e2364263dd823f9 Mon Sep 17 00:00:00 2001 From: Stuart McCulloch Date: Tue, 9 Jul 2024 10:44:50 +0100 Subject: [PATCH] This feature was migrated to the modules under dd-java-agent/agent-otel (#7292) --- buildSrc/build.gradle.kts | 8 - .../groovy/otel/AbstractClassVisitor.java | 31 -- .../otel/InstrumentationModuleConverter.java | 86 ---- .../main/groovy/otel/OtelApiVerifier.groovy | 50 -- .../groovy/otel/OtelConverterPlugin.groovy | 137 ------ .../otel/TypeInstrumentationConverter.java | 79 ---- .../groovy/otel/VirtualFieldConverter.java | 145 ------ .../groovy/otel/muzzle/MuzzleConverter.java | 436 ------------------ .../main/groovy/otel/muzzle/MuzzleFlag.java | 68 --- .../groovy/otel/muzzle/MuzzleGenerator.java | 180 -------- .../groovy/otel/muzzle/MuzzleReference.java | 61 --- .../otel/muzzle/MuzzleConverterTest.groovy | 117 ----- .../groovy/otel/muzzle/MuzzleFlagTest.groovy | 23 - .../build.gradle | 18 - .../opentelemetry/automatic/HasAdvice.java | 62 --- .../OtelAutomaticInstrumentation.java | 19 - .../instrumentation/TypeInstrumentation.java | 19 - .../instrumentation/TypeTransformer.java | 15 - settings.gradle | 2 - 19 files changed, 1556 deletions(-) delete mode 100644 buildSrc/src/main/groovy/otel/AbstractClassVisitor.java delete mode 100644 buildSrc/src/main/groovy/otel/InstrumentationModuleConverter.java delete mode 100644 buildSrc/src/main/groovy/otel/OtelApiVerifier.groovy delete mode 100644 buildSrc/src/main/groovy/otel/OtelConverterPlugin.groovy delete mode 100644 buildSrc/src/main/groovy/otel/TypeInstrumentationConverter.java delete mode 100644 buildSrc/src/main/groovy/otel/VirtualFieldConverter.java delete mode 100644 buildSrc/src/main/groovy/otel/muzzle/MuzzleConverter.java delete mode 100644 buildSrc/src/main/groovy/otel/muzzle/MuzzleFlag.java delete mode 100644 buildSrc/src/main/groovy/otel/muzzle/MuzzleGenerator.java delete mode 100644 buildSrc/src/main/groovy/otel/muzzle/MuzzleReference.java delete mode 100644 buildSrc/src/test/groovy/otel/muzzle/MuzzleConverterTest.groovy delete mode 100644 buildSrc/src/test/groovy/otel/muzzle/MuzzleFlagTest.groovy delete mode 100644 dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/build.gradle delete mode 100644 dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/src/main/java/datadog/trace/instrumentation/opentelemetry/automatic/HasAdvice.java delete mode 100644 dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/src/main/java/datadog/trace/instrumentation/opentelemetry/automatic/OtelAutomaticInstrumentation.java delete mode 100644 dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/TypeInstrumentation.java delete mode 100644 dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/TypeTransformer.java diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 95591df0b4e..6760b42cc21 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -19,10 +19,6 @@ gradlePlugin { id = "call-site-instrumentation" implementationClass = "datadog.gradle.plugin.CallSiteInstrumentationPlugin" } - create("otel-converter-plugin") { - id = "otel-converter" - implementationClass = "otel.OtelConverterPlugin" - } } } @@ -48,10 +44,6 @@ dependencies { testImplementation("org.spockframework", "spock-core", "2.2-groovy-3.0") testImplementation("org.codehaus.groovy", "groovy-all", "3.0.17") - testImplementation("io.opentelemetry.javaagent", "opentelemetry-muzzle", "1.32.0-alpha") - // OpenTelemetry javaagent modules for OTel Muzzle converter - testImplementation("io.opentelemetry.javaagent", "opentelemetry-javaagent-extension-api", "1.32.0-alpha") - testImplementation("io.opentelemetry.javaagent.instrumentation", "opentelemetry-javaagent-grpc-1.6", "1.32.0-alpha") } tasks.compileKotlin { diff --git a/buildSrc/src/main/groovy/otel/AbstractClassVisitor.java b/buildSrc/src/main/groovy/otel/AbstractClassVisitor.java deleted file mode 100644 index 734c2eee590..00000000000 --- a/buildSrc/src/main/groovy/otel/AbstractClassVisitor.java +++ /dev/null @@ -1,31 +0,0 @@ -package otel; - -import static org.objectweb.asm.Opcodes.ASM9; - -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.MethodNode; - -/** - * Base class visitor to convert OpenTelemetry class into their Datadog equivalence using Tree API. - */ -public class AbstractClassVisitor extends ClassVisitor { - protected final ClassVisitor next; - protected final String className; - - public AbstractClassVisitor(ClassVisitor classVisitor, String className) { - super(ASM9, new ClassNode()); - this.next = classVisitor; - this.className = className; - } - - protected MethodNode findMethodNode(String methodName, String methodDesc) { - ClassNode classNode = (ClassNode) this.cv; - return classNode.methods.stream() - .filter(node -> methodName.equals(node.name) && methodDesc.equals(node.desc)) - .findAny() - .orElseThrow(() -> new IllegalStateException( - "Unable to find method " + methodName + " from " + this.className - )); - } -} diff --git a/buildSrc/src/main/groovy/otel/InstrumentationModuleConverter.java b/buildSrc/src/main/groovy/otel/InstrumentationModuleConverter.java deleted file mode 100644 index fba540f2f80..00000000000 --- a/buildSrc/src/main/groovy/otel/InstrumentationModuleConverter.java +++ /dev/null @@ -1,86 +0,0 @@ -package otel; - -import static org.objectweb.asm.Opcodes.ANEWARRAY; -import static org.objectweb.asm.Opcodes.INVOKESPECIAL; -import static org.objectweb.asm.tree.AbstractInsnNode.METHOD_INSN; -import static org.objectweb.asm.tree.AbstractInsnNode.TYPE_INSN; -import static otel.TypeInstrumentationConverter.TYPE_INSTRUMENTATION_CLASS_NAME; - -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.tree.AbstractInsnNode; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.InsnList; -import org.objectweb.asm.tree.MethodInsnNode; -import org.objectweb.asm.tree.MethodNode; -import org.objectweb.asm.tree.TypeInsnNode; - -/** - * This class visitor converts OpenTelemetry InstrumentationModule into Datadog InstrumenterModule (Tracing). - */ -public class InstrumentationModuleConverter extends AbstractClassVisitor { - private static final String INSTRUMENTATION_MODULE_CLASS_NAME = "io/opentelemetry/javaagent/extension/instrumentation/InstrumentationModule"; - private static final String INSTRUMENTATION_MODULE_CONSTRUCTOR_DESC = "(Ljava/lang/String;[Ljava/lang/String;)V"; - private static final String OTEL_AUTOMATIC_INSTRUMENTATION_CLASS_NAME = "datadog/trace/instrumentation/opentelemetry/automatic/OtelAutomaticInstrumentation"; - private static final String INSTRUMENTER_CLASS_NAME = "datadog/trace/agent/tooling/Instrumenter"; - private static final String CLASS_CONSTRUCTOR_DESC = "()V"; - private static final String TYPE_INSTRUMENTATIONS_METHOD_NAME = "typeInstrumentations"; - private static final String TYPE_INSTRUMENTATIONS_DESC = "()Ljava/util/List;"; - - public InstrumentationModuleConverter(ClassVisitor classVisitor, String className) { - super(classVisitor, className); - } - - @Override - public void visitEnd() { - if (extendsInstrumentationModule()) { - convertParentClass(); - convertTypeInstrumentations(); - } - if (this.next != null) { - ClassNode cn = (ClassNode) this.cv; - cn.accept(this.next); - } - } - - private boolean extendsInstrumentationModule() { - ClassNode classNode = (ClassNode) this.cv; - return INSTRUMENTATION_MODULE_CLASS_NAME.equals(classNode.superName); - } - - private void convertParentClass() { - ClassNode classNode = (ClassNode) this.cv; - // Update parent class - classNode.superName = OTEL_AUTOMATIC_INSTRUMENTATION_CLASS_NAME; - // Rewrite constructor to call the Datadog parent constructor - MethodNode constructorMethodNode = findMethodNode("", CLASS_CONSTRUCTOR_DESC); - InsnList instructions = new InsnList(); - for (AbstractInsnNode instruction : constructorMethodNode.instructions) { - if (instruction.getType() == METHOD_INSN) { - MethodInsnNode methodInsnNode = (MethodInsnNode) instruction; - if (methodInsnNode.getOpcode() == INVOKESPECIAL - && INSTRUMENTATION_MODULE_CLASS_NAME.equals(methodInsnNode.owner) - && INSTRUMENTATION_MODULE_CONSTRUCTOR_DESC.equals(methodInsnNode.desc)) { - methodInsnNode.owner = OTEL_AUTOMATIC_INSTRUMENTATION_CLASS_NAME; - } - } - instructions.add(instruction); - } - constructorMethodNode.instructions = instructions; - } - - private void convertTypeInstrumentations() { - // Rewrite typeInstrumentations() to create the Datadog type of array - MethodNode methodNode = findMethodNode(TYPE_INSTRUMENTATIONS_METHOD_NAME, TYPE_INSTRUMENTATIONS_DESC); - InsnList instructions = new InsnList(); - for (AbstractInsnNode instruction : methodNode.instructions) { - if (instruction.getType() == TYPE_INSN) { - TypeInsnNode typeInsnNode = (TypeInsnNode) instruction; - if (typeInsnNode.getOpcode() == ANEWARRAY && TYPE_INSTRUMENTATION_CLASS_NAME.equals(typeInsnNode.desc)) { - typeInsnNode.desc = INSTRUMENTER_CLASS_NAME; - } - } - instructions.add(instruction); - } - methodNode.instructions = instructions; - } -} diff --git a/buildSrc/src/main/groovy/otel/OtelApiVerifier.groovy b/buildSrc/src/main/groovy/otel/OtelApiVerifier.groovy deleted file mode 100644 index d6c5408cb48..00000000000 --- a/buildSrc/src/main/groovy/otel/OtelApiVerifier.groovy +++ /dev/null @@ -1,50 +0,0 @@ -package otel - -import org.objectweb.asm.ClassVisitor -import org.objectweb.asm.FieldVisitor -import org.objectweb.asm.MethodVisitor -import org.objectweb.asm.Type -import org.slf4j.LoggerFactory - -import static org.objectweb.asm.Opcodes.ASM9 - -/** This visitor checks no dependency on OTel agent left .*/ -class OtelApiVerifier extends ClassVisitor { - private static final LOGGER = LoggerFactory.getLogger(OtelApiVerifier.class) - /** The visited class name. */ - private final String className - - protected OtelApiVerifier(ClassVisitor classVisitor, String className) { - super(ASM9, classVisitor) - this.className = className - } - - // TODO: Only a POC. Need to cover more cases - - @Override - FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { - checkType(Type.getType(descriptor), name) - return super.visitField(access, name, descriptor, signature, value) - } - - @Override - MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - Type.getArgumentTypes(descriptor).each { - checkType(it, "parameter of $name") - } - checkType(Type.getReturnType(descriptor), "return of $name") - return super.visitMethod(access, name, descriptor, signature, exceptions) - } - - private void checkType(Type type, String name) { - String typeClassName = type.getClassName() - if (!isValidClass(typeClassName)) { - LOGGER.warn("Invalid OpenTelemetry type found: found $name of type $typeClassName in class $className") -// throw new IllegalStateException("Invalid OpenTelemetry type found: found $name of type $typeClassName in class $className") - } - } - - private static boolean isValidClass(String className) { - return !className.startsWith("io.opentelemetry.javaagent.") - } -} diff --git a/buildSrc/src/main/groovy/otel/OtelConverterPlugin.groovy b/buildSrc/src/main/groovy/otel/OtelConverterPlugin.groovy deleted file mode 100644 index 1e12d6d7456..00000000000 --- a/buildSrc/src/main/groovy/otel/OtelConverterPlugin.groovy +++ /dev/null @@ -1,137 +0,0 @@ -package otel - -import org.gradle.api.DefaultTask -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.tasks.TaskAction -import org.objectweb.asm.ClassReader -import org.objectweb.asm.ClassWriter -import otel.muzzle.MuzzleConverter -import otel.muzzle.MuzzleGenerator - -import java.nio.charset.StandardCharsets -import java.nio.file.Files -import java.nio.file.Path - -import static groovy.io.FileType.FILES -import static org.objectweb.asm.ClassWriter.COMPUTE_FRAMES - -@SuppressWarnings('unused') -class OtelConverterPlugin implements Plugin { - @Override - void apply(Project project) { - // Declare "javaagent" configuration to declare dependencies to convert - project.configurations { - javaagent { - visible = false // Only accessible inside this project - transitive = false // Only fetch javaagent modules and not their dependencies - } - } - // Create and initialize extension - def extension = project.extensions.create('otelConverter', OtelConverterExtension) - extension.workingDirectory.convention(project.layout.buildDirectory.dir('javaagent')) - extension.targetDirectory.convention(project.layout.buildDirectory.dir('classes/java/main')) - // Register task - def convertTask = project.tasks.register('convertOtelJavaAgent', ConvertJavaAgent).get() - def buildTask = project.tasks.named('classes').get() - buildTask.dependsOn(convertTask) - } -} - -class ConvertJavaAgent extends DefaultTask { - @TaskAction - void convert() { - // Retrieve plugin configuration - def extension = project.extensions.getByType(OtelConverterExtension) - def workingDirectory = extension.workingDirectory.get() - def targetDirectory = extension.targetDirectory.asFile.get() - // Convert each javaagent artifact - project.configurations.named('javaagent').get().resolve().each {jarFile -> - def artifactName = getArtifactName(jarFile.name) - def artifactDir = workingDirectory.dir(artifactName).asFile - def instrumenterFiles = [] - logger.debug("Coonverting javaagent $artifactName into $artifactDir") - project.copy { - from(project.zipTree(jarFile)) { - include '**/*.class' - } - into artifactDir - } - artifactDir.traverse( - type: FILES, - nameFilter: ~/.*\.class$/ - ) { - convertClass(artifactDir, targetDirectory, it, instrumenterFiles) - } - generateServiceLoaderConfiguration(targetDirectory, instrumenterFiles) - } - } - - static String getArtifactName(String jarName) { - // Removing file extension - String artifactName = jarName.endsWith('.jar') ? jarName.substring(0, jarName.length() - 4) : jarName - // Removing qualifier - def parts = artifactName.split('-') - def reversedParts = parts.iterator().reverse() - while (reversedParts.hasNext()) { - def part = reversedParts.next() - if (part =~ /[a-zA-Z]/) { - reversedParts.remove() - } else { - break - } - } - return reversedParts.reverse().join('-') - } - - void convertClass(File sourceDirectory, File targetDirectory, File file, List instrumenterFiles) { - // Compute target file location - def relativePath = sourceDirectory.relativePath(file) - Path targetFile = targetDirectory.toPath().resolve(relativePath) - Path targetFolder = targetFile.parent - logger.debug("Converting class file ${relativePath}") - // Ensure target folder exists - if (!Files.isDirectory(targetFolder)) { - Files.createDirectories(targetFolder) - } - - try (InputStream inputStream = Files.newInputStream(file.toPath())) { - def writer = new ClassWriter(COMPUTE_FRAMES) - def virtualFieldConverter = new VirtualFieldConverter(writer, file.name) - def muzzleConverter = new MuzzleConverter(virtualFieldConverter, file.name) - def instrumentationModuleConverter = new InstrumentationModuleConverter(muzzleConverter, file.name) - def typeInstrumentationConverter = new TypeInstrumentationConverter(instrumentationModuleConverter, file.name) - def javaAgentApiChecker = new OtelApiVerifier(typeInstrumentationConverter, file.name) - def reader = new ClassReader(inputStream) - reader.accept(javaAgentApiChecker, 0) - Files.write(targetFile, writer.toByteArray()) - - // Check if there are references to write as muzzle class - if (muzzleConverter.isInstrumentationModule()) { - MuzzleGenerator.writeMuzzleClass(targetFolder, relativePath, muzzleConverter.getReferences()) - instrumenterFiles.add(relativePath) - } - } - } - - void generateServiceLoaderConfiguration(File targetDirectory, List instrumenterFiles) { - if (instrumenterFiles.isEmpty()) { - return - } - def classNames = instrumenterFiles.collect { - it.replace('/', '.').substring(0, it.length() - 6) - } - logger.debug("Writing service loader configuration for instrumenters: ${classNames.join(',')}") - def configurationPath = targetDirectory.toPath().resolve("META-INF/services/datadog.trace.agent.tooling.Instrumenter") - Files.createDirectories(configurationPath.parent) - Files.write(configurationPath, classNames, StandardCharsets.UTF_8) - } -} - -interface OtelConverterExtension { - /** Where to extract original javaagent class files */ - DirectoryProperty getWorkingDirectory() - /** Where to store converted javaagent class files */ - DirectoryProperty getTargetDirectory() -} diff --git a/buildSrc/src/main/groovy/otel/TypeInstrumentationConverter.java b/buildSrc/src/main/groovy/otel/TypeInstrumentationConverter.java deleted file mode 100644 index 09f1d5c586c..00000000000 --- a/buildSrc/src/main/groovy/otel/TypeInstrumentationConverter.java +++ /dev/null @@ -1,79 +0,0 @@ -package otel; - -import static org.objectweb.asm.Opcodes.ACC_PUBLIC; -import static org.objectweb.asm.Opcodes.ACONST_NULL; -import static org.objectweb.asm.Opcodes.ARETURN; -import static org.objectweb.asm.Opcodes.ASM9; - -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.InsnList; -import org.objectweb.asm.tree.InsnNode; -import org.objectweb.asm.tree.MethodNode; - -/** - * This class visitor converts OpenTelemetry TypeInstrumentation into Datadog instrumenter. - */ -public class TypeInstrumentationConverter extends AbstractClassVisitor { - static final String TYPE_INSTRUMENTATION_CLASS_NAME = "io/opentelemetry/javaagent/extension/instrumentation/TypeInstrumentation"; - private static final String FOR_TYPE_HIERARCHY_CLASS_NAME = "datadog/trace/agent/tooling/Instrumenter$ForTypeHierarchy"; - private static final String TYPE_MATCHER_METHOD_NAME = "typeMatcher"; - private static final String TYPE_MATCHER_DESC = "()Lnet/bytebuddy/matcher/ElementMatcher;"; - private static final String HIERARCHY_MATCHER_METHOD_NAME = "hierarchyMatcher"; - private static final String HAS_ADVICE_CLASS_NAME = "datadog/trace/instrumentation/opentelemetry/automatic/HasAdvice"; - - public TypeInstrumentationConverter(ClassVisitor classVisitor, String className) { - super(classVisitor, className); - } - - @Override - public void visitEnd() { - if (inheritsTypeInstrumentation()) { - convertTypeInstrumentation(); - } - if (this.next != null) { - ClassNode cn = (ClassNode) this.cv; - cn.accept(this.next); - } - } - - private boolean inheritsTypeInstrumentation() { - ClassNode classNode = (ClassNode) this.cv; - return classNode.interfaces.stream().anyMatch(TYPE_INSTRUMENTATION_CLASS_NAME::equals); - } - - private void convertTypeInstrumentation() { - ClassNode classNode = (ClassNode) this.cv; - // Remove OTel TypeInstrumentation interface - classNode.interfaces.remove(TYPE_INSTRUMENTATION_CLASS_NAME); - // Implement Instrumenter.ForTypeHierarchy - classNode.interfaces.add(FOR_TYPE_HIERARCHY_CLASS_NAME); - addHierarchyMarkerTypeMethod(); - convertTypeMatcherMethod(); - // Implement HasAdvice wrapper - classNode.interfaces.add(HAS_ADVICE_CLASS_NAME); - } - - private void addHierarchyMarkerTypeMethod() { - ClassNode classNode = (ClassNode) this.cv; - - MethodNode methodNode = new MethodNode( - ASM9, - ACC_PUBLIC, - "hierarchyMarkerType", - "()Ljava/lang/String;", - "()Ljava/lang/String;", - null - ); - InsnList instructions = methodNode.instructions; - instructions.add(new InsnNode(ACONST_NULL)); - instructions.add(new InsnNode(ARETURN)); - - classNode.methods.add(methodNode); - } - - private void convertTypeMatcherMethod() { - MethodNode methodNode = findMethodNode(TYPE_MATCHER_METHOD_NAME, TYPE_MATCHER_DESC); - methodNode.name = HIERARCHY_MATCHER_METHOD_NAME; - } -} diff --git a/buildSrc/src/main/groovy/otel/VirtualFieldConverter.java b/buildSrc/src/main/groovy/otel/VirtualFieldConverter.java deleted file mode 100644 index 083af73a229..00000000000 --- a/buildSrc/src/main/groovy/otel/VirtualFieldConverter.java +++ /dev/null @@ -1,145 +0,0 @@ -package otel; - -import static org.objectweb.asm.Opcodes.ASM9; -import static org.objectweb.asm.Opcodes.INVOKEINTERFACE; -import static org.objectweb.asm.Opcodes.INVOKESTATIC; -import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; - -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Type; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This visitor converts OpenTelemetry VirtualField API usage into Datadog ContextStore and InstrumentationContext usage. - */ -public class VirtualFieldConverter extends ClassVisitor { - private static final Logger LOGGER = LoggerFactory.getLogger(VirtualFieldConverter.class); - // VirtualField - private static final String VIRTUAL_FIELD_CLASS = "io/opentelemetry/instrumentation/api/util/VirtualField"; - private static final String FIND_METHOD = "find"; - private static final String FIND_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.getType("L" + VIRTUAL_FIELD_CLASS + ";"), Type.getType(Class.class), Type.getType(Class.class)); - // ContextStore - private static final String CONTEXT_STORE_CLASS = "datadog/trace/bootstrap/ContextStore"; - private static final String GET_METHOD = "get"; - private static final String SET_METHOD = "set"; - private static final String GET_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.getType(Object.class), Type.getType(Object.class)); - private static final String SET_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object.class), Type.getType(Object.class)); - // InstrumentationContext - private static final String INSTRUMENTATION_CONTEXT_CLASS = "datadog/trace/bootstrap/InstrumentationContext"; - private static final String INSTRUMENTATION_CONTEXT_GET_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.getType("L" + CONTEXT_STORE_CLASS + ";"), Type.getType(Class.class), Type.getType(Class.class)); - /** - * The visited class name. - */ - private final String className; - - public VirtualFieldConverter(ClassVisitor classVisitor, String className) { - super(ASM9, classVisitor); - this.className = className; - } - - @Override - public MethodVisitor visitMethod( - final int access, - final String name, - final String descriptor, - final String signature, - final String[] exceptions) { - final MethodVisitor defaultVisitor = super.visitMethod(access, name, descriptor, signature, exceptions); - return createMethodVisitor(defaultVisitor); - } - - private MethodVisitor createMethodVisitor(final MethodVisitor defaultVisitor) { - return new MethodVisitor(ASM9, defaultVisitor) { - /* The last two constants pushed onto the stack. */ - private Object constant1; - private Object constant2; - - @Override - public void visitLdcInsn(final Object value) { - // 'first' constant gets moved over once 'second' one comes in - constant1 = constant2; - constant2 = value; - super.visitLdcInsn(value); - } - - @Override - public void visitMethodInsn(final int opcode, final String owner, final String name, final String descriptor, final boolean isInterface) { - // Look for call to VirtualField.find(T.class, F.class) - if (INVOKESTATIC == opcode - && VIRTUAL_FIELD_CLASS.equals(owner) - && FIND_METHOD.equals(name) - && FIND_METHOD_DESCRIPTOR.equals(descriptor)) { - rewriteFind(); - } - // Look for call to VirtualField.get(T.class) - else if (INVOKEVIRTUAL == opcode - && VIRTUAL_FIELD_CLASS.equals(owner) - && GET_METHOD.equals(name) - && GET_METHOD_DESCRIPTOR.equals(descriptor)) { - rewriteGet(); - } - // Look for call to VirtualField.set(T.class, F.class) - else if (INVOKEVIRTUAL == opcode - && VIRTUAL_FIELD_CLASS.equals(owner) - && SET_METHOD.equals(name) - && SET_METHOD_DESCRIPTOR.equals(descriptor)) { - rewriteSet(); - } - // Otherwise, copy method - else { - super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); - } - // Reset constants for next method check - constant1 = null; - constant2 = null; - } - - private void rewriteFind() { - LOGGER.debug("Found VirtualField.find() access - instrumentation.class={}", className); - // We track the last two constants pushed onto the stack to make sure they match - // the expected key and context types. Matching calls are rewritten to call the - // dynamically injected context store implementation instead. - if (!(constant1 instanceof Type) || !(constant2 instanceof Type)) { - throw new IllegalStateException("Unexpected VirtualField.find() parameter types: " + constant1.getClass().getName() + " and " + constant2.getClass().getName()); - } - String keyClassName = ((Type) constant1).getClassName(); - String contextClassName = ((Type) constant2).getClassName(); - LOGGER.debug( - "Rewriting VirtualField.find() into InstrumentationContext.get() - instrumentation.class={} instrumentation.target.context={}->{}", - className, - keyClassName, - contextClassName); - mv.visitMethodInsn( - INVOKESTATIC, - INSTRUMENTATION_CONTEXT_CLASS, - GET_METHOD, - INSTRUMENTATION_CONTEXT_GET_METHOD_DESCRIPTOR, - false); - } - - private void rewriteGet() { - LOGGER.debug( - "Rewriting VirtualField.get() into ContextStore.get() - instrumentation.class={}", className); - mv.visitMethodInsn( - INVOKEINTERFACE, - CONTEXT_STORE_CLASS, - GET_METHOD, - GET_METHOD_DESCRIPTOR, - true); - } - - private void rewriteSet() { - LOGGER.debug( - "Rewriting VirtualField.set() into ContextStore.set() - instrumentation.class={}", className); - mv.visitMethodInsn( - INVOKEINTERFACE, - CONTEXT_STORE_CLASS, - SET_METHOD, - SET_METHOD_DESCRIPTOR, - true); - } - }; - } -} diff --git a/buildSrc/src/main/groovy/otel/muzzle/MuzzleConverter.java b/buildSrc/src/main/groovy/otel/muzzle/MuzzleConverter.java deleted file mode 100644 index 2c6a3f2db3e..00000000000 --- a/buildSrc/src/main/groovy/otel/muzzle/MuzzleConverter.java +++ /dev/null @@ -1,436 +0,0 @@ -package otel.muzzle; - -import static java.util.stream.Collectors.toList; -import static net.bytebuddy.jar.asm.Opcodes.ACC_PUBLIC; -import static org.objectweb.asm.Opcodes.AASTORE; -import static org.objectweb.asm.Opcodes.ALOAD; -import static org.objectweb.asm.Opcodes.ANEWARRAY; -import static org.objectweb.asm.Opcodes.ARETURN; -import static org.objectweb.asm.Opcodes.ASTORE; -import static org.objectweb.asm.Opcodes.BIPUSH; -import static org.objectweb.asm.Opcodes.DUP; -import static org.objectweb.asm.Opcodes.GETSTATIC; -import static org.objectweb.asm.Opcodes.INVOKESPECIAL; -import static org.objectweb.asm.Opcodes.INVOKESTATIC; -import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; -import static org.objectweb.asm.Opcodes.NEW; -import static org.objectweb.asm.Opcodes.POP; -import static org.objectweb.asm.tree.AbstractInsnNode.FIELD_INSN; -import static org.objectweb.asm.tree.AbstractInsnNode.LDC_INSN; -import static org.objectweb.asm.tree.AbstractInsnNode.METHOD_INSN; - -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.tree.AbstractInsnNode; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.FieldInsnNode; -import org.objectweb.asm.tree.InsnList; -import org.objectweb.asm.tree.InsnNode; -import org.objectweb.asm.tree.IntInsnNode; -import org.objectweb.asm.tree.LdcInsnNode; -import org.objectweb.asm.tree.MethodInsnNode; -import org.objectweb.asm.tree.MethodNode; -import org.objectweb.asm.tree.TypeInsnNode; -import otel.AbstractClassVisitor; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.StreamSupport; - -/** - * This visitor converts muzzle methods from OpenTelemetry InstrumentationModuleMuzzle implementation into a dedicated Datadog Muzzle class. - */ -public class MuzzleConverter extends AbstractClassVisitor { - private static final String INSTRUMENTATION_MODULE_MUZZLE_CLASS_NAME = "io/opentelemetry/javaagent/tooling/muzzle/InstrumentationModuleMuzzle"; - private static final String STRING_CLASS_NAME = "java/lang/String"; - /* OTel muzzle API */ - private static final String GET_MUZZLE_HELPER_CLASS_NAMES_METHOD_NAME = "getMuzzleHelperClassNames"; - private static final String GET_MUZZLE_HELPS_CASS_NAMES_DESC = "()Ljava/util/List;"; - /* Datadog muzzle API */ - private static final String HELPER_CLASS_NAMES_METHOD_NAME = "helperClassNames"; - private static final String HELPER_CLASS_NAME_DESC = "()[Ljava/lang/String;"; - private static final String ADD_METHOD_NAME = "add"; - private static final String ADD_METHOD_DESC = "(Ljava/lang/Object;)Z"; - private static final String GET_MUZZLE_REFERENCES_METHOD_NAME = "getMuzzleReferences"; - private static final String GET_MUZZLE_REFERENCES_DESC = "()Ljava/util/Map;"; - private static final String REGISTER_MUZZLE_VIRTUAL_FIELDS_METHOD_NAME = "registerMuzzleVirtualFields"; - private static final String REGISTER_MUZZLE_VIRTUAL_FIELDS_DESC = "(Lio/opentelemetry/javaagent/tooling/muzzle/VirtualFieldMappingsBuilder;)V"; - - private final List references; - private boolean instrumentationModule; - - public MuzzleConverter(ClassVisitor classVisitor, String className) { - super(classVisitor, className); - this.references = new ArrayList<>(); - this.instrumentationModule = false; - } - - @Override - public void visitEnd() { - if (inheritsInstrumentationModuleMuzzle()) { - this.instrumentationModule = true; - convertHelperClassNames(); - convertContextStore(); - captureMuzzleReferences(); - // TODO Add oll other muzzle methods conversion too - cleanUpOTelMuzzle(); - } else { - this.instrumentationModule = false; - } - - if (this.next != null) { - ClassNode cn = (ClassNode) this.cv; - cn.accept(this.next); - } - } - - /** - * Checks whether the last visited class is an InstrumentationGroup instance. - * - * @return {@code true} if the last visited class is an InstrumentationGroup instance, {@code false} otherwise. - */ - public boolean isInstrumentationModule() { - return this.instrumentationModule; - } - - private boolean inheritsInstrumentationModuleMuzzle() { - ClassNode classNode = (ClassNode) this.cv; - return classNode.interfaces.stream().anyMatch(INSTRUMENTATION_MODULE_MUZZLE_CLASS_NAME::equals); - } - - /** - * Converts OTel {@code public List getMuzzleHelperClassNames()} method into Datadog {@code public String[] helperClassNames()} method. - */ - private void convertHelperClassNames() { - // Look for OTel method - MethodNode methodNode = findMethodNode(GET_MUZZLE_HELPER_CLASS_NAMES_METHOD_NAME, GET_MUZZLE_HELPS_CASS_NAMES_DESC); - List helperNames = captureHelperClassNames(methodNode); - /* - * Update method signature and implementation - */ - methodNode.name = HELPER_CLASS_NAMES_METHOD_NAME; - methodNode.desc = HELPER_CLASS_NAME_DESC; - methodNode.instructions = buildHelperClassNamesInstructions(helperNames); - } - - /** - * Captures all the helper names from OTel {@code public List getMuzzleHelperClassNames()} method. - * @param methodNode The OTel getMuzzleHelperClassNames method. - * @return The list of helper names. - */ - private List captureHelperClassNames(MethodNode methodNode) { - return StreamSupport.stream(methodNode.instructions.spliterator(), false) - .filter(node -> node.getType() == METHOD_INSN) // Filter method instructions - .map(node -> (MethodInsnNode) node) - .filter(node -> - ADD_METHOD_NAME.equals(node.name) && ADD_METHOD_DESC.equals(node.desc) - && node.getPrevious() instanceof LdcInsnNode - ) // Filter add(Object) - .map(node -> ((LdcInsnNode) node.getPrevious())) // Get previous LDC value as String - .map(node -> (String) node.cst) - .collect(toList()); - } - - /** - * Creates the Datadog {@code public String[] helperClassNames()} method instructions. - * @param helperNames The helper names. - * @return The Datadog helperClassNames method instruction list. - */ - private InsnList buildHelperClassNamesInstructions(List helperNames) { - InsnList list = new InsnList(); - // Create a String array of the right size - list.add(new IntInsnNode(BIPUSH, helperNames.size())); - list.add(new TypeInsnNode(ANEWARRAY, STRING_CLASS_NAME)); - // Append each helper name - int index = 0; - for (String helperName : helperNames) { - list.add(new InsnNode(DUP)); - list.add(new IntInsnNode(BIPUSH, index++)); - list.add(new LdcInsnNode(helperName)); - list.add(new InsnNode(AASTORE)); - } - // Return the array - list.add(new InsnNode(ARETURN)); - return list; - } - - /** - * Gets the captured muzzle references. - * - * @return The captured muzzle references, an empty collection otherwise. - */ - public List getReferences() { - return this.references; - } - - /** - * Captures OpenTelemetry ClassRef/ClassRefBuilder/Source/Field/Method and ASM Type calls to recreate muzzle references. - */ - private void captureMuzzleReferences() { - // Look for OTel method - MethodNode methodNode = findMethodNode(GET_MUZZLE_REFERENCES_METHOD_NAME, GET_MUZZLE_REFERENCES_DESC); - // Store sources, flags and types captured along walking the instructions - List sources = new ArrayList<>(); - int flags = 0; - List types = new ArrayList<>(); - // Declare the muzzle reference to be consolidated when walking over OTel builder API - MuzzleReference currentReference = null; - for (AbstractInsnNode instructionNode : methodNode.instructions) { - if (instructionNode.getType() == METHOD_INSN) { - MethodInsnNode methodInsnNode = (MethodInsnNode) instructionNode; - // Look for ClassRef.builder(String) - if ("io/opentelemetry/javaagent/tooling/muzzle/references/ClassRef".equals(methodInsnNode.owner) - && "builder".equals(methodInsnNode.name) - && "(Ljava/lang/String;)Lio/opentelemetry/javaagent/tooling/muzzle/references/ClassRefBuilder;".equals(methodInsnNode.desc) - && methodInsnNode.getPrevious().getType() == LDC_INSN) { - LdcInsnNode ldcInsnNode = (LdcInsnNode) methodInsnNode.getPrevious(); - if (currentReference != null) { - this.references.add(currentReference); - } - currentReference = new MuzzleReference(); - currentReference.className = ((String) ldcInsnNode.cst); - } else if ("io/opentelemetry/javaagent/tooling/muzzle/references/ClassRefBuilder".equals(methodInsnNode.owner)) { - if (currentReference == null) { - throw new IllegalStateException("Failed to capture muzzle references of " + className + ": no current reference"); - } - // Look for ClassRefBuilder.setSuperClassName(String) - if ("setSuperClassName".equals(methodInsnNode.name) - && "(Ljava/lang/String;)Lio/opentelemetry/javaagent/tooling/muzzle/references/ClassRefBuilder;".equals(methodInsnNode.desc) - && methodInsnNode.getPrevious().getType() == LDC_INSN) { - currentReference.superName = ((String) ((LdcInsnNode) methodInsnNode.getPrevious()).cst); - } - // Look for ClassRefBuilder.addSource(String, int) - // NOTE: Call for ClassRefBuilder.addSource(String) will be forwarded to ClassRefBuilder.addSource(String, int) - else if ("addSource".equals(methodInsnNode.name) - && "(Ljava/lang/String;I)Lio/opentelemetry/javaagent/tooling/muzzle/references/ClassRefBuilder;".equals(methodInsnNode.desc) - && methodInsnNode.getPrevious().getType() == LDC_INSN - && methodInsnNode.getPrevious().getPrevious().getType() == LDC_INSN) { - String source = ((LdcInsnNode) methodInsnNode.getPrevious().getPrevious()).cst + ":" + ((LdcInsnNode) methodInsnNode.getPrevious()).cst; - currentReference.sources.add(source); - } - // Look for ClassRefBuilder.addFlag(Flag) - else if ("addFlag".equals(methodInsnNode.name) - && "(Lio/opentelemetry/javaagent/tooling/muzzle/references/Flag;)Lio/opentelemetry/javaagent/tooling/muzzle/references/ClassRefBuilder;".equals(methodInsnNode.desc)) { - currentReference.flags += flags; - flags = 0; - } - // Look for ClassRefBuilder.addInterfaceName(String) - else if ("addInterfaceName".equals(methodInsnNode.name) - && "(Ljava/lang/String;)Lio/opentelemetry/javaagent/tooling/muzzle/references/ClassRefBuilder;".equals(methodInsnNode.desc) - && methodInsnNode.getPrevious().getType() == LDC_INSN) { - currentReference.interfaces.add((String) ((LdcInsnNode) methodInsnNode.getPrevious()).cst); - } - // Look for ClassRefBuilder.addInterfaceName(Collection). It is not supported as it does not seem to be used - else if ("addInterfaceNames".equals(methodInsnNode.name) - && "(Ljava/util/Collection;)Lio/opentelemetry/javaagent/tooling/muzzle/references/ClassRefBuilder;".equals(methodInsnNode.desc)) { - throw new IllegalStateException("ClassRefBuilder.addInterfaceName(Collection) is not supported"); - } - // Look for ClassRefBuilder.addField(Source[], Flag[], String, Type, boolean) - else if ("addField".equals(methodInsnNode.name) - && "([Lio/opentelemetry/javaagent/tooling/muzzle/references/Source;[Lio/opentelemetry/javaagent/tooling/muzzle/references/Flag;Ljava/lang/String;Lorg/objectweb/asm/Type;Z)Lio/opentelemetry/javaagent/tooling/muzzle/references/ClassRefBuilder;".equals(methodInsnNode.desc) - && methodInsnNode.getPrevious().getPrevious().getPrevious().getPrevious().getType() == LDC_INSN) { - LdcInsnNode ldcInsnNode = (LdcInsnNode) methodInsnNode.getPrevious().getPrevious().getPrevious().getPrevious(); - MuzzleReference.Field field = new MuzzleReference.Field(); - field.sources = sources; - field.flags = flags; - field.name = (String) ldcInsnNode.cst; - field.fieldType = getFieldType(types); - currentReference.fields.add(field); - sources = new ArrayList<>(); - flags = 0; - } - // Look for ClassRefBuilder.addMethod(Source[] methodSources, Flag[] methodFlags, String methodName, Type methodReturnType, Type... methodArgumentTypes) - else if ("addMethod".equals(methodInsnNode.name) - && "([Lio/opentelemetry/javaagent/tooling/muzzle/references/Source;[Lio/opentelemetry/javaagent/tooling/muzzle/references/Flag;Ljava/lang/String;Lorg/objectweb/asm/Type;[Lorg/objectweb/asm/Type;)Lio/opentelemetry/javaagent/tooling/muzzle/references/ClassRefBuilder;".equals(methodInsnNode.desc) - ) { - String name = getReferenceMethodName(methodInsnNode, types); - MuzzleReference.Method method = new MuzzleReference.Method(); - method.sources = sources; - method.flags = flags; - method.name = name; - method.methodType = getMethodType(types); - currentReference.methods.add(method); - sources = new ArrayList<>(); - flags = 0; - } - } else if ("io/opentelemetry/javaagent/tooling/muzzle/references/Source".equals(methodInsnNode.owner)) { - // Look for new Source(String, int) - if ("".equals(methodInsnNode.name) - && "(Ljava/lang/String;I)V".equals(methodInsnNode.desc) - && methodInsnNode.getPrevious().getType() == LDC_INSN - && methodInsnNode.getPrevious().getPrevious().getType() == LDC_INSN) { - String source = ((LdcInsnNode) methodInsnNode.getPrevious().getPrevious()).cst + ":" + ((LdcInsnNode) methodInsnNode.getPrevious()).cst; - sources.add(source); - } - } else if ("org/objectweb/asm/Type".equals(methodInsnNode.owner)) { - // Look for Type.getType(String) - if ("getType".equals(methodInsnNode.name) - && "(Ljava/lang/String;)Lorg/objectweb/asm/Type;".equals(methodInsnNode.desc) - && methodInsnNode.getPrevious().getType() == LDC_INSN) { - types.add((String) ((LdcInsnNode) methodInsnNode.getPrevious()).cst); - } - } - } else if (instructionNode.getType() == FIELD_INSN) { - FieldInsnNode fieldInsnNode = (FieldInsnNode) instructionNode; - if (fieldInsnNode.getOpcode() == GETSTATIC - && fieldInsnNode.owner.startsWith("io/opentelemetry/javaagent/tooling/muzzle/references/Flag$")) { - flags += getFlag(fieldInsnNode); - } - } - } - if (currentReference != null) { - this.references.add(currentReference); - } - } - - private int getFlag(FieldInsnNode fieldInsnNode) { - int index = fieldInsnNode.owner.lastIndexOf("$"); - String flagType = index == -1 ? fieldInsnNode.owner :fieldInsnNode.owner.substring(index + 1); - String flagName = fieldInsnNode.name; - int flag = MuzzleFlag.convertOtelFlag(flagType, flagName); - if (flag < 0) { - throw new IllegalStateException("Failed to extract muzzle reference flag from " + fieldInsnNode.owner + "." + fieldInsnNode.name + " of " + className); - } - return flag; - } - - /** - * Converts OTel {@code public void getMuzzleHelperClassNames()} method into Datadog {@code public Map contextStore()} method. - */ - private void convertContextStore() { - ClassNode classNode = (ClassNode) this.cv; - MethodNode methodNode = findMethodNode(REGISTER_MUZZLE_VIRTUAL_FIELDS_METHOD_NAME, REGISTER_MUZZLE_VIRTUAL_FIELDS_DESC); - Map stores = captureContextStore(methodNode); - if (!stores.isEmpty()) { - MethodNode contextStoreMethodNode = generateContextStoreMethod(stores); - classNode.methods.add(contextStoreMethodNode); - } - } - - private Map captureContextStore(MethodNode methodNode) { - Map stores = new HashMap<>(); - for (AbstractInsnNode instructionNode : methodNode.instructions) { - if (instructionNode.getType() == METHOD_INSN) { - MethodInsnNode methodInsnNode = (MethodInsnNode) instructionNode; - // Look for VirtualFieldMappingsBuilder.register(String, String) - if ("io/opentelemetry/javaagent/tooling/muzzle/VirtualFieldMappingsBuilder".equals(methodInsnNode.owner) - && "register".equals(methodInsnNode.name) - && "(Ljava/lang/String;Ljava/lang/String;)Lio/opentelemetry/javaagent/tooling/muzzle/VirtualFieldMappingsBuilder;".equals(methodInsnNode.desc) - && methodInsnNode.getPrevious().getType() == LDC_INSN - && methodInsnNode.getPrevious().getPrevious().getType() == LDC_INSN) { - LdcInsnNode valueLdcInsnNode = (LdcInsnNode) methodInsnNode.getPrevious(); - String value = (String) valueLdcInsnNode.cst; - LdcInsnNode keyLdcInsnNode = (LdcInsnNode) methodInsnNode.getPrevious().getPrevious(); - String key = (String) keyLdcInsnNode.cst; - stores.put(key,value); - } - } - } - return stores; - } - - private MethodNode generateContextStoreMethod(Map stores) { - MethodNode methodNode = new MethodNode( - ACC_PUBLIC, - "contextStore", - "()Ljava/util/Map;", - "()Ljava/util/Map;", - null - ); - // Create HashMap - methodNode.visitTypeInsn(NEW, "java/util/HashMap"); - methodNode.visitInsn(DUP); - methodNode.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "", "()V", false); - methodNode.visitVarInsn(ASTORE, 1); - // Put keys and values - stores.forEach((key, value) -> { - methodNode.visitVarInsn(ALOAD, 1); - methodNode.visitLdcInsn(key); - methodNode.visitLdcInsn(value); - methodNode.visitMethodInsn(INVOKEVIRTUAL, "java/util/HashMap", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", false); - methodNode.visitInsn(POP); - }); - // Wrap into unmodifiable map - methodNode.visitVarInsn(ALOAD, 1); - methodNode.visitMethodInsn(INVOKESTATIC, "java/util/Collections", "unmodifiableMap", "(Ljava/util/Map;)Ljava/util/Map;", false); - // Return wrapped map - methodNode.visitInsn(ARETURN); - return methodNode; - } - - private String getFieldType(List types) { - if (types.size() != 1) { - throw new IllegalStateException("Unexpected number of collected types: "+types.size() + " but expected 1"); - } - String fieldType = types.get(0); - types.clear(); - return fieldType; - } - - private String getMethodType(List types) { - if (types.isEmpty()) { - throw new IllegalStateException("Unexpected number of collected types: no types but expected at least one"); - } - String returnType = types.remove(0); - String methodType = "(" + String.join("", types) + ")" + returnType; - types.clear(); - return methodType; - } - - private String getReferenceMethodName(MethodInsnNode methodInsnNode, List types) { - if (types.isEmpty()) { - throw new IllegalStateException("Unexpected number of collected types: no types but expected at least one"); - } - int rewindDistance = 0; - int parameterCount = types.size() - 1; - // Rewind the Type.getType() for parameters stored as the vararg parameter - // Need to rewind 5 instructions per parameter: - // * dup - // * ldc (array index) - // * ldc_w (type descriptor string) - // * invokestatic (Type.getType() call) - // * aastore (array store) - rewindDistance += 5*parameterCount; - // Rewind vararg array creation - // Need to rewind 2 instructions: - // * ldc (array size) - // * anewarray (array creation) - rewindDistance += 2; - // Rewind return type parameter - // Need to rewind 2 instructions: - // * ldc_w (type descriptor string) - // * invokestatic (Type.getType() call) - rewindDistance+= 2; - // Finally rewind up to the load instruction with the method name - rewindDistance++; - AbstractInsnNode abstractInsnNode = methodInsnNode; - for (int i = 0; i < rewindDistance; i++) { - abstractInsnNode = abstractInsnNode.getPrevious(); - if (abstractInsnNode == null) { - throw new IllegalStateException("Invalid rewind distance: no more instructions"); - } - } - if (abstractInsnNode instanceof LdcInsnNode) { - return (String) ((LdcInsnNode) abstractInsnNode).cst; - } else { - throw new IllegalStateException("Unexpected instruction type "+abstractInsnNode.getType() + " when looking for reference method name"); - } - } - - /** - * Removes any OpenTelemetry specific muzzle method and interfaces. - */ - private void cleanUpOTelMuzzle() { - ClassNode classNode = (ClassNode) this.cv; - // Remove inheritance from InstrumentationModuleMuzzle - classNode.interfaces.remove(INSTRUMENTATION_MODULE_MUZZLE_CLASS_NAME); - // Remove getMuzzleReferences() method - MethodNode getMuzzleReferencesMethodNode = - findMethodNode(GET_MUZZLE_REFERENCES_METHOD_NAME, GET_MUZZLE_REFERENCES_DESC); - classNode.methods.remove(getMuzzleReferencesMethodNode); - // Remove registerMuzzleVirtualFields(VirtualFieldMappingsBuilder) method - MethodNode registerMuzzleVirtualFieldsMethodNode = - findMethodNode(REGISTER_MUZZLE_VIRTUAL_FIELDS_METHOD_NAME, REGISTER_MUZZLE_VIRTUAL_FIELDS_DESC); - classNode.methods.remove(registerMuzzleVirtualFieldsMethodNode); - } -} diff --git a/buildSrc/src/main/groovy/otel/muzzle/MuzzleFlag.java b/buildSrc/src/main/groovy/otel/muzzle/MuzzleFlag.java deleted file mode 100644 index c6f4c1a6445..00000000000 --- a/buildSrc/src/main/groovy/otel/muzzle/MuzzleFlag.java +++ /dev/null @@ -1,68 +0,0 @@ -package otel.muzzle; - -/** - * This class is a helper class to convert OTel io.opentelemetry.javaagent.tooling.muzzle.references.Flag into - * datadog.trace.agent.tooling.muzzle.Reference flags - */ -public class MuzzleFlag { - /** - * Convert an OTel field instruction node to get a flag into the related Datadog reference/ flag. - * Conversion is based on the OTel enumerate name. - * - * @param flagType The type of flag to parse. - * @param flagName The name of the flag to parse. - * @return The Datadog reference flag, {@code -1} if no matching flag found. - */ - public static int convertOtelFlag(String flagType, String flagName) { - switch (flagType) { - case "VisibilityFlag": - switch (flagName) { - case "PUBLIC": - return 1; // EXPECTS_PUBLIC - case "PROTECTED": - return 2; // EXPECTS_PUBLIC_OR_PROTECTED - case "PACKAGE": - return 4; // EXPECTS_NON_PRIVATE - case "PRIVATE": - return 0; // No flag requirement - } - break; - case "MinimumVisibilityFlag": - switch (flagName) { - case "PUBLIC": - return 1; // EXPECTS_PUBLIC - case "PROTECTED_OR_HIGHER": - return 2; // EXPECTS_PUBLIC_OR_PROTECTED - case "PACKAGE_OR_HIGHER": - return 4; // EXPECTS_NON_PRIVATE - case "PRIVATE_OR_HIGHER": - return 0; // No flag requirement - } - break; - case "ManifestationFlag": - switch (flagName) { - case "FINAL": - return 0; // No flag requirement - case "NON_FINAL": - return 128; // EXPECTS_NON_FINAL - case "ABSTRACT": - return 0; // No flag requirement - case "INTERFACE": - return 32; // EXPECTS_INTERFACE - case "NON_INTERFACE": - return 64; // EXPECTS_NON_INTERFACE - } - break; - case "OwnershipFlag": - switch (flagName) { - case "STATIC": - return 8; // EXPECTS_STATIC - case "NON_STATIC": - return 0; // No flag requirement - } - break; - } - // No flag found - return -1; - } -} diff --git a/buildSrc/src/main/groovy/otel/muzzle/MuzzleGenerator.java b/buildSrc/src/main/groovy/otel/muzzle/MuzzleGenerator.java deleted file mode 100644 index 90fda5278a6..00000000000 --- a/buildSrc/src/main/groovy/otel/muzzle/MuzzleGenerator.java +++ /dev/null @@ -1,180 +0,0 @@ -package otel.muzzle; - -import static net.bytebuddy.jar.asm.ClassWriter.COMPUTE_FRAMES; -import static net.bytebuddy.jar.asm.Opcodes.AASTORE; -import static net.bytebuddy.jar.asm.Opcodes.ACC_FINAL; -import static net.bytebuddy.jar.asm.Opcodes.ACC_PUBLIC; -import static net.bytebuddy.jar.asm.Opcodes.ACC_STATIC; -import static net.bytebuddy.jar.asm.Opcodes.ANEWARRAY; -import static net.bytebuddy.jar.asm.Opcodes.ARETURN; -import static net.bytebuddy.jar.asm.Opcodes.DUP; -import static net.bytebuddy.jar.asm.Opcodes.INVOKESPECIAL; -import static net.bytebuddy.jar.asm.Opcodes.NEW; -import static net.bytebuddy.jar.asm.Opcodes.V1_8; - -import net.bytebuddy.jar.asm.ClassWriter; -import net.bytebuddy.jar.asm.MethodVisitor; -import net.bytebuddy.jar.asm.Opcodes; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; - -/** - * This is a helper class to generate the Muzzle classes with its references. - * This is a port of datadog.trace.agent.tooling.muzzle.MuzzleGenerator. - */ -public final class MuzzleGenerator { - private MuzzleGenerator() { - } - - private static String internalName(String originalClass) { - return originalClass.substring(0, originalClass.length() - 6); - } - - private static String getMuzzleFileName(String originalClass) { - String fileName = internalName(originalClass) + "$Muzzle.class"; - int index = fileName.lastIndexOf('/'); - return fileName.substring(index + 1); - } - - public static void writeMuzzleClass(Path target, String originalClass, List references) throws IOException { - Files.write( - target.resolve(getMuzzleFileName(originalClass)), - writeMuzzleClass(originalClass, references) - ); - } - - private static byte[] writeMuzzleClass(String originalClass, List references) { - ClassWriter cw = new ClassWriter(COMPUTE_FRAMES); - cw.visit( - V1_8, - ACC_PUBLIC | ACC_FINAL, - internalName(originalClass) + "$Muzzle", - null, - "java/lang/Object", - null); - - MethodVisitor mv = - cw.visitMethod( - ACC_PUBLIC | ACC_STATIC, - "create", - "()Ldatadog/trace/agent/tooling/muzzle/ReferenceMatcher;", - null, - null); - - mv.visitCode(); - - mv.visitTypeInsn(NEW, "datadog/trace/agent/tooling/muzzle/ReferenceMatcher"); - mv.visitInsn(DUP); - - mv.visitLdcInsn(references.size()); - mv.visitTypeInsn(ANEWARRAY, "datadog/trace/agent/tooling/muzzle/Reference"); - - int i = 0; - for (MuzzleReference reference : references) { - mv.visitInsn(DUP); - mv.visitLdcInsn(i++); - writeReference(mv, reference); - mv.visitInsn(AASTORE); - } - - mv.visitMethodInsn( - INVOKESPECIAL, - "datadog/trace/agent/tooling/muzzle/ReferenceMatcher", - "", - "([Ldatadog/trace/agent/tooling/muzzle/Reference;)V", - false); - - mv.visitInsn(ARETURN); - - mv.visitMaxs(0, 0); - mv.visitEnd(); - - return cw.toByteArray(); - } - - private static void writeReference(MethodVisitor mv, MuzzleReference reference) { - mv.visitTypeInsn(NEW, "datadog/trace/agent/tooling/muzzle/Reference"); - mv.visitInsn(DUP); - - writeStrings(mv, reference.sources); - mv.visitLdcInsn(reference.flags); - mv.visitLdcInsn(reference.className); - if (null != reference.superName) { - mv.visitLdcInsn(reference.superName); - } else { - mv.visitInsn(Opcodes.ACONST_NULL); - } - writeStrings(mv, reference.interfaces); - writeFields(mv, reference.fields); - writeMethods(mv, reference.methods); - - mv.visitMethodInsn( - INVOKESPECIAL, - "datadog/trace/agent/tooling/muzzle/Reference", - "", - "([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;" - + "[Ldatadog/trace/agent/tooling/muzzle/Reference$Field;" - + "[Ldatadog/trace/agent/tooling/muzzle/Reference$Method;)V", - false); - } - - private static void writeStrings(MethodVisitor mv, List strings) { - mv.visitLdcInsn(strings.size()); - mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); - int i = 0; - for (String string : strings) { - mv.visitInsn(DUP); - mv.visitLdcInsn(i++); - mv.visitLdcInsn(string); - mv.visitInsn(AASTORE); - } - } - - private static void writeFields(MethodVisitor mv, List fields) { - mv.visitLdcInsn(fields.size()); - mv.visitTypeInsn(ANEWARRAY, "datadog/trace/agent/tooling/muzzle/Reference$Field"); - int i = 0; - for (MuzzleReference.Field field : fields) { - mv.visitInsn(DUP); - mv.visitLdcInsn(i++); - mv.visitTypeInsn(NEW, "datadog/trace/agent/tooling/muzzle/Reference$Field"); - mv.visitInsn(DUP); - writeStrings(mv, field.sources); - mv.visitLdcInsn(field.flags); - mv.visitLdcInsn(field.name); - mv.visitLdcInsn(field.fieldType); - mv.visitMethodInsn( - INVOKESPECIAL, - "datadog/trace/agent/tooling/muzzle/Reference$Field", - "", - "([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V", - false); - mv.visitInsn(AASTORE); - } - } - - private static void writeMethods(MethodVisitor mv, List methods) { - mv.visitLdcInsn(methods.size()); - mv.visitTypeInsn(ANEWARRAY, "datadog/trace/agent/tooling/muzzle/Reference$Method"); - int i = 0; - for (MuzzleReference.Method method : methods) { - mv.visitInsn(DUP); - mv.visitLdcInsn(i++); - mv.visitTypeInsn(NEW, "datadog/trace/agent/tooling/muzzle/Reference$Method"); - mv.visitInsn(DUP); - writeStrings(mv, method.sources); - mv.visitLdcInsn(method.flags); - mv.visitLdcInsn(method.name); - mv.visitLdcInsn(method.methodType); - mv.visitMethodInsn( - INVOKESPECIAL, - "datadog/trace/agent/tooling/muzzle/Reference$Method", - "", - "([Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V", - false); - mv.visitInsn(AASTORE); - } - } -} diff --git a/buildSrc/src/main/groovy/otel/muzzle/MuzzleReference.java b/buildSrc/src/main/groovy/otel/muzzle/MuzzleReference.java deleted file mode 100644 index c43a05eced3..00000000000 --- a/buildSrc/src/main/groovy/otel/muzzle/MuzzleReference.java +++ /dev/null @@ -1,61 +0,0 @@ -package otel.muzzle; - -import java.util.ArrayList; -import java.util.List; - -public class MuzzleReference { - public List sources = new ArrayList<>(); - public int flags = 0; - public String className; - public String superName; - public List interfaces = new ArrayList<>(); - public List fields = new ArrayList<>(); - public List methods = new ArrayList<>(); - - @Override - public String toString() { - return "Reference{" + - "sources=" + sources + - ", flags=" + flags + - ", className='" + className + '\'' + - ", superName='" + superName + '\'' + - ", interfaces=" + interfaces + '\'' + - ", fields="+ fields + '\'' + - ", methods="+ methods + - '}'; - } - - public static class Field { - public List sources; - public int flags; - public String name; - public String fieldType; - - @Override - public String toString() { - return "Field{" + - "sources=" + sources + - ", flags=" + flags + - ", name='" + name + '\'' + - ", fieldType='" + fieldType + '\'' + - '}'; - } - } - - public static class Method { - public List sources; - public int flags; - public String name; - public String methodType; - - @Override - public String toString() { - return "Method{" + - "sources=" + sources + - ", flags=" + flags + - ", name='" + name + '\'' + - ", methodType='" + methodType + '\'' + - '}'; - } - } -} diff --git a/buildSrc/src/test/groovy/otel/muzzle/MuzzleConverterTest.groovy b/buildSrc/src/test/groovy/otel/muzzle/MuzzleConverterTest.groovy deleted file mode 100644 index 80e7ebc3fa7..00000000000 --- a/buildSrc/src/test/groovy/otel/muzzle/MuzzleConverterTest.groovy +++ /dev/null @@ -1,117 +0,0 @@ -package otel.muzzle - -import io.opentelemetry.javaagent.instrumentation.grpc.v1_6.GrpcInstrumentationModule -import io.opentelemetry.javaagent.tooling.muzzle.InstrumentationModuleMuzzle -import io.opentelemetry.javaagent.tooling.muzzle.references.ClassRef -import io.opentelemetry.javaagent.tooling.muzzle.references.FieldRef -import io.opentelemetry.javaagent.tooling.muzzle.references.Flag -import io.opentelemetry.javaagent.tooling.muzzle.references.MethodRef -import io.opentelemetry.javaagent.tooling.muzzle.references.Source -import org.objectweb.asm.ClassReader -import spock.lang.Specification - -class MuzzleConverterTest extends Specification { - def 'check muzzle converter reference extraction'(InstrumentationModuleMuzzle module) { - setup: - def expectedReferences = module.getMuzzleReferences().collectEntries { - key, value -> [key , convert(value as ClassRef)] - } - def filename = "${module.class.simpleName}.class" - def muzzleConverter = new MuzzleConverter(null, filename) - - when: - def reader = new ClassReader(module.class.name) - reader.accept(muzzleConverter, 0) - def capturedReferences = [:] as Map - muzzleConverter.references.forEach { - capturedReferences[it.className] = it - } - - then: - capturedReferences.size() == expectedReferences.size() - expectedReferences.forEach { className, MuzzleReference expectedReference -> - assertMuzzleReference(capturedReferences[className], expectedReference) - } - - where: - module << [new GrpcInstrumentationModule()] - } - - // This might seems tedious to compare field be field rather than using built-in object comparison - // But this is way more easy to debug and investigate any issue - // The object to test can contains dozens of sub-structures and make the built-in comparison hard to read - void assertMuzzleReference(MuzzleReference actual, MuzzleReference expected) { - assert actual.sources.size() == expected.sources.size() - assert actual.sources == expected.sources - assert actual.flags == expected.flags - assert actual.className == expected.className - assert actual.superName == expected.superName - assert actual.interfaces.size() == expected.interfaces.size() - assert actual.interfaces == expected.interfaces - assert actual.fields.size() == expected.fields.size() - for (i in 0.. flags) { - def sum = flags.collect { - MuzzleFlag.convertOtelFlag(it.class.superclass.simpleName, it.name()) - }.sum() - return sum == null ? 0 : sum as int - } - - MuzzleReference.Field convert(FieldRef fieldRef) { - MuzzleReference.Field field = new MuzzleReference.Field() - field.sources = fieldRef.sources.collect { convert(it) } - field.flags = convert(fieldRef.flags) - field.name = fieldRef.name - field.fieldType = fieldRef.descriptor - return field - } - - MuzzleReference.Method convert(MethodRef methodRef) { - MuzzleReference.Method method = new MuzzleReference.Method() - method.sources = methodRef.sources.collect { convert(it) } - method.flags = convert(methodRef.flags) - method.name = methodRef.name - method.methodType = methodRef.descriptor - return method - } -} diff --git a/buildSrc/src/test/groovy/otel/muzzle/MuzzleFlagTest.groovy b/buildSrc/src/test/groovy/otel/muzzle/MuzzleFlagTest.groovy deleted file mode 100644 index 94a04bab3fe..00000000000 --- a/buildSrc/src/test/groovy/otel/muzzle/MuzzleFlagTest.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package otel.muzzle - -import io.opentelemetry.javaagent.tooling.muzzle.references.Flag -import spock.lang.Specification - -class MuzzleFlagTest extends Specification { - def 'check all OTel flags are converted'() { - setup: - def missingFlags = [] - - when: - for (final def innerClass in Flag.class.classes) { - for (final def enumConstant in innerClass.enumConstants) { - if (MuzzleFlag.convertOtelFlag(innerClass.simpleName, enumConstant.name()) < 0) { - missingFlags += "${innerClass.simpleName}.${enumConstant.name()}" - } - } - } - - then: - missingFlags == [] - } -} diff --git a/dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/build.gradle b/dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/build.gradle deleted file mode 100644 index 82a0c2896bd..00000000000 --- a/dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/build.gradle +++ /dev/null @@ -1,18 +0,0 @@ -def openTelemetryVersion = '1.32.0-alpha' // TODO 2.0.0 coming soon - -apply from: "$rootDir/gradle/java.gradle" -apply plugin: 'otel-converter' - -dependencies { - compileOnly group: 'io.opentelemetry', name: 'opentelemetry-api', version: openTelemetryVersion - compileOnly group: 'com.google.auto.value', name: 'auto-value-annotations', version: '1.6.6' - - // gRPC instrumentation (as test during the WIP) - implementation group: 'io.opentelemetry.instrumentation', name: 'opentelemetry-grpc-1.6', version: openTelemetryVersion - javaagent group: 'io.opentelemetry.javaagent.instrumentation', name: 'opentelemetry-javaagent-grpc-1.6', version: openTelemetryVersion -} - -forbiddenApisMain { - // Exclude converted OTel integrations - exclude('io/opentelemetry/javaagent/instrumentation/**') -} diff --git a/dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/src/main/java/datadog/trace/instrumentation/opentelemetry/automatic/HasAdvice.java b/dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/src/main/java/datadog/trace/instrumentation/opentelemetry/automatic/HasAdvice.java deleted file mode 100644 index fd4ee251643..00000000000 --- a/dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/src/main/java/datadog/trace/instrumentation/opentelemetry/automatic/HasAdvice.java +++ /dev/null @@ -1,62 +0,0 @@ -package datadog.trace.instrumentation.opentelemetry.automatic; - -import datadog.trace.agent.tooling.Instrumenter; -import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import net.bytebuddy.agent.builder.AgentBuilder; -import net.bytebuddy.description.method.MethodDescription; -import net.bytebuddy.matcher.ElementMatcher; - -/** - * This interface delegates calls from Datadog {@link Instrumenter.HasTypeAdvice} and {@link - * Instrumenter.HasMethodAdvice} to the OpenTelemetry {@link - * #transform(io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer)} method. This is - * an interface with default methods rather than a base class to easily inject common methods - * without changing parent type. - */ -public interface HasAdvice - extends Instrumenter.HasMethodAdvice, Instrumenter.HasTypeAdvice, TypeInstrumentation { - @Override - default void methodAdvice(MethodTransformer transformer) { - transform(TypeTransformerWrapper.of(transformer)); - } - - @Override - default void typeAdvice(TypeTransformer transformer) { - transform(TypeTransformerWrapper.of(transformer)); - } - - class TypeTransformerWrapper - implements io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer { - final MethodTransformer methodTransformer; - final TypeTransformer typeTransformer; - - private TypeTransformerWrapper( - MethodTransformer methodTransformer, TypeTransformer typeTransformer) { - this.methodTransformer = methodTransformer; - this.typeTransformer = typeTransformer; - } - - static TypeTransformerWrapper of(MethodTransformer methodTransformer) { - return new TypeTransformerWrapper(methodTransformer, null); - } - - static TypeTransformerWrapper of(TypeTransformer typeTransformer) { - return new TypeTransformerWrapper(null, typeTransformer); - } - - @Override - public void applyAdviceToMethod( - ElementMatcher methodMatcher, String adviceClassName) { - if (this.methodTransformer != null) { - this.methodTransformer.applyAdvice(methodMatcher, adviceClassName); - } - } - - @Override - public void applyTransformer(AgentBuilder.Transformer transformer) { - if (this.typeTransformer != null) { - this.typeTransformer.applyAdvice(transformer::transform); - } - } - } -} diff --git a/dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/src/main/java/datadog/trace/instrumentation/opentelemetry/automatic/OtelAutomaticInstrumentation.java b/dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/src/main/java/datadog/trace/instrumentation/opentelemetry/automatic/OtelAutomaticInstrumentation.java deleted file mode 100644 index 0029a06a441..00000000000 --- a/dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/src/main/java/datadog/trace/instrumentation/opentelemetry/automatic/OtelAutomaticInstrumentation.java +++ /dev/null @@ -1,19 +0,0 @@ -package datadog.trace.instrumentation.opentelemetry.automatic; - -import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.Config; - -public abstract class OtelAutomaticInstrumentation extends InstrumenterModule.Tracing { - public OtelAutomaticInstrumentation(String instrumentationName, String... additionalNames) { - super(instrumentationName, additionalNames); - } - - @Override - protected boolean defaultEnabled() { - // NOTE: This won't work with GraalVM Native Image - // We might need to include it within InstrumenterConfig for Native Image support - return Config.get() - .configProvider() - .isEnabled(this.names(), "otel.instrumentation.", ".enabled", true); - } -} diff --git a/dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/TypeInstrumentation.java b/dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/TypeInstrumentation.java deleted file mode 100644 index fe70f5d2eab..00000000000 --- a/dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/TypeInstrumentation.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.opentelemetry.javaagent.extension.instrumentation; - -import static net.bytebuddy.matcher.ElementMatchers.any; - -import net.bytebuddy.description.type.TypeDescription; -import net.bytebuddy.matcher.ElementMatcher; - -/* - * This interface is vendor from https://github.com/open-telemetry/opentelemetry-java-instrumentation. - */ -public interface TypeInstrumentation { - default ElementMatcher classLoaderOptimization() { - return any(); - } - - ElementMatcher typeMatcher(); - - void transform(TypeTransformer transformer); -} diff --git a/dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/TypeTransformer.java b/dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/TypeTransformer.java deleted file mode 100644 index de6a6f9faa4..00000000000 --- a/dd-java-agent/instrumentation/opentelemetry/opentelemetry-instrumentations/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/TypeTransformer.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.opentelemetry.javaagent.extension.instrumentation; - -import net.bytebuddy.agent.builder.AgentBuilder; -import net.bytebuddy.description.method.MethodDescription; -import net.bytebuddy.matcher.ElementMatcher; - -/* - * This interface is vendor from https://github.com/open-telemetry/opentelemetry-java-instrumentation. - */ -public interface TypeTransformer { - void applyAdviceToMethod( - ElementMatcher methodMatcher, String adviceClassName); - - void applyTransformer(AgentBuilder.Transformer transformer); -} diff --git a/settings.gradle b/settings.gradle index 80828204dc8..53384c4822a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -366,8 +366,6 @@ include ':dd-java-agent:instrumentation:opentelemetry:opentelemetry-0.3' include ':dd-java-agent:instrumentation:opentelemetry:opentelemetry-1.4' include ':dd-java-agent:instrumentation:opentelemetry:opentelemetry-annotations-1.20' include ':dd-java-agent:instrumentation:opentelemetry:opentelemetry-annotations-1.26' -// POC - Disabled for now -//include ':dd-java-agent:instrumentation:opentelemetry:opentelemetry-instrumentations' include ':dd-java-agent:instrumentation:opentracing' include ':dd-java-agent:instrumentation:opentracing:api-0.31' include ':dd-java-agent:instrumentation:opentracing:api-0.32'