Refactor Instrumenters into InstrumentationModules - J (#1562)

This commit is contained in:
Mateusz Rzeszutek 2020-11-09 23:41:37 +01:00 committed by GitHub
parent aa3ba8d165
commit 0e83a5b56d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 934 additions and 819 deletions

View File

@ -17,10 +17,9 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
import io.opentelemetry.javaagent.tooling.Constants; import io.opentelemetry.javaagent.tooling.Constants;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
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;
@ -37,11 +36,7 @@ import net.bytebuddy.matcher.ElementMatcher;
* This instrumentation forces all class loaders to delegate to the bootstrap class loader * This instrumentation forces all class loaders to delegate to the bootstrap class loader
* for the classes that we have put in the bootstrap class loader. * for the classes that we have put in the bootstrap class loader.
*/ */
@AutoService(Instrumenter.class) final class ClassLoaderInstrumentation implements TypeInstrumentation {
public final class ClassLoaderInstrumentation extends Instrumenter.Default {
public ClassLoaderInstrumentation() {
super("class-loader");
}
@Override @Override
public ElementMatcher<TypeDescription> typeMatcher() { public ElementMatcher<TypeDescription> typeMatcher() {
@ -54,11 +49,6 @@ public final class ClassLoaderInstrumentation extends Instrumenter.Default {
.and(extendsClass(named("java.lang.ClassLoader"))); .and(extendsClass(named("java.lang.ClassLoader")));
} }
@Override
public String[] helperClassNames() {
return new String[] {Constants.class.getName()};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(

View File

@ -0,0 +1,30 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.javaclassloader;
import static java.util.Arrays.asList;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List;
@AutoService(InstrumentationModule.class)
public class ClassLoaderInstrumentationModule extends InstrumentationModule {
public ClassLoaderInstrumentationModule() {
super("class-loader");
}
@Override
public String[] helperClassNames() {
return new String[] {"io.opentelemetry.javaagent.tooling.Constants"};
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return asList(new ClassLoaderInstrumentation(), new ResourceInjectionInstrumentation());
}
}

View File

@ -10,9 +10,8 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.bootstrap.HelperResources; import io.opentelemetry.javaagent.bootstrap.HelperResources;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.net.URL; import java.net.URL;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
@ -30,12 +29,7 @@ import net.bytebuddy.matcher.ElementMatcher;
* <p>We currently only intercept {@link ClassLoader#getResources(String)} because this is the case * <p>We currently only intercept {@link ClassLoader#getResources(String)} because this is the case
* we are currently always interested in, where it's used for service loading. * we are currently always interested in, where it's used for service loading.
*/ */
@AutoService(Instrumenter.class) class ResourceInjectionInstrumentation implements TypeInstrumentation {
public class ResourceInjectionInstrumentation extends Instrumenter.Default {
public ResourceInjectionInstrumentation() {
super("class-loader");
}
@Override @Override
public ElementMatcher<? super TypeDescription> typeMatcher() { public ElementMatcher<? super TypeDescription> typeMatcher() {

View File

@ -10,7 +10,7 @@ import static net.bytebuddy.matcher.ElementMatchers.any;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
import io.opentelemetry.instrumentation.api.config.Config; import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -22,12 +22,9 @@ import net.bytebuddy.matcher.ElementMatcher;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public abstract class AbstractExecutorInstrumentation extends Instrumenter.Default { abstract class AbstractExecutorInstrumentation implements TypeInstrumentation {
private static final Logger log = LoggerFactory.getLogger(AbstractExecutorInstrumentation.class); private static final Logger log = LoggerFactory.getLogger(AbstractExecutorInstrumentation.class);
public static final String EXEC_NAME = "java_concurrent";
private static final String TRACE_EXECUTORS_CONFIG = "otel.trace.executors"; private static final String TRACE_EXECUTORS_CONFIG = "otel.trace.executors";
private final boolean TRACE_ALL_EXECUTORS = private final boolean TRACE_ALL_EXECUTORS =
Config.get().getBooleanProperty("otel.trace.executors.all", false); Config.get().getBooleanProperty("otel.trace.executors.all", false);
@ -45,9 +42,7 @@ public abstract class AbstractExecutorInstrumentation extends Instrumenter.Defau
*/ */
private final Collection<String> ALLOWED_EXECUTORS_PREFIXES; private final Collection<String> ALLOWED_EXECUTORS_PREFIXES;
public AbstractExecutorInstrumentation(String... additionalNames) { AbstractExecutorInstrumentation() {
super(EXEC_NAME, additionalNames);
if (TRACE_ALL_EXECUTORS) { if (TRACE_ALL_EXECUTORS) {
log.info("Tracing all executors enabled."); log.info("Tracing all executors enabled.");
ALLOWED_EXECUTORS = Collections.emptyList(); ALLOWED_EXECUTORS = Collections.emptyList();

View File

@ -11,13 +11,12 @@ 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 static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
import io.opentelemetry.javaagent.instrumentation.api.concurrent.AdviceUtils; import io.opentelemetry.javaagent.instrumentation.api.concurrent.AdviceUtils;
import io.opentelemetry.javaagent.instrumentation.api.concurrent.State; import io.opentelemetry.javaagent.instrumentation.api.concurrent.State;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
@ -25,24 +24,13 @@ import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
/** Instrument {@link Runnable} and {@link Callable} */ final class CallableInstrumentation implements TypeInstrumentation {
@AutoService(Instrumenter.class)
public final class CallableInstrumentation extends Instrumenter.Default {
public CallableInstrumentation() {
super(AbstractExecutorInstrumentation.EXEC_NAME);
}
@Override @Override
public ElementMatcher<TypeDescription> typeMatcher() { public ElementMatcher<TypeDescription> typeMatcher() {
return implementsInterface(named(Callable.class.getName())); return implementsInterface(named(Callable.class.getName()));
} }
@Override
public Map<String, String> contextStore() {
return singletonMap(Callable.class.getName(), State.class.getName());
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(

View File

@ -10,11 +10,10 @@ import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.returns; import static net.bytebuddy.matcher.ElementMatchers.returns;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
import io.opentelemetry.javaagent.instrumentation.api.concurrent.State; import io.opentelemetry.javaagent.instrumentation.api.concurrent.State;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -28,9 +27,7 @@ import net.bytebuddy.matcher.ElementMatcher;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@AutoService(Instrumenter.class) final class FutureInstrumentation implements TypeInstrumentation {
public final class FutureInstrumentation extends Instrumenter.Default {
private static final Logger log = LoggerFactory.getLogger(FutureInstrumentation.class); private static final Logger log = LoggerFactory.getLogger(FutureInstrumentation.class);
/** /**
@ -76,10 +73,6 @@ public final class FutureInstrumentation extends Instrumenter.Default {
ALLOWED_FUTURES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(allowed))); ALLOWED_FUTURES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(allowed)));
} }
public FutureInstrumentation() {
super(AbstractExecutorInstrumentation.EXEC_NAME);
}
@Override @Override
public ElementMatcher<TypeDescription> typeMatcher() { public ElementMatcher<TypeDescription> typeMatcher() {
final ElementMatcher.Junction<TypeDescription> hasFutureInterfaceMatcher = final ElementMatcher.Junction<TypeDescription> hasFutureInterfaceMatcher =
@ -96,11 +89,6 @@ public final class FutureInstrumentation extends Instrumenter.Default {
}.and(hasFutureInterfaceMatcher); // Apply expensive matcher last. }.and(hasFutureInterfaceMatcher); // Apply expensive matcher last.
} }
@Override
public Map<String, String> contextStore() {
return singletonMap(Future.class.getName(), State.class.getName());
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(

View File

@ -0,0 +1,47 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.javaconcurrent;
import static java.util.Arrays.asList;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.instrumentation.api.concurrent.State;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.Future;
@AutoService(InstrumentationModule.class)
public class JavaConcurrentInstrumentationModule extends InstrumentationModule {
public JavaConcurrentInstrumentationModule() {
super("java_concurrent");
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return asList(
new CallableInstrumentation(),
new FutureInstrumentation(),
new JavaExecutorInstrumentation(),
new JavaForkJoinTaskInstrumentation(),
new RunnableInstrumentation());
}
@Override
public Map<String, String> contextStore() {
Map<String, String> map = new HashMap<>();
map.put(Callable.class.getName(), State.class.getName());
map.put(ForkJoinTask.class.getName(), State.class.getName());
map.put(Future.class.getName(), State.class.getName());
map.put(Runnable.class.getName(), State.class.getName());
return Collections.unmodifiableMap(map);
}
}

View File

@ -10,7 +10,6 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
@ -18,10 +17,8 @@ import io.opentelemetry.javaagent.instrumentation.api.concurrent.CallableWrapper
import io.opentelemetry.javaagent.instrumentation.api.concurrent.ExecutorInstrumentationUtils; import io.opentelemetry.javaagent.instrumentation.api.concurrent.ExecutorInstrumentationUtils;
import io.opentelemetry.javaagent.instrumentation.api.concurrent.RunnableWrapper; import io.opentelemetry.javaagent.instrumentation.api.concurrent.RunnableWrapper;
import io.opentelemetry.javaagent.instrumentation.api.concurrent.State; import io.opentelemetry.javaagent.instrumentation.api.concurrent.State;
import io.opentelemetry.javaagent.tooling.Instrumenter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
@ -31,18 +28,7 @@ import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) final class JavaExecutorInstrumentation extends AbstractExecutorInstrumentation {
public final class JavaExecutorInstrumentation extends AbstractExecutorInstrumentation {
@Override
public Map<String, String> contextStore() {
Map<String, String> map = new HashMap<>();
map.put(Runnable.class.getName(), State.class.getName());
map.put(Callable.class.getName(), State.class.getName());
map.put(ForkJoinTask.class.getName(), State.class.getName());
map.put(Future.class.getName(), State.class.getName());
return Collections.unmodifiableMap(map);
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {

View File

@ -12,15 +12,12 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not; import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
import io.opentelemetry.javaagent.instrumentation.api.concurrent.AdviceUtils; import io.opentelemetry.javaagent.instrumentation.api.concurrent.AdviceUtils;
import io.opentelemetry.javaagent.instrumentation.api.concurrent.State; import io.opentelemetry.javaagent.instrumentation.api.concurrent.State;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
@ -36,27 +33,13 @@ import net.bytebuddy.matcher.ElementMatcher;
* <p>Note: There are quite a few separate implementations of {@code ForkJoinTask}/{@code * <p>Note: There are quite a few separate implementations of {@code ForkJoinTask}/{@code
* ForkJoinPool}: JVM, Akka, Scala, Netty to name a few. This class handles JVM version. * ForkJoinPool}: JVM, Akka, Scala, Netty to name a few. This class handles JVM version.
*/ */
@AutoService(Instrumenter.class) final class JavaForkJoinTaskInstrumentation implements TypeInstrumentation {
public final class JavaForkJoinTaskInstrumentation extends Instrumenter.Default {
public JavaForkJoinTaskInstrumentation() {
super(AbstractExecutorInstrumentation.EXEC_NAME);
}
@Override @Override
public ElementMatcher<TypeDescription> typeMatcher() { public ElementMatcher<TypeDescription> typeMatcher() {
return extendsClass(named(ForkJoinTask.class.getName())); return extendsClass(named(ForkJoinTask.class.getName()));
} }
@Override
public Map<String, String> contextStore() {
Map<String, String> map = new HashMap<>();
map.put(Runnable.class.getName(), State.class.getName());
map.put(Callable.class.getName(), State.class.getName());
map.put(ForkJoinTask.class.getName(), State.class.getName());
return Collections.unmodifiableMap(map);
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(

View File

@ -1,42 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.javaconcurrent;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.instrumentation.api.concurrent.State;
import io.opentelemetry.javaagent.tooling.Instrumenter;
import java.util.HashMap;
import java.util.Map;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class)
public final class NonStandardExecutorInstrumentation extends AbstractExecutorInstrumentation {
public NonStandardExecutorInstrumentation() {
super(EXEC_NAME + ".other");
}
@Override
public Map<String, String> contextStore() {
return singletonMap(Runnable.class.getName(), State.class.getName());
}
@Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>();
transformers.put( // org.eclipse.jetty.util.thread.QueuedThreadPool
named("dispatch").and(takesArguments(1)).and(takesArgument(0, Runnable.class)),
JavaExecutorInstrumentation.class.getName() + "$SetExecuteRunnableStateAdvice");
return transformers;
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.javaconcurrent;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.instrumentation.api.concurrent.State;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
@AutoService(InstrumentationModule.class)
public final class NonStandardExecutorsInstrumentationModule extends InstrumentationModule {
public NonStandardExecutorsInstrumentationModule() {
super("java_concurrent.other");
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return singletonList(new OtherExecutorsInstrumentation());
}
@Override
public Map<String, String> contextStore() {
return singletonMap(Runnable.class.getName(), State.class.getName());
}
private static final class OtherExecutorsInstrumentation extends AbstractExecutorInstrumentation {
@Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>();
transformers.put( // org.eclipse.jetty.util.thread.QueuedThreadPool
named("dispatch").and(takesArguments(1)).and(takesArgument(0, Runnable.class)),
JavaExecutorInstrumentation.class.getName() + "$SetExecuteRunnableStateAdvice");
return transformers;
}
}
}

View File

@ -11,37 +11,25 @@ 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 static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
import io.opentelemetry.javaagent.instrumentation.api.concurrent.AdviceUtils; import io.opentelemetry.javaagent.instrumentation.api.concurrent.AdviceUtils;
import io.opentelemetry.javaagent.instrumentation.api.concurrent.State; import io.opentelemetry.javaagent.instrumentation.api.concurrent.State;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
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;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
/** Instrument {@link Runnable} and {@Callable} */ final class RunnableInstrumentation implements TypeInstrumentation {
@AutoService(Instrumenter.class)
public final class RunnableInstrumentation extends Instrumenter.Default {
public RunnableInstrumentation() {
super(AbstractExecutorInstrumentation.EXEC_NAME);
}
@Override @Override
public ElementMatcher<TypeDescription> typeMatcher() { public ElementMatcher<TypeDescription> typeMatcher() {
return implementsInterface(named(Runnable.class.getName())); return implementsInterface(named(Runnable.class.getName()));
} }
@Override
public Map<String, String> contextStore() {
return singletonMap(Runnable.class.getName(), State.class.getName());
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(

View File

@ -16,11 +16,10 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap.Depth; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap.Depth;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.net.http.HttpRequest; import java.net.http.HttpRequest;
import java.net.http.HttpResponse; import java.net.http.HttpResponse;
import java.util.HashMap; import java.util.HashMap;
@ -31,12 +30,7 @@ import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) final class HttpClientInstrumentation implements TypeInstrumentation {
public class HttpClientInstrumentation extends Instrumenter.Default {
public HttpClientInstrumentation() {
super("httpclient");
}
@Override @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() { public ElementMatcher<ClassLoader> classLoaderMatcher() {
@ -52,15 +46,6 @@ public class HttpClientInstrumentation extends Instrumenter.Default {
.and(extendsClass(named("java.net.http.HttpClient"))); .and(extendsClass(named("java.net.http.HttpClient")));
} }
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".HttpHeadersInjectAdapter",
packageName + ".JdkHttpClientTracer",
packageName + ".ResponseConsumer"
};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>(); Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>();
@ -103,7 +88,7 @@ public class HttpClientInstrumentation extends Instrumenter.Default {
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void methodExit( public static void methodExit(
@Advice.Return HttpResponse result, @Advice.Return HttpResponse<?> result,
@Advice.Thrown Throwable throwable, @Advice.Thrown Throwable throwable,
@Advice.Local("otelSpan") Span span, @Advice.Local("otelSpan") Span span,
@Advice.Local("otelScope") Scope scope, @Advice.Local("otelScope") Scope scope,

View File

@ -0,0 +1,34 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.httpclient;
import static java.util.Arrays.asList;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List;
@AutoService(InstrumentationModule.class)
public class HttpClientInstrumentationModule extends InstrumentationModule {
public HttpClientInstrumentationModule() {
super("httpclient");
}
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".HttpHeadersInjectAdapter",
packageName + ".JdkHttpClientTracer",
packageName + ".ResponseConsumer"
};
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return asList(new HttpClientInstrumentation(), new HttpHeadersInstrumentation());
}
}

View File

@ -12,9 +12,8 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith; import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.net.http.HttpHeaders; import java.net.http.HttpHeaders;
import java.util.Map; import java.util.Map;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
@ -22,12 +21,7 @@ import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) final class HttpHeadersInstrumentation implements TypeInstrumentation {
public class HttpHeadersInstrumentation extends Instrumenter.Default {
public HttpHeadersInstrumentation() {
super("httpclient");
}
@Override @Override
public ElementMatcher<TypeDescription> typeMatcher() { public ElementMatcher<TypeDescription> typeMatcher() {
@ -36,13 +30,6 @@ public class HttpHeadersInstrumentation extends Instrumenter.Default {
.and(extendsClass(named("java.net.http.HttpRequest"))); .and(extendsClass(named("java.net.http.HttpRequest")));
} }
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".HttpHeadersInjectAdapter", packageName + ".JdkHttpClientTracer"
};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(

View File

@ -10,6 +10,7 @@ import static io.opentelemetry.javaagent.instrumentation.jaxrsclient.v1_1.JaxRsC
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed; import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap; import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.returns; import static net.bytebuddy.matcher.ElementMatchers.returns;
@ -21,31 +22,22 @@ import com.sun.jersey.api.client.ClientRequest;
import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.ClientResponse;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List;
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;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) @AutoService(InstrumentationModule.class)
public final class JaxRsClientV1Instrumentation extends Instrumenter.Default { public final class JaxRsClientInstrumentationModule extends InstrumentationModule {
public JaxRsClientV1Instrumentation() { public JaxRsClientInstrumentationModule() {
super("jax-rs", "jaxrs", "jax-rs-client"); super("jax-rs", "jaxrs", "jax-rs-client");
} }
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return hasClassesNamed("com.sun.jersey.api.client.ClientHandler");
}
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return implementsInterface(named("com.sun.jersey.api.client.ClientHandler"));
}
@Override @Override
public String[] helperClassNames() { public String[] helperClassNames() {
return new String[] { return new String[] {
@ -54,12 +46,30 @@ public final class JaxRsClientV1Instrumentation extends Instrumenter.Default {
} }
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public List<TypeInstrumentation> typeInstrumentations() {
return singletonMap( return singletonList(new ClientHandlerInstrumentation());
named("handle") }
.and(takesArgument(0, extendsClass(named("com.sun.jersey.api.client.ClientRequest"))))
.and(returns(extendsClass(named("com.sun.jersey.api.client.ClientResponse")))), private static final class ClientHandlerInstrumentation implements TypeInstrumentation {
JaxRsClientV1Instrumentation.class.getName() + "$HandleAdvice"); @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return hasClassesNamed("com.sun.jersey.api.client.ClientHandler");
}
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return implementsInterface(named("com.sun.jersey.api.client.ClientHandler"));
}
@Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap(
named("handle")
.and(takesArgument(0, extendsClass(named("com.sun.jersey.api.client.ClientRequest"))))
.and(returns(extendsClass(named("com.sun.jersey.api.client.ClientResponse")))),
JaxRsClientInstrumentationModule.class.getName() + "$HandleAdvice");
}
} }
public static class HandleAdvice { public static class HandleAdvice {

View File

@ -13,8 +13,11 @@ import static net.bytebuddy.matcher.ElementMatchers.returns;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@ -30,18 +33,13 @@ import org.glassfish.jersey.client.ClientRequest;
* JAX-RS Client API doesn't define a good point where we can handle connection failures, so we must * JAX-RS Client API doesn't define a good point where we can handle connection failures, so we must
* handle these errors at the implementation level. * handle these errors at the implementation level.
*/ */
@AutoService(Instrumenter.class) @AutoService(InstrumentationModule.class)
public final class JerseyClientConnectionErrorInstrumentation extends Instrumenter.Default { public final class JerseyClientInstrumentationModule extends InstrumentationModule {
public JerseyClientConnectionErrorInstrumentation() { public JerseyClientInstrumentationModule() {
super("jax-rs", "jaxrs", "jax-rs-client"); super("jax-rs", "jaxrs", "jax-rs-client");
} }
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return named("org.glassfish.jersey.client.JerseyInvocation");
}
@Override @Override
public String[] helperClassNames() { public String[] helperClassNames() {
return new String[] { return new String[] {
@ -52,18 +50,31 @@ public final class JerseyClientConnectionErrorInstrumentation extends Instrument
} }
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public List<TypeInstrumentation> typeInstrumentations() {
Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>(); return Collections.singletonList(new JerseyClientConnectionErrorInstrumentation());
}
transformers.put( private static final class JerseyClientConnectionErrorInstrumentation
isMethod().and(isPublic()).and(named("invoke")), implements TypeInstrumentation {
JerseyClientConnectionErrorInstrumentation.class.getName() + "$InvokeAdvice"); @Override
public ElementMatcher<TypeDescription> typeMatcher() {
return named("org.glassfish.jersey.client.JerseyInvocation");
}
transformers.put( @Override
isMethod().and(isPublic()).and(named("submit")).and(returns(Future.class)), public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
JerseyClientConnectionErrorInstrumentation.class.getName() + "$SubmitAdvice"); Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>();
return transformers; transformers.put(
isMethod().and(isPublic()).and(named("invoke")),
JerseyClientInstrumentationModule.class.getName() + "$InvokeAdvice");
transformers.put(
isMethod().and(isPublic()).and(named("submit")).and(returns(Future.class)),
JerseyClientInstrumentationModule.class.getName() + "$SubmitAdvice");
return transformers;
}
} }
public static class InvokeAdvice { public static class InvokeAdvice {

View File

@ -6,6 +6,8 @@
package io.opentelemetry.javaagent.instrumentation.jaxrsclient.v2_0; package io.opentelemetry.javaagent.instrumentation.jaxrsclient.v2_0;
import static io.opentelemetry.javaagent.instrumentation.jaxrsclient.v2_0.ResteasyClientTracer.tracer; import static io.opentelemetry.javaagent.instrumentation.jaxrsclient.v2_0.ResteasyClientTracer.tracer;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
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.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
@ -14,8 +16,9 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import java.util.HashMap; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List;
import java.util.Map; import java.util.Map;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
@ -29,21 +32,16 @@ import org.jboss.resteasy.client.jaxrs.internal.ClientInvocation;
* all requests through single point. Both sync ADN async! This allows for easy instrumentation and * all requests through single point. Both sync ADN async! This allows for easy instrumentation and
* proper scope handling. * proper scope handling.
* *
* <p>This specific instrumentation will not conflict with {@link JaxRsClientInstrumentation}, * <p>This specific instrumentation will not conflict with {@link JaxRsClientInstrumentationModule},
* because {@link JaxRsClientTracer} used by the latter checks against double client spans. * because {@link JaxRsClientTracer} used by the latter checks against double client spans.
*/ */
@AutoService(Instrumenter.class) @AutoService(InstrumentationModule.class)
public final class ResteasyClientConnectionErrorInstrumentation extends Instrumenter.Default { public final class ResteasyClientInstrumentationModule extends InstrumentationModule {
public ResteasyClientConnectionErrorInstrumentation() { public ResteasyClientInstrumentationModule() {
super("jax-rs", "jaxrs", "jax-rs-client"); super("jax-rs", "jaxrs", "jax-rs-client");
} }
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return named("org.jboss.resteasy.client.jaxrs.internal.ClientInvocation");
}
@Override @Override
public String[] helperClassNames() { public String[] helperClassNames() {
return new String[] { return new String[] {
@ -52,14 +50,23 @@ public final class ResteasyClientConnectionErrorInstrumentation extends Instrume
} }
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public List<TypeInstrumentation> typeInstrumentations() {
Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>(); return singletonList(new ResteasyClientConnectionErrorInstrumentation());
}
transformers.put( private static final class ResteasyClientConnectionErrorInstrumentation
isMethod().and(isPublic()).and(named("invoke")).and(takesArguments(0)), implements TypeInstrumentation {
ResteasyClientConnectionErrorInstrumentation.class.getName() + "$InvokeAdvice"); @Override
public ElementMatcher<TypeDescription> typeMatcher() {
return named("org.jboss.resteasy.client.jaxrs.internal.ClientInvocation");
}
return transformers; @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap(
isMethod().and(isPublic()).and(named("invoke")).and(takesArguments(0)),
ResteasyClientInstrumentationModule.class.getName() + "$InvokeAdvice");
}
} }
public static class InvokeAdvice { public static class InvokeAdvice {

View File

@ -8,12 +8,15 @@ package io.opentelemetry.javaagent.instrumentation.jaxrsclient.v2_0;
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed; import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.hasInterface; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.hasInterface;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap; import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.returns; import static net.bytebuddy.matcher.ElementMatchers.returns;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List;
import java.util.Map; import java.util.Map;
import javax.ws.rs.client.Client; import javax.ws.rs.client.Client;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
@ -22,24 +25,13 @@ import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.implementation.bytecode.assign.Assigner; import net.bytebuddy.implementation.bytecode.assign.Assigner;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) @AutoService(InstrumentationModule.class)
public final class JaxRsClientInstrumentation extends Instrumenter.Default { public final class JaxRsClientInstrumentationModule extends InstrumentationModule {
public JaxRsClientInstrumentation() { public JaxRsClientInstrumentationModule() {
super("jax-rs", "jaxrs", "jax-rs-client"); super("jax-rs", "jaxrs", "jax-rs-client");
} }
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return hasClassesNamed("javax.ws.rs.client.ClientBuilder");
}
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return extendsClass(named("javax.ws.rs.client.ClientBuilder"));
}
@Override @Override
public String[] helperClassNames() { public String[] helperClassNames() {
return new String[] { return new String[] {
@ -51,10 +43,28 @@ public final class JaxRsClientInstrumentation extends Instrumenter.Default {
} }
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public List<TypeInstrumentation> typeInstrumentations() {
return singletonMap( return singletonList(new ClientBuilderInstrumentation());
named("build").and(returns(hasInterface(named("javax.ws.rs.client.Client")))), }
JaxRsClientInstrumentation.class.getName() + "$ClientBuilderAdvice");
private static final class ClientBuilderInstrumentation implements TypeInstrumentation {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return hasClassesNamed("javax.ws.rs.client.ClientBuilder");
}
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return extendsClass(named("javax.ws.rs.client.ClientBuilder"));
}
@Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap(
named("build").and(returns(hasInterface(named("javax.ws.rs.client.Client")))),
JaxRsClientInstrumentationModule.class.getName() + "$ClientBuilderAdvice");
}
} }
public static class ClientBuilderAdvice { public static class ClientBuilderAdvice {

View File

@ -15,13 +15,11 @@ import static net.bytebuddy.matcher.ElementMatchers.declaresMethod;
import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith; import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith;
import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Map; import java.util.Map;
import javax.ws.rs.Path; import javax.ws.rs.Path;
@ -30,19 +28,12 @@ import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) final class JaxRsAnnotationsInstrumentation implements TypeInstrumentation {
public final class JaxRsAnnotationsInstrumentation extends Instrumenter.Default {
public JaxRsAnnotationsInstrumentation() {
super("jax-rs", "jaxrs", "jax-rs-annotations");
}
// this is required to make sure instrumentation won't apply to jax-rs 2
@Override @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() { public ElementMatcher<ClassLoader> classLoaderMatcher() {
return not(hasClassesNamed("javax.ws.rs.container.AsyncResponse")) // Optimization for expensive typeMatcher.
// Optimization for expensive typeMatcher. return hasClassesNamed("javax.ws.rs.Path");
.and(hasClassesNamed("javax.ws.rs.Path"));
} }
@Override @Override
@ -52,15 +43,6 @@ public final class JaxRsAnnotationsInstrumentation extends Instrumenter.Default
.<TypeDescription>or(declaresMethod(isAnnotatedWith(named("javax.ws.rs.Path"))))); .<TypeDescription>or(declaresMethod(isAnnotatedWith(named("javax.ws.rs.Path")))));
} }
@Override
public String[] helperClassNames() {
return new String[] {
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable",
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable$ClassIterator",
packageName + ".JaxRsAnnotationsTracer",
};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(

View File

@ -0,0 +1,43 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.jaxrs.v1_0;
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static java.util.Collections.singletonList;
import static net.bytebuddy.matcher.ElementMatchers.not;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List;
import net.bytebuddy.matcher.ElementMatcher;
@AutoService(InstrumentationModule.class)
public class JaxRsInstrumentationModule extends InstrumentationModule {
public JaxRsInstrumentationModule() {
super("jax-rs", "jaxrs");
}
// this is required to make sure instrumentation won't apply to jax-rs 2
@Override
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
return not(hasClassesNamed("javax.ws.rs.container.AsyncResponse"));
}
@Override
public String[] helperClassNames() {
return new String[] {
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable",
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable$ClassIterator",
packageName + ".JaxRsAnnotationsTracer",
};
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return singletonList(new JaxRsAnnotationsInstrumentation());
}
}

View File

@ -5,7 +5,6 @@
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0; package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
import static io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0.JaxRsAnnotationsTracer.tracer;
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed; import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static java.util.Collections.singletonMap; import static java.util.Collections.singletonMap;
@ -14,24 +13,13 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
import io.opentelemetry.javaagent.tooling.Instrumenter;
import java.lang.reflect.Method;
import java.util.Map; import java.util.Map;
import javax.ws.rs.container.ContainerRequestContext;
import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
public abstract class AbstractRequestContextInstrumentation extends Instrumenter.Default { public abstract class AbstractRequestContextInstrumentation implements TypeInstrumentation {
public AbstractRequestContextInstrumentation() {
super("jax-rs", "jaxrs", "jax-rs-filter");
}
@Override @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() { public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher. // Optimization for expensive typeMatcher.
@ -43,16 +31,6 @@ public abstract class AbstractRequestContextInstrumentation extends Instrumenter
return implementsInterface(named("javax.ws.rs.container.ContainerRequestContext")); return implementsInterface(named("javax.ws.rs.container.ContainerRequestContext"));
} }
@Override
public String[] helperClassNames() {
return new String[] {
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable",
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable$ClassIterator",
packageName + ".JaxRsAnnotationsTracer",
AbstractRequestContextInstrumentation.class.getName() + "$RequestFilterHelper",
};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(
@ -60,44 +38,8 @@ public abstract class AbstractRequestContextInstrumentation extends Instrumenter
.and(named("abortWith")) .and(named("abortWith"))
.and(takesArguments(1)) .and(takesArguments(1))
.and(takesArgument(0, named("javax.ws.rs.core.Response"))), .and(takesArgument(0, named("javax.ws.rs.core.Response"))),
getClass().getName() + "$ContainerRequestContextAdvice"); abortAdviceName());
} }
public static class RequestFilterHelper { protected abstract String abortAdviceName();
public static Span createOrUpdateAbortSpan(
ContainerRequestContext requestContext, Class<?> resourceClass, Method method) {
if (method != null && resourceClass != null) {
requestContext.setProperty(JaxRsAnnotationsTracer.ABORT_HANDLED, true);
Context context = Java8BytecodeBridge.currentContext();
Span serverSpan = BaseTracer.getCurrentServerSpan(context);
Span currentSpan = Java8BytecodeBridge.spanFromContext(context);
// if there's no current span or it's the same as the server (servlet) span we need to start
// a JAX-RS one
// in other case, DefaultRequestContextInstrumentation must have already run so it's enough
// to just update the names
if (currentSpan == null || currentSpan == serverSpan) {
return tracer().startSpan(resourceClass, method);
} else {
tracer().updateSpanNames(context, currentSpan, serverSpan, resourceClass, method);
}
}
return null;
}
public static void closeSpanAndScope(Span span, Scope scope, Throwable throwable) {
if (span == null || scope == null) {
return;
}
if (throwable != null) {
tracer().endExceptionally(span, throwable);
} else {
tracer().end(span);
}
scope.close();
}
}
} }

View File

@ -13,8 +13,7 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import io.opentelemetry.javaagent.tooling.Instrumenter;
import java.util.Map; import java.util.Map;
import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.container.ContainerRequestFilter;
@ -27,12 +26,7 @@ import net.bytebuddy.matcher.ElementMatcher;
* This adds the filter class name to the request properties. The class name is used by <code> * This adds the filter class name to the request properties. The class name is used by <code>
* DefaultRequestContextInstrumentation</code> * DefaultRequestContextInstrumentation</code>
*/ */
@AutoService(Instrumenter.class) class ContainerRequestFilterInstrumentation implements TypeInstrumentation {
public class ContainerRequestFilterInstrumentation extends Instrumenter.Default {
public ContainerRequestFilterInstrumentation() {
super("jax-rs", "jaxrs", "jax-rs-filter");
}
@Override @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() { public ElementMatcher<ClassLoader> classLoaderMatcher() {

View File

@ -7,10 +7,8 @@ package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
import static io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0.JaxRsAnnotationsTracer.tracer; import static io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0.JaxRsAnnotationsTracer.tracer;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.tooling.Instrumenter;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestContext;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
@ -25,8 +23,12 @@ import net.bytebuddy.asm.Advice.Local;
* <p>This default instrumentation uses the class name of the filter to create the span. More * <p>This default instrumentation uses the class name of the filter to create the span. More
* specific instrumentations may override this value. * specific instrumentations may override this value.
*/ */
@AutoService(Instrumenter.class) final class DefaultRequestContextInstrumentation extends AbstractRequestContextInstrumentation {
public class DefaultRequestContextInstrumentation extends AbstractRequestContextInstrumentation { @Override
protected String abortAdviceName() {
return ContainerRequestContextAdvice.class.getName();
}
public static class ContainerRequestContextAdvice { public static class ContainerRequestContextAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class) @Advice.OnMethodEnter(suppress = Throwable.class)
public static void createGenericSpan( public static void createGenericSpan(
@ -54,7 +56,7 @@ public class DefaultRequestContextInstrumentation extends AbstractRequestContext
@Local("otelSpan") Span span, @Local("otelSpan") Span span,
@Local("otelScope") Scope scope, @Local("otelScope") Scope scope,
@Advice.Thrown Throwable throwable) { @Advice.Thrown Throwable throwable) {
RequestFilterHelper.closeSpanAndScope(span, scope, throwable); RequestContextHelper.closeSpanAndScope(span, scope, throwable);
} }
} }
} }

View File

@ -16,13 +16,12 @@ import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith;
import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletionStage; import java.util.concurrent.CompletionStage;
@ -34,17 +33,7 @@ import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.implementation.bytecode.assign.Assigner.Typing; import net.bytebuddy.implementation.bytecode.assign.Assigner.Typing;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) final class JaxRsAnnotationsInstrumentation implements TypeInstrumentation {
public final class JaxRsAnnotationsInstrumentation extends Instrumenter.Default {
public JaxRsAnnotationsInstrumentation() {
super("jax-rs", "jaxrs", "jax-rs-annotations");
}
@Override
public Map<String, String> contextStore() {
return singletonMap("javax.ws.rs.container.AsyncResponse", Span.class.getName());
}
@Override @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() { public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher. // Optimization for expensive typeMatcher.
@ -58,16 +47,6 @@ public final class JaxRsAnnotationsInstrumentation extends Instrumenter.Default
.<TypeDescription>or(declaresMethod(isAnnotatedWith(named("javax.ws.rs.Path"))))); .<TypeDescription>or(declaresMethod(isAnnotatedWith(named("javax.ws.rs.Path")))));
} }
@Override
public String[] helperClassNames() {
return new String[] {
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable",
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable$ClassIterator",
packageName + ".JaxRsAnnotationsTracer",
packageName + ".CompletionStageFinishCallback"
};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(

View File

@ -8,16 +8,14 @@ package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
import static io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0.JaxRsAnnotationsTracer.tracer; import static io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0.JaxRsAnnotationsTracer.tracer;
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed; import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isPublic; 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.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.ws.rs.container.AsyncResponse; import javax.ws.rs.container.AsyncResponse;
@ -26,17 +24,7 @@ import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) final class JaxRsAsyncResponseInstrumentation implements TypeInstrumentation {
public final class JaxRsAsyncResponseInstrumentation extends Instrumenter.Default {
public JaxRsAsyncResponseInstrumentation() {
super("jax-rs", "jaxrs", "jax-rs-annotations");
}
@Override
public Map<String, String> contextStore() {
return singletonMap("javax.ws.rs.container.AsyncResponse", Span.class.getName());
}
@Override @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() { public ElementMatcher<ClassLoader> classLoaderMatcher() {
@ -49,15 +37,6 @@ public final class JaxRsAsyncResponseInstrumentation extends Instrumenter.Defaul
return implementsInterface(named("javax.ws.rs.container.AsyncResponse")); return implementsInterface(named("javax.ws.rs.container.AsyncResponse"));
} }
@Override
public String[] helperClassNames() {
return new String[] {
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable",
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable$ClassIterator",
packageName + ".JaxRsAnnotationsTracer",
};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>(); Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>();

View File

@ -0,0 +1,56 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonMap;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List;
import java.util.Map;
import net.bytebuddy.matcher.ElementMatcher;
@AutoService(InstrumentationModule.class)
public class JaxRsInstrumentationModule extends InstrumentationModule {
public JaxRsInstrumentationModule() {
super("jax-rs", "jaxrs");
}
// require jax-rs 2
@Override
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
return hasClassesNamed("javax.ws.rs.container.AsyncResponse");
}
@Override
public String[] helperClassNames() {
return new String[] {
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable",
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable$ClassIterator",
packageName + ".JaxRsAnnotationsTracer",
packageName + ".CompletionStageFinishCallback",
packageName + ".RequestContextHelper"
};
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return asList(
new ContainerRequestFilterInstrumentation(),
new DefaultRequestContextInstrumentation(),
new JaxRsAnnotationsInstrumentation(),
new JaxRsAsyncResponseInstrumentation());
}
@Override
public Map<String, String> contextStore() {
return singletonMap("javax.ws.rs.container.AsyncResponse", Span.class.getName());
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
import static io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0.JaxRsAnnotationsTracer.tracer;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
import java.lang.reflect.Method;
import javax.ws.rs.container.ContainerRequestContext;
public final class RequestContextHelper {
public static Span createOrUpdateAbortSpan(
ContainerRequestContext requestContext, Class<?> resourceClass, Method method) {
if (method != null && resourceClass != null) {
requestContext.setProperty(JaxRsAnnotationsTracer.ABORT_HANDLED, true);
Context context = Java8BytecodeBridge.currentContext();
Span serverSpan = BaseTracer.getCurrentServerSpan(context);
Span currentSpan = Java8BytecodeBridge.spanFromContext(context);
// if there's no current span or it's the same as the server (servlet) span we need to start
// a JAX-RS one
// in other case, DefaultRequestContextInstrumentation must have already run so it's enough
// to just update the names
if (currentSpan == null || currentSpan == serverSpan) {
return tracer().startSpan(resourceClass, method);
} else {
tracer().updateSpanNames(context, currentSpan, serverSpan, resourceClass, method);
}
}
return null;
}
public static void closeSpanAndScope(Span span, Scope scope, Throwable throwable) {
if (span == null || scope == null) {
return;
}
if (throwable != null) {
tracer().endExceptionally(span, throwable);
} else {
tracer().end(span);
}
scope.close();
}
private RequestContextHelper() {}
}

View File

@ -0,0 +1,34 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Collections;
import java.util.List;
@AutoService(InstrumentationModule.class)
public class JerseyInstrumentationModule extends InstrumentationModule {
public JerseyInstrumentationModule() {
super("jax-rs", "jaxrs", "jersey");
}
@Override
public String[] helperClassNames() {
return new String[] {
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable",
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable$ClassIterator",
packageName + ".JaxRsAnnotationsTracer",
packageName + ".RequestContextHelper"
};
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return Collections.singletonList(new JerseyRequestContextInstrumentation());
}
}

View File

@ -7,10 +7,8 @@ package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
import static io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0.JaxRsAnnotationsTracer.tracer; import static io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0.JaxRsAnnotationsTracer.tracer;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.tooling.Instrumenter;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ResourceInfo; import javax.ws.rs.container.ResourceInfo;
@ -27,8 +25,12 @@ import net.bytebuddy.asm.Advice.Local;
* <p>In the Jersey implementation, <code>UriInfo</code> implements <code>ResourceInfo</code>. The * <p>In the Jersey implementation, <code>UriInfo</code> implements <code>ResourceInfo</code>. The
* matched resource method can be retrieved from that object * matched resource method can be retrieved from that object
*/ */
@AutoService(Instrumenter.class) final class JerseyRequestContextInstrumentation extends AbstractRequestContextInstrumentation {
public class JerseyRequestContextInstrumentation extends AbstractRequestContextInstrumentation { @Override
protected String abortAdviceName() {
return ContainerRequestContextAdvice.class.getName();
}
public static class ContainerRequestContextAdvice { public static class ContainerRequestContextAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class) @Advice.OnMethodEnter(suppress = Throwable.class)
public static void decorateAbortSpan( public static void decorateAbortSpan(
@ -44,7 +46,7 @@ public class JerseyRequestContextInstrumentation extends AbstractRequestContextI
Method method = resourceInfo.getResourceMethod(); Method method = resourceInfo.getResourceMethod();
Class<?> resourceClass = resourceInfo.getResourceClass(); Class<?> resourceClass = resourceInfo.getResourceClass();
span = RequestFilterHelper.createOrUpdateAbortSpan(context, resourceClass, method); span = RequestContextHelper.createOrUpdateAbortSpan(context, resourceClass, method);
if (span != null) { if (span != null) {
scope = tracer().startScope(span); scope = tracer().startScope(span);
} }
@ -56,7 +58,7 @@ public class JerseyRequestContextInstrumentation extends AbstractRequestContextI
@Local("otelSpan") Span span, @Local("otelSpan") Span span,
@Local("otelScope") Scope scope, @Local("otelScope") Scope scope,
@Advice.Thrown Throwable throwable) { @Advice.Thrown Throwable throwable) {
RequestFilterHelper.closeSpanAndScope(span, scope, throwable); RequestContextHelper.closeSpanAndScope(span, scope, throwable);
} }
} }
} }

View File

@ -0,0 +1,34 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Collections;
import java.util.List;
@AutoService(InstrumentationModule.class)
public class Resteasy30InstrumentationModule extends InstrumentationModule {
public Resteasy30InstrumentationModule() {
super("jax-rs", "jaxrs", "resteasy");
}
@Override
public String[] helperClassNames() {
return new String[] {
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable",
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable$ClassIterator",
packageName + ".JaxRsAnnotationsTracer",
packageName + ".RequestContextHelper"
};
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return Collections.singletonList(new Resteasy30RequestContextInstrumentation());
}
}

View File

@ -7,10 +7,8 @@ package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
import static io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0.JaxRsAnnotationsTracer.tracer; import static io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0.JaxRsAnnotationsTracer.tracer;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.tooling.Instrumenter;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestContext;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
@ -28,8 +26,12 @@ import org.jboss.resteasy.core.interception.PostMatchContainerRequestContext;
* PostMatchContainerRequestContext</code>. This class provides a way to get the matched resource * PostMatchContainerRequestContext</code>. This class provides a way to get the matched resource
* method through <code>getResourceMethod()</code>. * method through <code>getResourceMethod()</code>.
*/ */
@AutoService(Instrumenter.class) final class Resteasy30RequestContextInstrumentation extends AbstractRequestContextInstrumentation {
public class Resteasy30RequestContextInstrumentation extends AbstractRequestContextInstrumentation { @Override
protected String abortAdviceName() {
return ContainerRequestContextAdvice.class.getName();
}
public static class ContainerRequestContextAdvice { public static class ContainerRequestContextAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class) @Advice.OnMethodEnter(suppress = Throwable.class)
public static void decorateAbortSpan( public static void decorateAbortSpan(
@ -44,7 +46,7 @@ public class Resteasy30RequestContextInstrumentation extends AbstractRequestCont
Method method = resourceMethodInvoker.getMethod(); Method method = resourceMethodInvoker.getMethod();
Class<?> resourceClass = resourceMethodInvoker.getResourceClass(); Class<?> resourceClass = resourceMethodInvoker.getResourceClass();
span = RequestFilterHelper.createOrUpdateAbortSpan(context, resourceClass, method); span = RequestContextHelper.createOrUpdateAbortSpan(context, resourceClass, method);
if (span != null) { if (span != null) {
scope = tracer().startScope(span); scope = tracer().startScope(span);
} }
@ -56,7 +58,7 @@ public class Resteasy30RequestContextInstrumentation extends AbstractRequestCont
@Local("otelSpan") Span span, @Local("otelSpan") Span span,
@Local("otelScope") Scope scope, @Local("otelScope") Scope scope,
@Advice.Thrown Throwable throwable) { @Advice.Thrown Throwable throwable) {
RequestFilterHelper.closeSpanAndScope(span, scope, throwable); RequestContextHelper.closeSpanAndScope(span, scope, throwable);
} }
} }
} }

View File

@ -0,0 +1,34 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Collections;
import java.util.List;
@AutoService(InstrumentationModule.class)
public class Resteasy31InstrumentationModule extends InstrumentationModule {
public Resteasy31InstrumentationModule() {
super("jax-rs", "jaxrs", "resteasy");
}
@Override
public String[] helperClassNames() {
return new String[] {
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable",
"io.opentelemetry.javaagent.tooling.ClassHierarchyIterable$ClassIterator",
packageName + ".JaxRsAnnotationsTracer",
packageName + ".RequestContextHelper"
};
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return Collections.singletonList(new Resteasy31RequestContextInstrumentation());
}
}

View File

@ -7,10 +7,8 @@ package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
import static io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0.JaxRsAnnotationsTracer.tracer; import static io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0.JaxRsAnnotationsTracer.tracer;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.tooling.Instrumenter;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestContext;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
@ -28,8 +26,12 @@ import org.jboss.resteasy.core.interception.jaxrs.PostMatchContainerRequestConte
* PostMatchContainerRequestContext</code>. This class provides a way to get the matched resource * PostMatchContainerRequestContext</code>. This class provides a way to get the matched resource
* method through <code>getResourceMethod()</code>. * method through <code>getResourceMethod()</code>.
*/ */
@AutoService(Instrumenter.class) final class Resteasy31RequestContextInstrumentation extends AbstractRequestContextInstrumentation {
public class Resteasy31RequestContextInstrumentation extends AbstractRequestContextInstrumentation { @Override
protected String abortAdviceName() {
return ContainerRequestContextAdvice.class.getName();
}
public static class ContainerRequestContextAdvice { public static class ContainerRequestContextAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class) @Advice.OnMethodEnter(suppress = Throwable.class)
public static void decorateAbortSpan( public static void decorateAbortSpan(
@ -44,7 +46,7 @@ public class Resteasy31RequestContextInstrumentation extends AbstractRequestCont
Method method = resourceMethodInvoker.getMethod(); Method method = resourceMethodInvoker.getMethod();
Class<?> resourceClass = resourceMethodInvoker.getResourceClass(); Class<?> resourceClass = resourceMethodInvoker.getResourceClass();
span = RequestFilterHelper.createOrUpdateAbortSpan(context, resourceClass, method); span = RequestContextHelper.createOrUpdateAbortSpan(context, resourceClass, method);
if (span != null) { if (span != null) {
scope = tracer().startScope(span); scope = tracer().startScope(span);
} }
@ -56,7 +58,7 @@ public class Resteasy31RequestContextInstrumentation extends AbstractRequestCont
@Local("otelSpan") Span span, @Local("otelSpan") Span span,
@Local("otelScope") Scope scope, @Local("otelScope") Scope scope,
@Advice.Thrown Throwable throwable) { @Advice.Thrown Throwable throwable) {
RequestFilterHelper.closeSpanAndScope(span, scope, throwable); RequestContextHelper.closeSpanAndScope(span, scope, throwable);
} }
} }
} }

View File

@ -14,8 +14,7 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.returns; import static net.bytebuddy.matcher.ElementMatchers.returns;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import io.opentelemetry.javaagent.tooling.Instrumenter;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.util.Map; import java.util.Map;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
@ -23,12 +22,7 @@ import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) final class ConnectionInstrumentation implements TypeInstrumentation {
public final class ConnectionInstrumentation extends Instrumenter.Default {
public ConnectionInstrumentation() {
super("jdbc");
}
@Override @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() { public ElementMatcher<ClassLoader> classLoaderMatcher() {
@ -40,36 +34,6 @@ public final class ConnectionInstrumentation extends Instrumenter.Default {
return implementsInterface(named("java.sql.Connection")); return implementsInterface(named("java.sql.Connection"));
} }
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".DataSourceTracer",
packageName + ".DBInfo",
packageName + ".DBInfo$Builder",
packageName + ".JDBCConnectionUrlParser",
packageName + ".JDBCConnectionUrlParser$1",
packageName + ".JDBCConnectionUrlParser$2",
packageName + ".JDBCConnectionUrlParser$3",
packageName + ".JDBCConnectionUrlParser$4",
packageName + ".JDBCConnectionUrlParser$5",
packageName + ".JDBCConnectionUrlParser$6",
packageName + ".JDBCConnectionUrlParser$7",
packageName + ".JDBCConnectionUrlParser$8",
packageName + ".JDBCConnectionUrlParser$9",
packageName + ".JDBCConnectionUrlParser$10",
packageName + ".JDBCConnectionUrlParser$11",
packageName + ".JDBCConnectionUrlParser$12",
packageName + ".JDBCConnectionUrlParser$13",
packageName + ".JDBCConnectionUrlParser$14",
packageName + ".JDBCConnectionUrlParser$15",
packageName + ".JDBCConnectionUrlParser$16",
packageName + ".JDBCConnectionUrlParser$17",
packageName + ".JDBCMaps",
packageName + ".JdbcTracer",
packageName + ".JDBCUtils",
};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(

View File

@ -13,8 +13,7 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.returns; import static net.bytebuddy.matcher.ElementMatchers.returns;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import io.opentelemetry.javaagent.tooling.Instrumenter;
import java.sql.Connection; import java.sql.Connection;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@ -23,12 +22,7 @@ import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) final class DriverInstrumentation implements TypeInstrumentation {
public final class DriverInstrumentation extends Instrumenter.Default {
public DriverInstrumentation() {
super("jdbc");
}
@Override @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() { public ElementMatcher<ClassLoader> classLoaderMatcher() {
@ -40,34 +34,6 @@ public final class DriverInstrumentation extends Instrumenter.Default {
return implementsInterface(named("java.sql.Driver")); return implementsInterface(named("java.sql.Driver"));
} }
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".DBInfo",
packageName + ".DBInfo$Builder",
packageName + ".JDBCConnectionUrlParser",
packageName + ".JDBCConnectionUrlParser$1",
packageName + ".JDBCConnectionUrlParser$2",
packageName + ".JDBCConnectionUrlParser$3",
packageName + ".JDBCConnectionUrlParser$4",
packageName + ".JDBCConnectionUrlParser$5",
packageName + ".JDBCConnectionUrlParser$6",
packageName + ".JDBCConnectionUrlParser$7",
packageName + ".JDBCConnectionUrlParser$8",
packageName + ".JDBCConnectionUrlParser$9",
packageName + ".JDBCConnectionUrlParser$10",
packageName + ".JDBCConnectionUrlParser$11",
packageName + ".JDBCConnectionUrlParser$12",
packageName + ".JDBCConnectionUrlParser$13",
packageName + ".JDBCConnectionUrlParser$14",
packageName + ".JDBCConnectionUrlParser$15",
packageName + ".JDBCConnectionUrlParser$16",
packageName + ".JDBCConnectionUrlParser$17",
packageName + ".JDBCMaps",
packageName + ".JDBCUtils",
};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(

View File

@ -8,6 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.jdbc;
import static io.opentelemetry.api.trace.Span.Kind.CLIENT; import static io.opentelemetry.api.trace.Span.Kind.CLIENT;
import static io.opentelemetry.javaagent.instrumentation.jdbc.DataSourceTracer.tracer; import static io.opentelemetry.javaagent.instrumentation.jdbc.DataSourceTracer.tracer;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap; import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
@ -15,7 +16,9 @@ import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List;
import java.util.Map; import java.util.Map;
import javax.sql.DataSource; import javax.sql.DataSource;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
@ -23,17 +26,12 @@ import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) @AutoService(InstrumentationModule.class)
public final class DataSourceInstrumentation extends Instrumenter.Default { public final class JdbcDataSourceInstrumentationModule extends InstrumentationModule {
public DataSourceInstrumentation() { public JdbcDataSourceInstrumentationModule() {
super("jdbc-datasource"); super("jdbc-datasource");
} }
@Override
public boolean defaultEnabled() {
return false;
}
@Override @Override
public String[] helperClassNames() { public String[] helperClassNames() {
return new String[] { return new String[] {
@ -64,13 +62,25 @@ public final class DataSourceInstrumentation extends Instrumenter.Default {
} }
@Override @Override
public ElementMatcher<TypeDescription> typeMatcher() { public List<TypeInstrumentation> typeInstrumentations() {
return implementsInterface(named("javax.sql.DataSource")); return singletonList(new DataSourceInstrumentation());
} }
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public boolean defaultEnabled() {
return singletonMap(named("getConnection"), GetConnectionAdvice.class.getName()); return false;
}
private static final class DataSourceInstrumentation implements TypeInstrumentation {
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return implementsInterface(named("javax.sql.DataSource"));
}
@Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap(named("getConnection"), GetConnectionAdvice.class.getName());
}
} }
public static class GetConnectionAdvice { public static class GetConnectionAdvice {

View File

@ -0,0 +1,58 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.jdbc;
import static java.util.Arrays.asList;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List;
@AutoService(InstrumentationModule.class)
public class JdbcInstrumentationModule extends InstrumentationModule {
public JdbcInstrumentationModule() {
super("jdbc");
}
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".DBInfo",
packageName + ".DBInfo$Builder",
packageName + ".JDBCConnectionUrlParser",
packageName + ".JDBCConnectionUrlParser$1",
packageName + ".JDBCConnectionUrlParser$2",
packageName + ".JDBCConnectionUrlParser$3",
packageName + ".JDBCConnectionUrlParser$4",
packageName + ".JDBCConnectionUrlParser$5",
packageName + ".JDBCConnectionUrlParser$6",
packageName + ".JDBCConnectionUrlParser$7",
packageName + ".JDBCConnectionUrlParser$8",
packageName + ".JDBCConnectionUrlParser$9",
packageName + ".JDBCConnectionUrlParser$10",
packageName + ".JDBCConnectionUrlParser$11",
packageName + ".JDBCConnectionUrlParser$12",
packageName + ".JDBCConnectionUrlParser$13",
packageName + ".JDBCConnectionUrlParser$14",
packageName + ".JDBCConnectionUrlParser$15",
packageName + ".JDBCConnectionUrlParser$16",
packageName + ".JDBCConnectionUrlParser$17",
packageName + ".JDBCMaps",
packageName + ".JdbcTracer",
packageName + ".JDBCUtils",
};
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return asList(
new ConnectionInstrumentation(),
new DriverInstrumentation(),
new PreparedStatementInstrumentation(),
new StatementInstrumentation());
}
}

View File

@ -14,11 +14,10 @@ import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap.Depth; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap.Depth;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.util.Map; import java.util.Map;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
@ -26,12 +25,7 @@ import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) final class PreparedStatementInstrumentation implements TypeInstrumentation {
public final class PreparedStatementInstrumentation extends Instrumenter.Default {
public PreparedStatementInstrumentation() {
super("jdbc");
}
@Override @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() { public ElementMatcher<ClassLoader> classLoaderMatcher() {
@ -43,36 +37,6 @@ public final class PreparedStatementInstrumentation extends Instrumenter.Default
return implementsInterface(named("java.sql.PreparedStatement")); return implementsInterface(named("java.sql.PreparedStatement"));
} }
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".DataSourceTracer",
packageName + ".DBInfo",
packageName + ".DBInfo$Builder",
packageName + ".JDBCConnectionUrlParser",
packageName + ".JDBCConnectionUrlParser$1",
packageName + ".JDBCConnectionUrlParser$2",
packageName + ".JDBCConnectionUrlParser$3",
packageName + ".JDBCConnectionUrlParser$4",
packageName + ".JDBCConnectionUrlParser$5",
packageName + ".JDBCConnectionUrlParser$6",
packageName + ".JDBCConnectionUrlParser$7",
packageName + ".JDBCConnectionUrlParser$8",
packageName + ".JDBCConnectionUrlParser$9",
packageName + ".JDBCConnectionUrlParser$10",
packageName + ".JDBCConnectionUrlParser$11",
packageName + ".JDBCConnectionUrlParser$12",
packageName + ".JDBCConnectionUrlParser$13",
packageName + ".JDBCConnectionUrlParser$14",
packageName + ".JDBCConnectionUrlParser$15",
packageName + ".JDBCConnectionUrlParser$16",
packageName + ".JDBCConnectionUrlParser$17",
packageName + ".JDBCMaps",
packageName + ".JdbcTracer",
packageName + ".JDBCUtils",
};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(

View File

@ -14,11 +14,10 @@ import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap.Depth; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap.Depth;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.sql.Statement; import java.sql.Statement;
import java.util.Map; import java.util.Map;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
@ -26,12 +25,7 @@ import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) final class StatementInstrumentation implements TypeInstrumentation {
public final class StatementInstrumentation extends Instrumenter.Default {
public StatementInstrumentation() {
super("jdbc");
}
@Override @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() { public ElementMatcher<ClassLoader> classLoaderMatcher() {
@ -43,36 +37,6 @@ public final class StatementInstrumentation extends Instrumenter.Default {
return implementsInterface(named("java.sql.Statement")); return implementsInterface(named("java.sql.Statement"));
} }
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".DataSourceTracer",
packageName + ".DBInfo",
packageName + ".DBInfo$Builder",
packageName + ".JDBCConnectionUrlParser",
packageName + ".JDBCConnectionUrlParser$1",
packageName + ".JDBCConnectionUrlParser$2",
packageName + ".JDBCConnectionUrlParser$3",
packageName + ".JDBCConnectionUrlParser$4",
packageName + ".JDBCConnectionUrlParser$5",
packageName + ".JDBCConnectionUrlParser$6",
packageName + ".JDBCConnectionUrlParser$7",
packageName + ".JDBCConnectionUrlParser$8",
packageName + ".JDBCConnectionUrlParser$9",
packageName + ".JDBCConnectionUrlParser$10",
packageName + ".JDBCConnectionUrlParser$11",
packageName + ".JDBCConnectionUrlParser$12",
packageName + ".JDBCConnectionUrlParser$13",
packageName + ".JDBCConnectionUrlParser$14",
packageName + ".JDBCConnectionUrlParser$15",
packageName + ".JDBCConnectionUrlParser$16",
packageName + ".JDBCConnectionUrlParser$17",
packageName + ".JDBCMaps",
packageName + ".JdbcTracer",
packageName + ".JDBCUtils",
};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(

View File

@ -7,6 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.jedis.v1_4;
import static io.opentelemetry.javaagent.instrumentation.jedis.v1_4.JedisClientTracer.tracer; import static io.opentelemetry.javaagent.instrumentation.jedis.v1_4.JedisClientTracer.tracer;
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed; import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static java.util.Collections.singletonList;
import static net.bytebuddy.matcher.ElementMatchers.is; import static net.bytebuddy.matcher.ElementMatchers.is;
import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
@ -19,8 +20,10 @@ import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
import io.opentelemetry.javaagent.instrumentation.jedis.v1_4.JedisClientTracer.CommandWithArgs; import io.opentelemetry.javaagent.instrumentation.jedis.v1_4.JedisClientTracer.CommandWithArgs;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
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;
@ -29,24 +32,19 @@ import net.bytebuddy.matcher.ElementMatcher;
import redis.clients.jedis.Connection; import redis.clients.jedis.Connection;
import redis.clients.jedis.Protocol.Command; import redis.clients.jedis.Protocol.Command;
@AutoService(Instrumenter.class) @AutoService(InstrumentationModule.class)
public final class JedisInstrumentation extends Instrumenter.Default { public final class JedisInstrumentationModule extends InstrumentationModule {
public JedisInstrumentation() { public JedisInstrumentationModule() {
super("jedis", "redis"); super("jedis", "redis");
} }
@Override @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() { public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
// Avoid matching 3.x // Avoid matching 3.x
return not(hasClassesNamed("redis.clients.jedis.commands.ProtocolCommand")); return not(hasClassesNamed("redis.clients.jedis.commands.ProtocolCommand"));
} }
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return named("redis.clients.jedis.Connection");
}
@Override @Override
public String[] helperClassNames() { public String[] helperClassNames() {
return new String[] { return new String[] {
@ -55,23 +53,36 @@ public final class JedisInstrumentation extends Instrumenter.Default {
} }
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public List<TypeInstrumentation> typeInstrumentations() {
// FIXME: This instrumentation only incorporates sending the command, not processing the result. return singletonList(new ConnectionInstrumentation());
Map<ElementMatcher.Junction<MethodDescription>, String> transformers = new HashMap<>(); }
transformers.put(
isMethod() private static final class ConnectionInstrumentation implements TypeInstrumentation {
.and(named("sendCommand")) @Override
.and(takesArguments(1)) public ElementMatcher<TypeDescription> typeMatcher() {
.and(takesArgument(0, named("redis.clients.jedis.Protocol$Command"))), return named("redis.clients.jedis.Connection");
JedisInstrumentation.class.getName() + "$JedisNoArgsAdvice"); }
transformers.put(
isMethod() @Override
.and(named("sendCommand")) public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
.and(takesArguments(2)) // FIXME: This instrumentation only incorporates sending the command, not processing the
.and(takesArgument(0, named("redis.clients.jedis.Protocol$Command"))) // result.
.and(takesArgument(1, is(byte[][].class))), Map<ElementMatcher.Junction<MethodDescription>, String> transformers = new HashMap<>();
JedisInstrumentation.class.getName() + "$JedisArgsAdvice"); transformers.put(
return transformers; isMethod()
.and(named("sendCommand"))
.and(takesArguments(1))
.and(takesArgument(0, named("redis.clients.jedis.Protocol$Command"))),
JedisInstrumentationModule.class.getName() + "$JedisNoArgsAdvice");
transformers.put(
isMethod()
.and(named("sendCommand"))
.and(takesArguments(2))
.and(takesArgument(0, named("redis.clients.jedis.Protocol$Command")))
.and(takesArgument(1, is(byte[][].class))),
JedisInstrumentationModule.class.getName() + "$JedisArgsAdvice");
return transformers;
}
} }
public static class JedisNoArgsAdvice { public static class JedisNoArgsAdvice {

View File

@ -6,6 +6,7 @@
package io.opentelemetry.javaagent.instrumentation.jedis.v3_0; package io.opentelemetry.javaagent.instrumentation.jedis.v3_0;
import static io.opentelemetry.javaagent.instrumentation.jedis.v3_0.JedisClientTracer.tracer; import static io.opentelemetry.javaagent.instrumentation.jedis.v3_0.JedisClientTracer.tracer;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap; import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.is; import static net.bytebuddy.matcher.ElementMatchers.is;
import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.isMethod;
@ -17,7 +18,9 @@ import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.jedis.v3_0.JedisClientTracer.CommandWithArgs; import io.opentelemetry.javaagent.instrumentation.jedis.v3_0.JedisClientTracer.CommandWithArgs;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List;
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;
@ -26,18 +29,13 @@ import net.bytebuddy.matcher.ElementMatcher;
import redis.clients.jedis.Connection; import redis.clients.jedis.Connection;
import redis.clients.jedis.commands.ProtocolCommand; import redis.clients.jedis.commands.ProtocolCommand;
@AutoService(Instrumenter.class) @AutoService(InstrumentationModule.class)
public final class JedisInstrumentation extends Instrumenter.Default { public final class JedisInstrumentationModule extends InstrumentationModule {
public JedisInstrumentation() { public JedisInstrumentationModule() {
super("jedis", "redis"); super("jedis", "redis");
} }
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return named("redis.clients.jedis.Connection");
}
@Override @Override
public String[] helperClassNames() { public String[] helperClassNames() {
return new String[] { return new String[] {
@ -46,15 +44,28 @@ public final class JedisInstrumentation extends Instrumenter.Default {
} }
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public List<TypeInstrumentation> typeInstrumentations() {
return singletonMap( return singletonList(new ConnectionInstrumentation());
isMethod() }
.and(named("sendCommand"))
.and(takesArguments(2)) private static final class ConnectionInstrumentation implements TypeInstrumentation {
.and(takesArgument(0, named("redis.clients.jedis.commands.ProtocolCommand"))) @Override
.and(takesArgument(1, is(byte[][].class))), public ElementMatcher<TypeDescription> typeMatcher() {
JedisInstrumentation.class.getName() + "$JedisAdvice"); return named("redis.clients.jedis.Connection");
// FIXME: This instrumentation only incorporates sending the command, not processing the result. }
@Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap(
isMethod()
.and(named("sendCommand"))
.and(takesArguments(2))
.and(takesArgument(0, named("redis.clients.jedis.commands.ProtocolCommand")))
.and(takesArgument(1, is(byte[][].class))),
JedisInstrumentationModule.class.getName() + "$JedisAdvice");
// FIXME: This instrumentation only incorporates sending the command, not processing the
// result.
}
} }
public static class JedisAdvice { public static class JedisAdvice {

View File

@ -1,76 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.jetty;
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.Instrumenter;
import java.util.Map;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class)
public final class JettyHandlerInstrumentation extends Instrumenter.Default {
public JettyHandlerInstrumentation() {
super("jetty", "jetty-8");
}
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return hasClassesNamed("org.eclipse.jetty.server.Handler");
}
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
// skipping built-in handlers, so that for servlets there will be no span started by jetty.
// this is so that the servlet instrumentation will capture contextPath and servletPath
// normally, which the jetty instrumentation does not capture since jetty doesn't populate
// contextPath and servletPath until right before calling the servlet
// (another option is to instrument ServletHolder.handle() to capture those fields)
return not(named("org.eclipse.jetty.server.handler.HandlerWrapper"))
.and(not(named("org.eclipse.jetty.server.handler.ScopedHandler")))
.and(not(named("org.eclipse.jetty.server.handler.ContextHandler")))
.and(not(named("org.eclipse.jetty.servlet.ServletHandler")))
.and(implementsInterface(named("org.eclipse.jetty.server.Handler")));
}
@Override
public String[] helperClassNames() {
// order matters here because subclasses (e.g. JettyHttpServerTracer) need to be injected into
// the class loader after their super classes (e.g. Servlet3HttpServerTracer)
return new String[] {
"io.opentelemetry.instrumentation.servlet.HttpServletRequestGetter",
"io.opentelemetry.instrumentation.servlet.ServletHttpServerTracer",
"io.opentelemetry.javaagent.instrumentation.servlet.v3_0.Servlet3HttpServerTracer",
"io.opentelemetry.javaagent.instrumentation.servlet.v3_0.TagSettingAsyncListener",
packageName + ".JettyHttpServerTracer",
};
}
@Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap(
named("handle")
// need to capture doHandle() for handlers that extend built-in handlers excluded above
.or(named("doHandle"))
.and(takesArgument(0, named("java.lang.String")))
.and(takesArgument(1, named("org.eclipse.jetty.server.Request")))
.and(takesArgument(2, named("javax.servlet.http.HttpServletRequest")))
.and(takesArgument(3, named("javax.servlet.http.HttpServletResponse")))
.and(isPublic()),
packageName + ".JettyHandlerAdvice");
}
}

View File

@ -0,0 +1,87 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.jetty;
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List;
import java.util.Map;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
@AutoService(InstrumentationModule.class)
public final class JettyInstrumentationModule extends InstrumentationModule {
public JettyInstrumentationModule() {
super("jetty", "jetty-8");
}
@Override
public String[] helperClassNames() {
// order matters here because subclasses (e.g. JettyHttpServerTracer) need to be injected into
// the class loader after their super classes (e.g. Servlet3HttpServerTracer)
return new String[] {
"io.opentelemetry.instrumentation.servlet.HttpServletRequestGetter",
"io.opentelemetry.instrumentation.servlet.ServletHttpServerTracer",
"io.opentelemetry.javaagent.instrumentation.servlet.v3_0.Servlet3HttpServerTracer",
"io.opentelemetry.javaagent.instrumentation.servlet.v3_0.TagSettingAsyncListener",
packageName + ".JettyHttpServerTracer",
};
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return singletonList(new HandlerInstrumentation());
}
private static final class HandlerInstrumentation implements TypeInstrumentation {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return hasClassesNamed("org.eclipse.jetty.server.Handler");
}
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
// skipping built-in handlers, so that for servlets there will be no span started by jetty.
// this is so that the servlet instrumentation will capture contextPath and servletPath
// normally, which the jetty instrumentation does not capture since jetty doesn't populate
// contextPath and servletPath until right before calling the servlet
// (another option is to instrument ServletHolder.handle() to capture those fields)
return not(named("org.eclipse.jetty.server.handler.HandlerWrapper"))
.and(not(named("org.eclipse.jetty.server.handler.ScopedHandler")))
.and(not(named("org.eclipse.jetty.server.handler.ContextHandler")))
.and(not(named("org.eclipse.jetty.servlet.ServletHandler")))
.and(implementsInterface(named("org.eclipse.jetty.server.Handler")));
}
@Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap(
named("handle")
// need to capture doHandle() for handlers that extend built-in handlers excluded
// above
.or(named("doHandle"))
.and(takesArgument(0, named("java.lang.String")))
.and(takesArgument(1, named("org.eclipse.jetty.server.Request")))
.and(takesArgument(2, named("javax.servlet.http.HttpServletRequest")))
.and(takesArgument(3, named("javax.servlet.http.HttpServletResponse")))
.and(isPublic()),
JettyHandlerAdvice.class.getName());
}
}
}

View File

@ -8,15 +8,13 @@ package io.opentelemetry.javaagent.instrumentation.jms;
import static io.opentelemetry.javaagent.instrumentation.jms.JMSTracer.tracer; import static io.opentelemetry.javaagent.instrumentation.jms.JMSTracer.tracer;
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed; import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isPublic; 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 static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.jms.Message; import javax.jms.Message;
@ -26,12 +24,7 @@ import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) final class JMSMessageConsumerInstrumentation implements TypeInstrumentation {
public final class JMSMessageConsumerInstrumentation extends Instrumenter.Default {
public JMSMessageConsumerInstrumentation() {
super("jms", "jms-1", "jms-2");
}
@Override @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() { public ElementMatcher<ClassLoader> classLoaderMatcher() {
@ -44,16 +37,6 @@ public final class JMSMessageConsumerInstrumentation extends Instrumenter.Defaul
return implementsInterface(named("javax.jms.MessageConsumer")); return implementsInterface(named("javax.jms.MessageConsumer"));
} }
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".MessageDestination",
packageName + ".JMSTracer",
packageName + ".MessageExtractAdapter",
packageName + ".MessageInjectAdapter"
};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>(); Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>();
@ -66,13 +49,6 @@ public final class JMSMessageConsumerInstrumentation extends Instrumenter.Defaul
return transformers; return transformers;
} }
@Override
public Map<String, String> contextStore() {
return singletonMap(
"javax.jms.MessageConsumer",
"io.opentelemetry.javaagent.instrumentation.jms.MessageDestination");
}
public static class ConsumerAdvice { public static class ConsumerAdvice {
@Advice.OnMethodEnter @Advice.OnMethodEnter

View File

@ -13,10 +13,9 @@ 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.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Map; import java.util.Map;
import javax.jms.Message; import javax.jms.Message;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
@ -24,12 +23,7 @@ import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) final class JMSMessageListenerInstrumentation implements TypeInstrumentation {
public final class JMSMessageListenerInstrumentation extends Instrumenter.Default {
public JMSMessageListenerInstrumentation() {
super("jms", "jms-1", "jms-2");
}
@Override @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() { public ElementMatcher<ClassLoader> classLoaderMatcher() {
@ -42,16 +36,6 @@ public final class JMSMessageListenerInstrumentation extends Instrumenter.Defaul
return implementsInterface(named("javax.jms.MessageListener")); return implementsInterface(named("javax.jms.MessageListener"));
} }
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".MessageDestination",
packageName + ".JMSTracer",
packageName + ".MessageExtractAdapter",
packageName + ".MessageInjectAdapter"
};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(

View File

@ -12,11 +12,10 @@ 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.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.jms.Destination; import javax.jms.Destination;
@ -28,12 +27,7 @@ import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) final class JMSMessageProducerInstrumentation implements TypeInstrumentation {
public final class JMSMessageProducerInstrumentation extends Instrumenter.Default {
public JMSMessageProducerInstrumentation() {
super("jms", "jms-1", "jms-2");
}
@Override @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() { public ElementMatcher<ClassLoader> classLoaderMatcher() {
@ -46,16 +40,6 @@ public final class JMSMessageProducerInstrumentation extends Instrumenter.Defaul
return implementsInterface(named("javax.jms.MessageProducer")); return implementsInterface(named("javax.jms.MessageProducer"));
} }
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".MessageDestination",
packageName + ".JMSTracer",
packageName + ".MessageExtractAdapter",
packageName + ".MessageInjectAdapter"
};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>(); Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>();

View File

@ -12,9 +12,8 @@ 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.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Map; import java.util.Map;
import javax.jms.Destination; import javax.jms.Destination;
import javax.jms.MessageConsumer; import javax.jms.MessageConsumer;
@ -23,12 +22,7 @@ import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) final class JMSSessionInstrumentation implements TypeInstrumentation {
public final class JMSSessionInstrumentation extends Instrumenter.Default {
public JMSSessionInstrumentation() {
super("jms", "jms-1", "jms-2");
}
@Override @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() { public ElementMatcher<ClassLoader> classLoaderMatcher() {
@ -41,16 +35,6 @@ public final class JMSSessionInstrumentation extends Instrumenter.Default {
return implementsInterface(named("javax.jms.Session")); return implementsInterface(named("javax.jms.Session"));
} }
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".MessageDestination",
packageName + ".JMSTracer",
packageName + ".MessageExtractAdapter",
packageName + ".MessageInjectAdapter"
};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(
@ -60,13 +44,6 @@ public final class JMSSessionInstrumentation extends Instrumenter.Default {
JMSSessionInstrumentation.class.getName() + "$ConsumerAdvice"); JMSSessionInstrumentation.class.getName() + "$ConsumerAdvice");
} }
@Override
public Map<String, String> contextStore() {
return singletonMap(
"javax.jms.MessageConsumer",
"io.opentelemetry.javaagent.instrumentation.jms.MessageDestination");
}
public static class ConsumerAdvice { public static class ConsumerAdvice {
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)

View File

@ -0,0 +1,46 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.jms;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonMap;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List;
import java.util.Map;
@AutoService(InstrumentationModule.class)
public class JmsInstrumentationModule extends InstrumentationModule {
public JmsInstrumentationModule() {
super("jms", "jms-1", "jms-2");
}
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".MessageDestination",
packageName + ".JMSTracer",
packageName + ".MessageExtractAdapter",
packageName + ".MessageInjectAdapter"
};
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return asList(
new JMSMessageConsumerInstrumentation(),
new JMSMessageListenerInstrumentation(),
new JMSMessageProducerInstrumentation(),
new JMSSessionInstrumentation());
}
@Override
public Map<String, String> contextStore() {
return singletonMap("javax.jms.MessageConsumer", MessageDestination.class.getName());
}
}

View File

@ -13,11 +13,10 @@ 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.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Span.Kind; import io.opentelemetry.api.trace.Span.Kind;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Map; import java.util.Map;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
@ -25,12 +24,7 @@ import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class) final class HttpJspPageInstrumentation implements TypeInstrumentation {
public final class JSPInstrumentation extends Instrumenter.Default {
public JSPInstrumentation() {
super("jsp", "jsp-render");
}
@Override @Override
public ElementMatcher<ClassLoader> classLoaderMatcher() { public ElementMatcher<ClassLoader> classLoaderMatcher() {
@ -43,13 +37,6 @@ public final class JSPInstrumentation extends Instrumenter.Default {
return implementsInterface(named("javax.servlet.jsp.HttpJspPage")); return implementsInterface(named("javax.servlet.jsp.HttpJspPage"));
} }
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".JSPTracer",
};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(
@ -57,7 +44,7 @@ public final class JSPInstrumentation extends Instrumenter.Default {
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest"))) .and(takesArgument(0, named("javax.servlet.http.HttpServletRequest")))
.and(takesArgument(1, named("javax.servlet.http.HttpServletResponse"))) .and(takesArgument(1, named("javax.servlet.http.HttpServletResponse")))
.and(isPublic()), .and(isPublic()),
JSPInstrumentation.class.getName() + "$HttpJspPageAdvice"); HttpJspPageInstrumentation.class.getName() + "$HttpJspPageAdvice");
} }
public static class HttpJspPageAdvice { public static class HttpJspPageAdvice {

View File

@ -11,11 +11,10 @@ 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 static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Span.Kind; import io.opentelemetry.api.trace.Span.Kind;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.tooling.Instrumenter; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
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;
@ -23,31 +22,18 @@ import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
import org.apache.jasper.JspCompilationContext; import org.apache.jasper.JspCompilationContext;
@AutoService(Instrumenter.class) final class JspCompilationContextInstrumentation implements TypeInstrumentation {
public final class JasperJSPCompilationContextInstrumentation extends Instrumenter.Default {
public JasperJSPCompilationContextInstrumentation() {
super("jsp", "jsp-compile");
}
@Override @Override
public ElementMatcher<TypeDescription> typeMatcher() { public ElementMatcher<TypeDescription> typeMatcher() {
return named("org.apache.jasper.JspCompilationContext"); return named("org.apache.jasper.JspCompilationContext");
} }
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".JSPTracer",
};
}
@Override @Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap( return singletonMap(
named("compile").and(takesArguments(0)).and(isPublic()), named("compile").and(takesArguments(0)).and(isPublic()),
JasperJSPCompilationContextInstrumentation.class.getName() JspCompilationContextInstrumentation.class.getName() + "$JasperJspCompilationContext");
+ "$JasperJspCompilationContext");
} }
public static class JasperJspCompilationContext { public static class JasperJspCompilationContext {

View File

@ -0,0 +1,32 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.jsp;
import static java.util.Arrays.asList;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List;
@AutoService(InstrumentationModule.class)
public class JspInstrumentationModule extends InstrumentationModule {
public JspInstrumentationModule() {
super("jsp");
}
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".JSPTracer",
};
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return asList(new HttpJspPageInstrumentation(), new JspCompilationContextInstrumentation());
}
}