Refactor Instrumenters into InstrumentationModules - R, S, T, V (#1576)
This commit is contained in:
parent
087a9cbc4e
commit
9d2db827b9
|
@ -22,7 +22,6 @@ 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 com.rabbitmq.client.AMQP;
|
import com.rabbitmq.client.AMQP;
|
||||||
import com.rabbitmq.client.Channel;
|
import com.rabbitmq.client.Channel;
|
||||||
import com.rabbitmq.client.Consumer;
|
import com.rabbitmq.client.Consumer;
|
||||||
|
@ -34,7 +33,7 @@ import io.opentelemetry.context.Context;
|
||||||
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.Java8BytecodeBridge;
|
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
|
||||||
import io.opentelemetry.javaagent.tooling.Instrumenter;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -44,12 +43,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 RabbitChannelInstrumentation implements TypeInstrumentation {
|
||||||
public class RabbitChannelInstrumentation extends Instrumenter.Default {
|
|
||||||
|
|
||||||
public RabbitChannelInstrumentation() {
|
|
||||||
super("amqp", "rabbitmq");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
|
@ -62,17 +56,6 @@ public class RabbitChannelInstrumentation extends Instrumenter.Default {
|
||||||
return implementsInterface(named("com.rabbitmq.client.Channel"));
|
return implementsInterface(named("com.rabbitmq.client.Channel"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] helperClassNames() {
|
|
||||||
return new String[] {
|
|
||||||
packageName + ".RabbitTracer",
|
|
||||||
packageName + ".TextMapInjectAdapter",
|
|
||||||
packageName + ".TextMapExtractAdapter",
|
|
||||||
packageName + ".TracedDelegatingConsumer",
|
|
||||||
RabbitCommandInstrumentation.class.getName() + "$SpanHolder",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
// We want the advice applied in a specific order, so use an ordered map.
|
// We want the advice applied in a specific order, so use an ordered map.
|
||||||
|
|
|
@ -13,22 +13,16 @@ import static java.util.Collections.singletonMap;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
|
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
|
||||||
import com.rabbitmq.client.Command;
|
import com.rabbitmq.client.Command;
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
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;
|
||||||
|
|
||||||
@AutoService(Instrumenter.class)
|
final class RabbitCommandInstrumentation implements TypeInstrumentation {
|
||||||
public class RabbitCommandInstrumentation extends Instrumenter.Default {
|
|
||||||
|
|
||||||
public RabbitCommandInstrumentation() {
|
|
||||||
super("amqp", "rabbitmq");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
|
@ -41,17 +35,6 @@ public class RabbitCommandInstrumentation extends Instrumenter.Default {
|
||||||
return implementsInterface(named("com.rabbitmq.client.Command"));
|
return implementsInterface(named("com.rabbitmq.client.Command"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] helperClassNames() {
|
|
||||||
return new String[] {
|
|
||||||
packageName + ".RabbitTracer",
|
|
||||||
// These are only used by muzzleCheck:
|
|
||||||
packageName + ".TextMapExtractAdapter",
|
|
||||||
packageName + ".TracedDelegatingConsumer",
|
|
||||||
RabbitCommandInstrumentation.class.getName() + "$SpanHolder"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
return singletonMap(
|
return singletonMap(
|
||||||
|
@ -72,14 +55,5 @@ public class RabbitCommandInstrumentation extends Instrumenter.Default {
|
||||||
tracer().onCommand(span, command);
|
tracer().onCommand(span, command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This instrumentation will match with 2.6, but the channel instrumentation only matches with
|
|
||||||
* 2.7 because of TracedDelegatingConsumer. This unused method is added to ensure consistent
|
|
||||||
* muzzle validation by preventing match with 2.6.
|
|
||||||
*/
|
|
||||||
public static void muzzleCheck(TracedDelegatingConsumer consumer) {
|
|
||||||
consumer.handleRecoverOk(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.rabbitmq.amqp;
|
||||||
|
|
||||||
|
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 RabbitMqInstrumentationModule extends InstrumentationModule {
|
||||||
|
public RabbitMqInstrumentationModule() {
|
||||||
|
super("amqp", "rabbitmq");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] helperClassNames() {
|
||||||
|
return new String[] {
|
||||||
|
packageName + ".RabbitTracer",
|
||||||
|
packageName + ".TextMapInjectAdapter",
|
||||||
|
packageName + ".TextMapExtractAdapter",
|
||||||
|
packageName + ".TracedDelegatingConsumer",
|
||||||
|
RabbitCommandInstrumentation.class.getName() + "$SpanHolder",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
|
return asList(new RabbitChannelInstrumentation(), new RabbitCommandInstrumentation());
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,22 +12,15 @@ 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.javaagent.tooling.TypeInstrumentation;
|
||||||
import io.opentelemetry.javaagent.tooling.Instrumenter;
|
|
||||||
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;
|
||||||
import ratpack.func.Block;
|
import ratpack.func.Block;
|
||||||
import ratpack.path.PathBinding;
|
|
||||||
|
|
||||||
@AutoService(Instrumenter.class)
|
final class ContinuationInstrumentation implements TypeInstrumentation {
|
||||||
public final class ContinuationInstrumentation extends Instrumenter.Default {
|
|
||||||
|
|
||||||
public ContinuationInstrumentation() {
|
|
||||||
super("ratpack");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
|
@ -41,11 +34,6 @@ public final class ContinuationInstrumentation extends Instrumenter.Default {
|
||||||
.<TypeDescription>and(implementsInterface(named("ratpack.exec.internal.Continuation")));
|
.<TypeDescription>and(implementsInterface(named("ratpack.exec.internal.Continuation")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] helperClassNames() {
|
|
||||||
return new String[] {packageName + ".BlockWrapper"};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
return singletonMap(
|
return singletonMap(
|
||||||
|
@ -59,10 +47,5 @@ public final class ContinuationInstrumentation extends Instrumenter.Default {
|
||||||
public static void wrap(@Advice.Argument(value = 0, readOnly = false) Block block) {
|
public static void wrap(@Advice.Argument(value = 0, readOnly = false) Block block) {
|
||||||
block = BlockWrapper.wrapIfNeeded(block);
|
block = BlockWrapper.wrapIfNeeded(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void muzzleCheck(PathBinding binding) {
|
|
||||||
// This was added in 1.4. Added here to ensure consistency with other instrumentation.
|
|
||||||
binding.getDescription();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,7 @@ 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.javaagent.tooling.TypeInstrumentation;
|
||||||
import io.opentelemetry.javaagent.tooling.Instrumenter;
|
|
||||||
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;
|
||||||
|
@ -19,25 +18,14 @@ import net.bytebuddy.description.type.TypeDescription;
|
||||||
import net.bytebuddy.matcher.ElementMatcher;
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
import ratpack.exec.internal.Continuation;
|
import ratpack.exec.internal.Continuation;
|
||||||
import ratpack.func.Action;
|
import ratpack.func.Action;
|
||||||
import ratpack.path.PathBinding;
|
|
||||||
|
|
||||||
@AutoService(Instrumenter.class)
|
final class DefaultExecutionInstrumentation implements TypeInstrumentation {
|
||||||
public final class DefaultExecutionInstrumentation extends Instrumenter.Default {
|
|
||||||
|
|
||||||
public DefaultExecutionInstrumentation() {
|
|
||||||
super("ratpack");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
||||||
return named("ratpack.exec.internal.DefaultExecution");
|
return named("ratpack.exec.internal.DefaultExecution");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] helperClassNames() {
|
|
||||||
return new String[] {packageName + ".ActionWrapper"};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
return singletonMap(
|
return singletonMap(
|
||||||
|
@ -56,10 +44,5 @@ public final class DefaultExecutionInstrumentation extends Instrumenter.Default
|
||||||
onError = ActionWrapper.wrapIfNeeded(onError);
|
onError = ActionWrapper.wrapIfNeeded(onError);
|
||||||
segment = ActionWrapper.wrapIfNeeded(segment);
|
segment = ActionWrapper.wrapIfNeeded(segment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void muzzleCheck(PathBinding binding) {
|
|
||||||
// This was added in 1.4. Added here to ensure consistency with other instrumentation.
|
|
||||||
binding.getDescription();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.ratpack;
|
||||||
|
|
||||||
|
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 RatpackInstrumentationModule extends InstrumentationModule {
|
||||||
|
public RatpackInstrumentationModule() {
|
||||||
|
super("ratpack");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] helperClassNames() {
|
||||||
|
return new String[] {
|
||||||
|
packageName + ".ActionWrapper",
|
||||||
|
packageName + ".BlockWrapper",
|
||||||
|
packageName + ".RatpackTracer",
|
||||||
|
packageName + ".TracingHandler",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
|
return asList(
|
||||||
|
new ContinuationInstrumentation(),
|
||||||
|
new DefaultExecutionInstrumentation(),
|
||||||
|
new ServerErrorHandlerInstrumentation(),
|
||||||
|
new ServerRegistryInstrumentation());
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,19 +13,13 @@ 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.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.util.Map;
|
import java.util.Map;
|
||||||
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)
|
final class ServerErrorHandlerInstrumentation implements TypeInstrumentation {
|
||||||
public class ServerErrorHandlerInstrumentation extends Instrumenter.Default {
|
|
||||||
|
|
||||||
public ServerErrorHandlerInstrumentation() {
|
|
||||||
super("ratpack");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
|
@ -38,19 +32,12 @@ public class ServerErrorHandlerInstrumentation extends Instrumenter.Default {
|
||||||
return not(isAbstract()).and(implementsInterface(named("ratpack.error.ServerErrorHandler")));
|
return not(isAbstract()).and(implementsInterface(named("ratpack.error.ServerErrorHandler")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] helperClassNames() {
|
|
||||||
return new String[] {
|
|
||||||
packageName + ".RatpackTracer",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
return singletonMap(
|
return singletonMap(
|
||||||
named("error")
|
named("error")
|
||||||
.and(takesArgument(0, named("ratpack.handling.Context")))
|
.and(takesArgument(0, named("ratpack.handling.Context")))
|
||||||
.and(takesArgument(1, Throwable.class)),
|
.and(takesArgument(1, Throwable.class)),
|
||||||
packageName + ".ErrorHandlerAdvice");
|
ErrorHandlerAdvice.class.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,36 +10,23 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isStatic;
|
import static net.bytebuddy.matcher.ElementMatchers.isStatic;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
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 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)
|
final class ServerRegistryInstrumentation implements TypeInstrumentation {
|
||||||
public class ServerRegistryInstrumentation extends Instrumenter.Default {
|
|
||||||
|
|
||||||
public ServerRegistryInstrumentation() {
|
|
||||||
super("ratpack");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
return named("ratpack.server.internal.ServerRegistry");
|
return named("ratpack.server.internal.ServerRegistry");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] helperClassNames() {
|
|
||||||
return new String[] {
|
|
||||||
packageName + ".RatpackTracer", packageName + ".TracingHandler",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
return singletonMap(
|
return singletonMap(
|
||||||
isMethod().and(isStatic()).and(named("buildBaseRegistry")),
|
isMethod().and(isStatic()).and(named("buildBaseRegistry")),
|
||||||
packageName + ".ServerRegistryAdvice");
|
ServerRegistryAdvice.class.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.reactor;
|
|
||||||
|
|
||||||
import static java.util.Collections.singletonMap;
|
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isTypeInitializer;
|
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
|
||||||
|
|
||||||
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 ReactorHooksInstrumentation extends Instrumenter.Default {
|
|
||||||
|
|
||||||
public ReactorHooksInstrumentation() {
|
|
||||||
super("reactor-core");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] helperClassNames() {
|
|
||||||
return new String[] {
|
|
||||||
"io.opentelemetry.instrumentation.reactor.TracingOperator$Lifter",
|
|
||||||
"io.opentelemetry.instrumentation.reactor.TracingOperator",
|
|
||||||
"io.opentelemetry.instrumentation.reactor.TracingSubscriber"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
|
||||||
return named("reactor.core.publisher.Hooks");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
|
||||||
return singletonMap(
|
|
||||||
isTypeInitializer().or(named("resetOnEachOperator")), packageName + ".ReactorHooksAdvice");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.reactor;
|
||||||
|
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
|
import static java.util.Collections.singletonMap;
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.isTypeInitializer;
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
|
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 ReactorInstrumentationModule extends InstrumentationModule {
|
||||||
|
|
||||||
|
public ReactorInstrumentationModule() {
|
||||||
|
super("reactor-core");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] helperClassNames() {
|
||||||
|
return new String[] {
|
||||||
|
"io.opentelemetry.instrumentation.reactor.TracingOperator$Lifter",
|
||||||
|
"io.opentelemetry.instrumentation.reactor.TracingOperator",
|
||||||
|
"io.opentelemetry.instrumentation.reactor.TracingSubscriber"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
|
return singletonList(new HooksInstrumentation());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class HooksInstrumentation implements TypeInstrumentation {
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
return named("reactor.core.publisher.Hooks");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return singletonMap(
|
||||||
|
isTypeInitializer().or(named("resetOnEachOperator")), ReactorHooksAdvice.class.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import static io.opentelemetry.javaagent.instrumentation.rediscala.RediscalaClie
|
||||||
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.safeHasSuperType;
|
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.safeHasSuperType;
|
||||||
import static io.opentelemetry.javaagent.tooling.matcher.NameMatchers.namedOneOf;
|
import static io.opentelemetry.javaagent.tooling.matcher.NameMatchers.namedOneOf;
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.Collections.singletonMap;
|
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;
|
||||||
|
@ -19,7 +20,9 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||||
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 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;
|
||||||
|
@ -31,52 +34,59 @@ import scala.concurrent.Future;
|
||||||
import scala.runtime.AbstractFunction1;
|
import scala.runtime.AbstractFunction1;
|
||||||
import scala.util.Try;
|
import scala.util.Try;
|
||||||
|
|
||||||
@AutoService(Instrumenter.class)
|
@AutoService(InstrumentationModule.class)
|
||||||
public final class RediscalaInstrumentation extends Instrumenter.Default {
|
public final class RediscalaInstrumentationModule extends InstrumentationModule {
|
||||||
|
|
||||||
public RediscalaInstrumentation() {
|
public RediscalaInstrumentationModule() {
|
||||||
super("rediscala", "redis");
|
super("rediscala", "redis");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
|
||||||
return hasClassesNamed("redis.Request");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
|
||||||
return safeHasSuperType(
|
|
||||||
namedOneOf(
|
|
||||||
"redis.ActorRequest",
|
|
||||||
"redis.Request",
|
|
||||||
"redis.BufferedRequest",
|
|
||||||
"redis.RoundRobinPoolRequest"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
RediscalaInstrumentation.class.getName() + "$OnCompleteHandler",
|
RediscalaInstrumentationModule.class.getName() + "$OnCompleteHandler",
|
||||||
packageName + ".RediscalaClientTracer",
|
packageName + ".RediscalaClientTracer",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
return singletonMap(
|
return singletonList(new RequestInstrumentation());
|
||||||
isMethod()
|
}
|
||||||
.and(isPublic())
|
|
||||||
.and(named("send"))
|
private static final class RequestInstrumentation implements TypeInstrumentation {
|
||||||
.and(takesArgument(0, named("redis.RedisCommand")))
|
@Override
|
||||||
.and(returns(named("scala.concurrent.Future"))),
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
RediscalaInstrumentation.class.getName() + "$RediscalaAdvice");
|
return hasClassesNamed("redis.Request");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
return safeHasSuperType(
|
||||||
|
namedOneOf(
|
||||||
|
"redis.ActorRequest",
|
||||||
|
"redis.Request",
|
||||||
|
"redis.BufferedRequest",
|
||||||
|
"redis.RoundRobinPoolRequest"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return singletonMap(
|
||||||
|
isMethod()
|
||||||
|
.and(isPublic())
|
||||||
|
.and(named("send"))
|
||||||
|
.and(takesArgument(0, named("redis.RedisCommand")))
|
||||||
|
.and(returns(named("scala.concurrent.Future"))),
|
||||||
|
RediscalaInstrumentationModule.class.getName() + "$RediscalaAdvice");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RediscalaAdvice {
|
public static class RediscalaAdvice {
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static void onEnter(
|
public static void onEnter(
|
||||||
@Advice.Argument(0) RedisCommand cmd,
|
@Advice.Argument(0) RedisCommand<?, ?> cmd,
|
||||||
@Advice.Local("otelSpan") Span span,
|
@Advice.Local("otelSpan") Span span,
|
||||||
@Advice.Local("otelScope") Scope scope) {
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
span = tracer().startSpan(cmd, cmd);
|
span = tracer().startSpan(cmd, cmd);
|
|
@ -6,6 +6,7 @@
|
||||||
package io.opentelemetry.javaagent.instrumentation.redisson;
|
package io.opentelemetry.javaagent.instrumentation.redisson;
|
||||||
|
|
||||||
import static io.opentelemetry.javaagent.instrumentation.redisson.RedissonClientTracer.tracer;
|
import static io.opentelemetry.javaagent.instrumentation.redisson.RedissonClientTracer.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.isMethod;
|
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
@ -13,7 +14,9 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
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 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;
|
||||||
|
@ -21,27 +24,35 @@ import net.bytebuddy.description.type.TypeDescription;
|
||||||
import net.bytebuddy.matcher.ElementMatcher;
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
import org.redisson.client.RedisConnection;
|
import org.redisson.client.RedisConnection;
|
||||||
|
|
||||||
@AutoService(Instrumenter.class)
|
@AutoService(InstrumentationModule.class)
|
||||||
public final class RedissonInstrumentation extends Instrumenter.Default {
|
public final class RedissonInstrumentation extends InstrumentationModule {
|
||||||
|
|
||||||
public RedissonInstrumentation() {
|
public RedissonInstrumentation() {
|
||||||
super("redisson", "redis");
|
super("redisson", "redis");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
|
||||||
return named("org.redisson.client.RedisConnection");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {packageName + ".RedissonClientTracer"};
|
return new String[] {packageName + ".RedissonClientTracer"};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
return singletonMap(
|
return singletonList(new RedisConnectionInstrumentation());
|
||||||
isMethod().and(named("send")), RedissonInstrumentation.class.getName() + "$RedissonAdvice");
|
}
|
||||||
|
|
||||||
|
private static final class RedisConnectionInstrumentation implements TypeInstrumentation {
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
return named("org.redisson.client.RedisConnection");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return singletonMap(
|
||||||
|
isMethod().and(named("send")),
|
||||||
|
RedissonInstrumentation.class.getName() + "$RedissonAdvice");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RedissonAdvice {
|
public static class RedissonAdvice {
|
||||||
|
|
|
@ -7,6 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.rmi.client;
|
||||||
|
|
||||||
import static io.opentelemetry.javaagent.instrumentation.rmi.client.RmiClientTracer.tracer;
|
import static io.opentelemetry.javaagent.instrumentation.rmi.client.RmiClientTracer.tracer;
|
||||||
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass;
|
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass;
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.Collections.singletonMap;
|
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.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
@ -16,39 +17,48 @@ 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.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
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 RmiClientInstrumentation extends Instrumenter.Default {
|
public final class RmiClientInstrumentationModule extends InstrumentationModule {
|
||||||
|
|
||||||
public RmiClientInstrumentation() {
|
public RmiClientInstrumentationModule() {
|
||||||
super("rmi", "rmi-client");
|
super("rmi", "rmi-client");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
|
||||||
return extendsClass(named("sun.rmi.server.UnicastRef"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {packageName + ".RmiClientTracer"};
|
return new String[] {packageName + ".RmiClientTracer"};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
return singletonMap(
|
return singletonList(new ClientInstrumentation());
|
||||||
isMethod()
|
}
|
||||||
.and(named("invoke"))
|
|
||||||
.and(takesArgument(0, named("java.rmi.Remote")))
|
private static final class ClientInstrumentation implements TypeInstrumentation {
|
||||||
.and(takesArgument(1, named("java.lang.reflect.Method"))),
|
@Override
|
||||||
getClass().getName() + "$RmiClientAdvice");
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
return extendsClass(named("sun.rmi.server.UnicastRef"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return singletonMap(
|
||||||
|
isMethod()
|
||||||
|
.and(named("invoke"))
|
||||||
|
.and(takesArgument(0, named("java.rmi.Remote")))
|
||||||
|
.and(takesArgument(1, named("java.lang.reflect.Method"))),
|
||||||
|
RmiClientInstrumentationModule.class.getName() + "$RmiClientAdvice");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RmiClientAdvice {
|
public static class RmiClientAdvice {
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.rmi.context;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import static java.util.Collections.singletonMap;
|
||||||
|
|
||||||
|
import com.google.auto.service.AutoService;
|
||||||
|
import io.opentelemetry.javaagent.instrumentation.rmi.context.client.RmiClientContextInstrumentation;
|
||||||
|
import io.opentelemetry.javaagent.instrumentation.rmi.context.server.RmiServerContextInstrumentation;
|
||||||
|
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 RmiContextPropagationInstrumentationModule extends InstrumentationModule {
|
||||||
|
public RmiContextPropagationInstrumentationModule() {
|
||||||
|
super("rmi", "rmi-context-propagator");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] helperClassNames() {
|
||||||
|
return new String[] {
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPayload$InjectAdapter",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPayload$ExtractAdapter",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPayload",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPropagator",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.rmi.context.server.ContextDispatcher",
|
||||||
|
"io.opentelemetry.javaagent.instrumentation.rmi.context.server.ContextDispatcher$NoopRemote"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
|
return asList(new RmiClientContextInstrumentation(), new RmiServerContextInstrumentation());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> contextStore() {
|
||||||
|
// caching if a connection can support enhanced format
|
||||||
|
return singletonMap("sun.rmi.transport.Connection", "java.lang.Boolean");
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,12 +12,11 @@ import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
|
||||||
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.instrumentation.api.Java8BytecodeBridge;
|
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
|
||||||
import io.opentelemetry.javaagent.tooling.Instrumenter;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.rmi.server.ObjID;
|
import java.rmi.server.ObjID;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
|
@ -47,34 +46,13 @@ import sun.rmi.transport.Connection;
|
||||||
* that instruction will essentially be garbage data and will cause the parsing loop to throw
|
* that instruction will essentially be garbage data and will cause the parsing loop to throw
|
||||||
* exception and shutdown the connection which we do not want
|
* exception and shutdown the connection which we do not want
|
||||||
*/
|
*/
|
||||||
@AutoService(Instrumenter.class)
|
public final class RmiClientContextInstrumentation implements TypeInstrumentation {
|
||||||
public class RmiClientContextInstrumentation extends Instrumenter.Default {
|
|
||||||
|
|
||||||
public RmiClientContextInstrumentation() {
|
|
||||||
super("rmi", "rmi-context-propagator", "rmi-client-context-propagator");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
||||||
return extendsClass(named("sun.rmi.transport.StreamRemoteCall"));
|
return extendsClass(named("sun.rmi.transport.StreamRemoteCall"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> contextStore() {
|
|
||||||
// caching if a connection can support enhanced format
|
|
||||||
return singletonMap("sun.rmi.transport.Connection", "java.lang.Boolean");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] helperClassNames() {
|
|
||||||
return new String[] {
|
|
||||||
"io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPayload$InjectAdapter",
|
|
||||||
"io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPayload$ExtractAdapter",
|
|
||||||
"io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPayload",
|
|
||||||
"io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPropagator"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
return singletonMap(
|
return singletonMap(
|
||||||
|
|
|
@ -13,8 +13,7 @@ import static net.bytebuddy.matcher.ElementMatchers.isStatic;
|
||||||
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.tooling.TypeInstrumentation;
|
||||||
import io.opentelemetry.javaagent.tooling.Instrumenter;
|
|
||||||
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;
|
||||||
|
@ -22,30 +21,13 @@ import net.bytebuddy.description.type.TypeDescription;
|
||||||
import net.bytebuddy.matcher.ElementMatcher;
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
import sun.rmi.transport.Target;
|
import sun.rmi.transport.Target;
|
||||||
|
|
||||||
@AutoService(Instrumenter.class)
|
public final class RmiServerContextInstrumentation implements TypeInstrumentation {
|
||||||
public class RmiServerContextInstrumentation extends Instrumenter.Default {
|
|
||||||
|
|
||||||
public RmiServerContextInstrumentation() {
|
|
||||||
super("rmi", "rmi-context-propagator", "rmi-server-context-propagator");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
||||||
return extendsClass(named("sun.rmi.transport.ObjectTable"));
|
return extendsClass(named("sun.rmi.transport.ObjectTable"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] helperClassNames() {
|
|
||||||
return new String[] {
|
|
||||||
"io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPayload$InjectAdapter",
|
|
||||||
"io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPayload$ExtractAdapter",
|
|
||||||
"io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPayload",
|
|
||||||
"io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPropagator",
|
|
||||||
packageName + ".ContextDispatcher",
|
|
||||||
packageName + ".ContextDispatcher$NoopRemote"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
return singletonMap(
|
return singletonMap(
|
||||||
|
|
|
@ -8,6 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.rmi.server;
|
||||||
import static io.opentelemetry.javaagent.instrumentation.api.rmi.ThreadLocalContext.THREAD_LOCAL_CONTEXT;
|
import static io.opentelemetry.javaagent.instrumentation.api.rmi.ThreadLocalContext.THREAD_LOCAL_CONTEXT;
|
||||||
import static io.opentelemetry.javaagent.instrumentation.rmi.server.RmiServerTracer.tracer;
|
import static io.opentelemetry.javaagent.instrumentation.rmi.server.RmiServerTracer.tracer;
|
||||||
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass;
|
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass;
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.Collections.singletonMap;
|
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;
|
||||||
|
@ -20,17 +21,19 @@ import io.opentelemetry.api.trace.Span;
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
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.InstrumentationModule;
|
||||||
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.rmi.server.RemoteServer;
|
import java.rmi.server.RemoteServer;
|
||||||
|
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 RmiServerInstrumentation extends Instrumenter.Default {
|
public final class RmiServerInstrumentation extends InstrumentationModule {
|
||||||
|
|
||||||
public RmiServerInstrumentation() {
|
public RmiServerInstrumentation() {
|
||||||
super("rmi", "rmi-server");
|
super("rmi", "rmi-server");
|
||||||
|
@ -42,14 +45,22 @@ public final class RmiServerInstrumentation extends Instrumenter.Default {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
return extendsClass(named("java.rmi.server.RemoteServer"));
|
return singletonList(new ServerInstrumentation());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private static final class ServerInstrumentation implements TypeInstrumentation {
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
@Override
|
||||||
return singletonMap(
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
isMethod().and(isPublic()).and(not(isStatic())), getClass().getName() + "$ServerAdvice");
|
return extendsClass(named("java.rmi.server.RemoteServer"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return singletonMap(
|
||||||
|
isMethod().and(isPublic()).and(not(isStatic())),
|
||||||
|
RmiServerInstrumentation.class.getName() + "$ServerAdvice");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ServerAdvice {
|
public static class ServerAdvice {
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.scalaconcurrent;
|
||||||
|
|
||||||
|
import static io.opentelemetry.javaagent.instrumentation.scalaconcurrent.ScalaForkJoinTaskInstrumentation.TASK_CLASS_NAME;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@AutoService(InstrumentationModule.class)
|
||||||
|
public class ScalaConcurrentInstrumentationModule extends InstrumentationModule {
|
||||||
|
public ScalaConcurrentInstrumentationModule() {
|
||||||
|
super("java_concurrent", "scala_concurrent");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
|
return asList(new ScalaForkJoinPoolInstrumentation(), new ScalaForkJoinTaskInstrumentation());
|
||||||
|
}
|
||||||
|
|
||||||
|
@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(TASK_CLASS_NAME, State.class.getName());
|
||||||
|
return Collections.unmodifiableMap(map);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,18 +5,16 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.scalaconcurrent;
|
package io.opentelemetry.javaagent.instrumentation.scalaconcurrent;
|
||||||
|
|
||||||
import static java.util.Collections.singletonMap;
|
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.nameMatches;
|
import static net.bytebuddy.matcher.ElementMatchers.nameMatches;
|
||||||
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.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;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.concurrent.ExecutorInstrumentationUtils;
|
import io.opentelemetry.javaagent.instrumentation.api.concurrent.ExecutorInstrumentationUtils;
|
||||||
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.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
|
@ -25,12 +23,7 @@ import net.bytebuddy.description.type.TypeDescription;
|
||||||
import net.bytebuddy.matcher.ElementMatcher;
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
import scala.concurrent.forkjoin.ForkJoinTask;
|
import scala.concurrent.forkjoin.ForkJoinTask;
|
||||||
|
|
||||||
@AutoService(Instrumenter.class)
|
final class ScalaForkJoinPoolInstrumentation implements TypeInstrumentation {
|
||||||
public final class ScalaForkJoinPoolInstrumentation extends Instrumenter.Default {
|
|
||||||
|
|
||||||
public ScalaForkJoinPoolInstrumentation() {
|
|
||||||
super("java_concurrent", "scala_concurrent");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
@ -38,11 +31,6 @@ public final class ScalaForkJoinPoolInstrumentation extends Instrumenter.Default
|
||||||
return named("scala.concurrent.forkjoin.ForkJoinPool");
|
return named("scala.concurrent.forkjoin.ForkJoinPool");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> contextStore() {
|
|
||||||
return singletonMap(ScalaForkJoinTaskInstrumentation.TASK_CLASS_NAME, State.class.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@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<>();
|
||||||
|
@ -65,7 +53,7 @@ public final class ScalaForkJoinPoolInstrumentation extends Instrumenter.Default
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static State enterJobSubmit(
|
public static State enterJobSubmit(
|
||||||
@Advice.Argument(value = 0, readOnly = false) ForkJoinTask task) {
|
@Advice.Argument(value = 0, readOnly = false) ForkJoinTask<?> task) {
|
||||||
if (ExecutorInstrumentationUtils.shouldAttachStateToTask(task)) {
|
if (ExecutorInstrumentationUtils.shouldAttachStateToTask(task)) {
|
||||||
ContextStore<ForkJoinTask, State> contextStore =
|
ContextStore<ForkJoinTask, State> contextStore =
|
||||||
InstrumentationContext.get(ForkJoinTask.class, State.class);
|
InstrumentationContext.get(ForkJoinTask.class, State.class);
|
||||||
|
|
|
@ -13,15 +13,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 net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
|
@ -37,15 +34,10 @@ import scala.concurrent.forkjoin.ForkJoinTask;
|
||||||
* <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 Scala version.
|
* ForkJoinPool}: JVM, Akka, Scala, Netty to name a few. This class handles Scala version.
|
||||||
*/
|
*/
|
||||||
@AutoService(Instrumenter.class)
|
final class ScalaForkJoinTaskInstrumentation implements TypeInstrumentation {
|
||||||
public final class ScalaForkJoinTaskInstrumentation extends Instrumenter.Default {
|
|
||||||
|
|
||||||
static final String TASK_CLASS_NAME = "scala.concurrent.forkjoin.ForkJoinTask";
|
static final String TASK_CLASS_NAME = "scala.concurrent.forkjoin.ForkJoinTask";
|
||||||
|
|
||||||
public ScalaForkJoinTaskInstrumentation() {
|
|
||||||
super("java_concurrent", "scala_concurrent");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
// Optimization for expensive typeMatcher.
|
// Optimization for expensive typeMatcher.
|
||||||
|
@ -57,15 +49,6 @@ public final class ScalaForkJoinTaskInstrumentation extends Instrumenter.Default
|
||||||
return extendsClass(named(TASK_CLASS_NAME));
|
return extendsClass(named(TASK_CLASS_NAME));
|
||||||
}
|
}
|
||||||
|
|
||||||
@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(TASK_CLASS_NAME, 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(
|
||||||
|
@ -82,7 +65,7 @@ public final class ScalaForkJoinTaskInstrumentation extends Instrumenter.Default
|
||||||
* need to use that state.
|
* need to use that state.
|
||||||
*/
|
*/
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static Scope enter(@Advice.This ForkJoinTask thiz) {
|
public static Scope enter(@Advice.This ForkJoinTask<?> thiz) {
|
||||||
ContextStore<ForkJoinTask, State> contextStore =
|
ContextStore<ForkJoinTask, State> contextStore =
|
||||||
InstrumentationContext.get(ForkJoinTask.class, State.class);
|
InstrumentationContext.get(ForkJoinTask.class, State.class);
|
||||||
Scope scope = AdviceUtils.startTaskScope(contextStore, thiz);
|
Scope scope = AdviceUtils.startTaskScope(contextStore, thiz);
|
||||||
|
|
|
@ -59,16 +59,16 @@ Next, request passes several other methods from Servlet specification, such as
|
||||||
|
|
||||||
`protected void org.springframework.web.servlet.FrameworkServlet#doGet(HttpServletRequest, HttpServletResponse)`.
|
`protected void org.springframework.web.servlet.FrameworkServlet#doGet(HttpServletRequest, HttpServletResponse)`.
|
||||||
|
|
||||||
They are the targets for `HttpServletInstrumentation`.
|
They are the targets for `HttpServletInstrumentationModule`.
|
||||||
From the observability point of view nothing of interest usually happens inside these methods.
|
From the observability point of view nothing of interest usually happens inside these methods.
|
||||||
Thus it usually does not make sense to create spans from them, as they would only add useless noise.
|
Thus it usually does not make sense to create spans from them, as they would only add useless noise.
|
||||||
For this reason `HttpServletInstrumentation` is disabled by default.
|
For this reason `HttpServletInstrumentationModule` is disabled by default.
|
||||||
In rare cases when you need it, you can enable it using configuration property `otel.integration.servlet-service.enabled`.
|
In rare cases when you need it, you can enable it using configuration property `otel.instrumentation.servlet-service.enabled`.
|
||||||
|
|
||||||
In exactly the same situation are all other Servlet filters beyond the initial entry point.
|
In exactly the same situation are all other Servlet filters beyond the initial entry point.
|
||||||
Usually unimportant, they may be sometimes of interest during troubleshooting.
|
Usually unimportant, they may be sometimes of interest during troubleshooting.
|
||||||
They are instrumented by `FilterInstrumentation` which is also disabled by default.
|
They are instrumented by `FilterInstrumentationModule` which is also disabled by default.
|
||||||
You can enable it with the configuration property `otel.integration.servlet-filter.enabled`.
|
You can enable it with the configuration property `otel.instrumentation.servlet-filter.enabled`.
|
||||||
At last, request processing may reach the specific framework that your application uses.
|
At last, request processing may reach the specific framework that your application uses.
|
||||||
In this case Spring MVC and `OwnerController.initCreationForm`.
|
In this case Spring MVC and `OwnerController.initCreationForm`.
|
||||||
|
|
||||||
|
@ -88,10 +88,10 @@ Of course, still adhering to OpenTelemetry
|
||||||
[semantic conventions](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/http.md).
|
[semantic conventions](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/http.md).
|
||||||
|
|
||||||
## Additional instrumentations
|
## Additional instrumentations
|
||||||
`RequestDispatcherInstrumentation` instruments `javax.servlet.RequestDispatcher.forward` and
|
`RequestDispatcherInstrumentationModule` instruments `javax.servlet.RequestDispatcher.forward` and
|
||||||
`javax.servlet.RequestDispatcher.include` methods to create new `INTERNAL` spans around their
|
`javax.servlet.RequestDispatcher.include` methods to create new `INTERNAL` spans around their
|
||||||
invocations.
|
invocations.
|
||||||
|
|
||||||
`HttpServletResponseInstrumentation` instruments `javax.servlet.http.HttpServletResponse.sendError`
|
`HttpServletResponseInstrumentationModule` instruments `javax.servlet.http.HttpServletResponse.sendError`
|
||||||
and `javax.servlet.http.HttpServletResponse.sendRedirect` methods to create new `INTERNAL` spans
|
and `javax.servlet.http.HttpServletResponse.sendRedirect` methods to create new `INTERNAL` spans
|
||||||
around their invocations.
|
around their invocations.
|
||||||
|
|
|
@ -8,15 +8,12 @@ package io.opentelemetry.javaagent.instrumentation.servlet.v2_2;
|
||||||
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.safeHasSuperType;
|
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.safeHasSuperType;
|
||||||
import static io.opentelemetry.javaagent.tooling.matcher.NameMatchers.namedOneOf;
|
import static io.opentelemetry.javaagent.tooling.matcher.NameMatchers.namedOneOf;
|
||||||
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.not;
|
|
||||||
|
|
||||||
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.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.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
|
@ -38,16 +35,10 @@ import net.bytebuddy.matcher.ElementMatcher;
|
||||||
* ServletResponse, Throwable, Span, Scope)} can get it from context and set required span
|
* ServletResponse, Throwable, Span, Scope)} can get it from context and set required span
|
||||||
* attribute.
|
* attribute.
|
||||||
*/
|
*/
|
||||||
@AutoService(Instrumenter.class)
|
final class HttpServletResponseInstrumentation implements TypeInstrumentation {
|
||||||
public final class Servlet2ResponseStatusInstrumentation extends Instrumenter.Default {
|
|
||||||
public Servlet2ResponseStatusInstrumentation() {
|
|
||||||
super("servlet", "servlet-2");
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is required to make sure servlet 2 instrumentation won't apply to servlet 3
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
return not(hasClassesNamed("javax.servlet.AsyncEvent", "javax.servlet.AsyncListener"));
|
return hasClassesNamed("javax.servlet.http.HttpServletResponse");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -55,20 +46,15 @@ public final class Servlet2ResponseStatusInstrumentation extends Instrumenter.De
|
||||||
return safeHasSuperType(named("javax.servlet.http.HttpServletResponse"));
|
return safeHasSuperType(named("javax.servlet.http.HttpServletResponse"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> contextStore() {
|
|
||||||
return singletonMap("javax.servlet.ServletResponse", Integer.class.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@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<>();
|
||||||
transformers.put(
|
transformers.put(
|
||||||
namedOneOf("sendError", "setStatus"),
|
namedOneOf("sendError", "setStatus"),
|
||||||
Servlet2ResponseStatusInstrumentation.class.getName() + "$Servlet2ResponseStatusAdvice");
|
HttpServletResponseInstrumentation.class.getName() + "$Servlet2ResponseStatusAdvice");
|
||||||
transformers.put(
|
transformers.put(
|
||||||
named("sendRedirect"),
|
named("sendRedirect"),
|
||||||
Servlet2ResponseStatusInstrumentation.class.getName() + "$Servlet2ResponseRedirectAdvice");
|
HttpServletResponseInstrumentation.class.getName() + "$Servlet2ResponseRedirectAdvice");
|
||||||
return transformers;
|
return transformers;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.servlet.v2_2;
|
||||||
|
|
||||||
|
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
|
||||||
|
import static java.util.Collections.singletonMap;
|
||||||
|
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.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
|
|
||||||
|
@AutoService(InstrumentationModule.class)
|
||||||
|
public class Servlet2InstrumentationModule extends InstrumentationModule {
|
||||||
|
public Servlet2InstrumentationModule() {
|
||||||
|
super("servlet", "servlet-2");
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is required to make sure servlet 2 instrumentation won't apply to servlet 3
|
||||||
|
@Override
|
||||||
|
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
|
||||||
|
return not(hasClassesNamed("javax.servlet.AsyncEvent", "javax.servlet.AsyncListener"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] helperClassNames() {
|
||||||
|
return new String[] {
|
||||||
|
"io.opentelemetry.instrumentation.servlet.ServletHttpServerTracer",
|
||||||
|
"io.opentelemetry.instrumentation.servlet.HttpServletRequestGetter",
|
||||||
|
packageName + ".ResponseWithStatus",
|
||||||
|
packageName + ".Servlet2HttpServerTracer"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
|
return Arrays.asList(
|
||||||
|
new HttpServletResponseInstrumentation(), new ServletAndFilterChainInstrumentation());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> contextStore() {
|
||||||
|
return singletonMap("javax.servlet.ServletResponse", Integer.class.getName());
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,29 +11,20 @@ import static io.opentelemetry.javaagent.tooling.matcher.NameMatchers.namedOneOf
|
||||||
import static java.util.Collections.singletonMap;
|
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.not;
|
|
||||||
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.util.Map;
|
import java.util.Map;
|
||||||
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)
|
final class ServletAndFilterChainInstrumentation implements TypeInstrumentation {
|
||||||
public final class Servlet2Instrumentation extends Instrumenter.Default {
|
|
||||||
|
|
||||||
public Servlet2Instrumentation() {
|
|
||||||
super("servlet", "servlet-2");
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is required to make sure servlet 2 instrumentation won't apply to servlet 3
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
// Optimization for expensive typeMatcher.
|
// Optimization for expensive typeMatcher.
|
||||||
return hasClassesNamed("javax.servlet.http.HttpServlet")
|
return hasClassesNamed("javax.servlet.http.HttpServlet");
|
||||||
.and(not(hasClassesNamed("javax.servlet.AsyncEvent", "javax.servlet.AsyncListener")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -41,22 +32,6 @@ public final class Servlet2Instrumentation extends Instrumenter.Default {
|
||||||
return safeHasSuperType(
|
return safeHasSuperType(
|
||||||
namedOneOf("javax.servlet.FilterChain", "javax.servlet.http.HttpServlet"));
|
namedOneOf("javax.servlet.FilterChain", "javax.servlet.http.HttpServlet"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> contextStore() {
|
|
||||||
return singletonMap("javax.servlet.ServletResponse", Integer.class.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] helperClassNames() {
|
|
||||||
return new String[] {
|
|
||||||
"io.opentelemetry.instrumentation.servlet.ServletHttpServerTracer",
|
|
||||||
"io.opentelemetry.instrumentation.servlet.HttpServletRequestGetter",
|
|
||||||
packageName + ".ResponseWithStatus",
|
|
||||||
packageName + ".Servlet2HttpServerTracer"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Here we are instrumenting the public method for HttpServlet. This should ensure that this
|
* Here we are instrumenting the public method for HttpServlet. This should ensure that this
|
||||||
* advice is always called before HttpServletInstrumentation which is instrumenting the protected
|
* advice is always called before HttpServletInstrumentation which is instrumenting the protected
|
||||||
|
@ -69,6 +44,6 @@ public final class Servlet2Instrumentation extends Instrumenter.Default {
|
||||||
.and(takesArgument(0, named("javax.servlet.ServletRequest")))
|
.and(takesArgument(0, named("javax.servlet.ServletRequest")))
|
||||||
.and(takesArgument(1, named("javax.servlet.ServletResponse")))
|
.and(takesArgument(1, named("javax.servlet.ServletResponse")))
|
||||||
.and(isPublic()),
|
.and(isPublic()),
|
||||||
packageName + ".Servlet2Advice");
|
Servlet2Advice.class.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,12 +13,11 @@ 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;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
|
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
|
||||||
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.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.AsyncContext;
|
import javax.servlet.AsyncContext;
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
|
@ -27,20 +26,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 AsyncContextInstrumentation implements TypeInstrumentation {
|
||||||
public final class AsyncContextInstrumentation extends Instrumenter.Default {
|
|
||||||
|
|
||||||
public AsyncContextInstrumentation() {
|
|
||||||
super("servlet", "servlet-3");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] helperClassNames() {
|
|
||||||
return new String[] {
|
|
||||||
"io.opentelemetry.instrumentation.servlet.HttpServletRequestGetter",
|
|
||||||
"io.opentelemetry.instrumentation.servlet.ServletHttpServerTracer",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.servlet.v3_0;
|
||||||
|
|
||||||
|
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 Servlet3InstrumentationModule extends InstrumentationModule {
|
||||||
|
public Servlet3InstrumentationModule() {
|
||||||
|
super("servlet", "servlet-3");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] helperClassNames() {
|
||||||
|
return new String[] {
|
||||||
|
"io.opentelemetry.instrumentation.servlet.HttpServletRequestGetter",
|
||||||
|
"io.opentelemetry.instrumentation.servlet.ServletHttpServerTracer",
|
||||||
|
packageName + ".Servlet3Advice",
|
||||||
|
packageName + ".Servlet3HttpServerTracer",
|
||||||
|
packageName + ".TagSettingAsyncListener"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
|
return asList(new AsyncContextInstrumentation(), new ServletAndFilterChainInstrumentation());
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,19 +13,13 @@ 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.tooling.TypeInstrumentation;
|
||||||
import io.opentelemetry.javaagent.tooling.Instrumenter;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
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)
|
final class ServletAndFilterChainInstrumentation implements TypeInstrumentation {
|
||||||
public final class Servlet3Instrumentation extends Instrumenter.Default {
|
|
||||||
public Servlet3Instrumentation() {
|
|
||||||
super("servlet", "servlet-3");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
// Optimization for expensive typeMatcher.
|
// Optimization for expensive typeMatcher.
|
||||||
|
@ -38,17 +32,6 @@ public final class Servlet3Instrumentation extends Instrumenter.Default {
|
||||||
namedOneOf("javax.servlet.FilterChain", "javax.servlet.http.HttpServlet"));
|
namedOneOf("javax.servlet.FilterChain", "javax.servlet.http.HttpServlet"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] helperClassNames() {
|
|
||||||
return new String[] {
|
|
||||||
"io.opentelemetry.instrumentation.servlet.HttpServletRequestGetter",
|
|
||||||
"io.opentelemetry.instrumentation.servlet.ServletHttpServerTracer",
|
|
||||||
packageName + ".Servlet3Advice",
|
|
||||||
packageName + ".Servlet3HttpServerTracer",
|
|
||||||
packageName + ".TagSettingAsyncListener"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Here we are instrumenting the public method for HttpServlet. This should ensure that this
|
* Here we are instrumenting the public method for HttpServlet. This should ensure that this
|
||||||
* advice is always called before HttpServletInstrumentation which is instrumenting the protected
|
* advice is always called before HttpServletInstrumentation which is instrumenting the protected
|
||||||
|
@ -61,6 +44,6 @@ public final class Servlet3Instrumentation extends Instrumenter.Default {
|
||||||
.and(takesArgument(0, named("javax.servlet.ServletRequest")))
|
.and(takesArgument(0, named("javax.servlet.ServletRequest")))
|
||||||
.and(takesArgument(1, named("javax.servlet.ServletResponse")))
|
.and(takesArgument(1, named("javax.servlet.ServletResponse")))
|
||||||
.and(isPublic()),
|
.and(isPublic()),
|
||||||
packageName + ".Servlet3Advice");
|
Servlet3Advice.class.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,7 +4,12 @@ muzzle {
|
||||||
pass {
|
pass {
|
||||||
group = "javax.servlet"
|
group = "javax.servlet"
|
||||||
module = "servlet-api"
|
module = "servlet-api"
|
||||||
versions = "[2.2,)"
|
versions = "(0,)"
|
||||||
|
}
|
||||||
|
pass {
|
||||||
|
group = "javax.servlet"
|
||||||
|
module = 'javax.servlet-api'
|
||||||
|
versions = "[3.0,)"
|
||||||
assertInverse = true
|
assertInverse = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import static io.opentelemetry.javaagent.instrumentation.servlet.dispatcher.Requ
|
||||||
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 io.opentelemetry.javaagent.tooling.matcher.NameMatchers.namedOneOf;
|
import static io.opentelemetry.javaagent.tooling.matcher.NameMatchers.namedOneOf;
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.Collections.singletonMap;
|
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;
|
||||||
|
@ -22,8 +23,10 @@ import io.opentelemetry.api.trace.SpanContext;
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
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.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.RequestDispatcher;
|
import javax.servlet.RequestDispatcher;
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
|
@ -32,23 +35,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 RequestDispatcherInstrumentation extends Instrumenter.Default {
|
public final class RequestDispatcherInstrumentationModule extends InstrumentationModule {
|
||||||
public RequestDispatcherInstrumentation() {
|
public RequestDispatcherInstrumentationModule() {
|
||||||
super("servlet", "servlet-dispatcher");
|
super("servlet", "servlet-dispatcher");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
|
||||||
// Optimization for expensive typeMatcher.
|
|
||||||
return hasClassesNamed("javax.servlet.RequestDispatcher");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
|
||||||
return implementsInterface(named("javax.servlet.RequestDispatcher"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
|
@ -56,20 +48,38 @@ public final class RequestDispatcherInstrumentation extends Instrumenter.Default
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
|
return singletonList(new RequestDispatcherInstrumentation());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> contextStore() {
|
public Map<String, String> contextStore() {
|
||||||
return singletonMap("javax.servlet.RequestDispatcher", String.class.getName());
|
return singletonMap("javax.servlet.RequestDispatcher", String.class.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private static final class RequestDispatcherInstrumentation implements TypeInstrumentation {
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
@Override
|
||||||
return singletonMap(
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
namedOneOf("forward", "include")
|
// Optimization for expensive typeMatcher.
|
||||||
.and(takesArguments(2))
|
return hasClassesNamed("javax.servlet.RequestDispatcher");
|
||||||
.and(takesArgument(0, named("javax.servlet.ServletRequest")))
|
}
|
||||||
.and(takesArgument(1, named("javax.servlet.ServletResponse")))
|
|
||||||
.and(isPublic()),
|
@Override
|
||||||
getClass().getName() + "$RequestDispatcherAdvice");
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
return implementsInterface(named("javax.servlet.RequestDispatcher"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return singletonMap(
|
||||||
|
namedOneOf("forward", "include")
|
||||||
|
.and(takesArguments(2))
|
||||||
|
.and(takesArgument(0, named("javax.servlet.ServletRequest")))
|
||||||
|
.and(takesArgument(1, named("javax.servlet.ServletResponse")))
|
||||||
|
.and(isPublic()),
|
||||||
|
RequestDispatcherInstrumentationModule.class.getName() + "$RequestDispatcherAdvice");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RequestDispatcherAdvice {
|
public static class RequestDispatcherAdvice {
|
|
@ -8,6 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.servlet.filter;
|
||||||
import static io.opentelemetry.javaagent.instrumentation.servlet.filter.FilterTracer.tracer;
|
import static io.opentelemetry.javaagent.instrumentation.servlet.filter.FilterTracer.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.singletonList;
|
||||||
import static java.util.Collections.singletonMap;
|
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;
|
||||||
|
@ -18,7 +19,9 @@ 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.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.servlet.Filter;
|
import javax.servlet.Filter;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
|
@ -31,9 +34,9 @@ import net.bytebuddy.matcher.ElementMatcher;
|
||||||
*
|
*
|
||||||
* <p>See README.md for more information about different servlet instrumentations.
|
* <p>See README.md for more information about different servlet instrumentations.
|
||||||
*/
|
*/
|
||||||
@AutoService(Instrumenter.class)
|
@AutoService(InstrumentationModule.class)
|
||||||
public final class FilterInstrumentation extends Instrumenter.Default {
|
public final class FilterInstrumentationModule extends InstrumentationModule {
|
||||||
public FilterInstrumentation() {
|
public FilterInstrumentationModule() {
|
||||||
super("servlet-filter");
|
super("servlet-filter");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,18 +45,6 @@ public final class FilterInstrumentation extends Instrumenter.Default {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
|
||||||
// Optimization for expensive typeMatcher.
|
|
||||||
// return hasClassesNamed("javax.servlet.Filter"); // Not available in 2.2
|
|
||||||
return hasClassesNamed("javax.servlet.http.HttpServlet");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
|
||||||
return implementsInterface(named("javax.servlet.Filter"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
|
@ -62,13 +53,31 @@ public final class FilterInstrumentation extends Instrumenter.Default {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
return singletonMap(
|
return singletonList(new FilterInstrumentation());
|
||||||
named("doFilter")
|
}
|
||||||
.and(takesArgument(0, named("javax.servlet.ServletRequest")))
|
|
||||||
.and(takesArgument(1, named("javax.servlet.ServletResponse")))
|
private static final class FilterInstrumentation implements TypeInstrumentation {
|
||||||
.and(isPublic()),
|
@Override
|
||||||
getClass().getName() + "$FilterAdvice");
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
|
// Optimization for expensive typeMatcher.
|
||||||
|
return hasClassesNamed("javax.servlet.Filter");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
return implementsInterface(named("javax.servlet.Filter"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return singletonMap(
|
||||||
|
named("doFilter")
|
||||||
|
.and(takesArgument(0, named("javax.servlet.ServletRequest")))
|
||||||
|
.and(takesArgument(1, named("javax.servlet.ServletResponse")))
|
||||||
|
.and(isPublic()),
|
||||||
|
FilterInstrumentationModule.class.getName() + "$FilterAdvice");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FilterAdvice {
|
public static class FilterAdvice {
|
|
@ -8,6 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.servlet.http;
|
||||||
import static io.opentelemetry.javaagent.instrumentation.servlet.http.HttpServletTracer.tracer;
|
import static io.opentelemetry.javaagent.instrumentation.servlet.http.HttpServletTracer.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.extendsClass;
|
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass;
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.Collections.singletonMap;
|
import static java.util.Collections.singletonMap;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isProtected;
|
import static net.bytebuddy.matcher.ElementMatchers.isProtected;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||||
|
@ -19,18 +20,21 @@ 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.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
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;
|
||||||
|
|
||||||
// Please read README.md of this subproject to understand what is this instrumentation.
|
// Please read README.md of this subproject to understand what this instrumentation is and why it
|
||||||
@AutoService(Instrumenter.class)
|
// requires a separate module.
|
||||||
public final class HttpServletInstrumentation extends Instrumenter.Default {
|
@AutoService(InstrumentationModule.class)
|
||||||
public HttpServletInstrumentation() {
|
public final class HttpServletInstrumentationModule extends InstrumentationModule {
|
||||||
|
public HttpServletInstrumentationModule() {
|
||||||
super("servlet-service");
|
super("servlet-service");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,17 +43,6 @@ public final class HttpServletInstrumentation extends Instrumenter.Default {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
|
||||||
// Optimization for expensive typeMatcher.
|
|
||||||
return hasClassesNamed("javax.servlet.http.HttpServlet");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
|
||||||
return extendsClass(named("javax.servlet.http.HttpServlet"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
|
@ -57,19 +50,38 @@ public final class HttpServletInstrumentation extends Instrumenter.Default {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Here we are instrumenting the protected method for HttpServlet. This should ensure that this
|
|
||||||
* advice is always called after Servlet3Instrumentation which is instrumenting the public method.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
return singletonMap(
|
return singletonList(new HttpServletInstrumentation());
|
||||||
named("service")
|
}
|
||||||
.or(nameStartsWith("do")) // doGet, doPost, etc
|
|
||||||
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest")))
|
private static final class HttpServletInstrumentation implements TypeInstrumentation {
|
||||||
.and(takesArgument(1, named("javax.servlet.http.HttpServletResponse")))
|
@Override
|
||||||
.and(isProtected().or(isPublic())),
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
getClass().getName() + "$HttpServletAdvice");
|
// Optimization for expensive typeMatcher.
|
||||||
|
return hasClassesNamed("javax.servlet.http.HttpServlet");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
return extendsClass(named("javax.servlet.http.HttpServlet"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Here we are instrumenting the protected method for HttpServlet. This should ensure that this
|
||||||
|
* advice is always called after Servlet3Instrumentation which is instrumenting the public
|
||||||
|
* method.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return singletonMap(
|
||||||
|
named("service")
|
||||||
|
.or(nameStartsWith("do")) // doGet, doPost, etc
|
||||||
|
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest")))
|
||||||
|
.and(takesArgument(1, named("javax.servlet.http.HttpServletResponse")))
|
||||||
|
.and(isProtected().or(isPublic())),
|
||||||
|
HttpServletInstrumentationModule.class.getName() + "$HttpServletAdvice");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class HttpServletAdvice {
|
public static class HttpServletAdvice {
|
|
@ -9,6 +9,7 @@ import static io.opentelemetry.javaagent.instrumentation.servlet.http.HttpServle
|
||||||
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 io.opentelemetry.javaagent.tooling.matcher.NameMatchers.namedOneOf;
|
import static io.opentelemetry.javaagent.tooling.matcher.NameMatchers.namedOneOf;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@ -18,8 +19,10 @@ 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.CallDepthThreadLocalMap.Depth;
|
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap.Depth;
|
||||||
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.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
|
@ -27,23 +30,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 HttpServletResponseInstrumentation extends Instrumenter.Default {
|
public final class HttpServletResponseInstrumentationModule extends InstrumentationModule {
|
||||||
public HttpServletResponseInstrumentation() {
|
public HttpServletResponseInstrumentationModule() {
|
||||||
super("servlet", "servlet-response");
|
super("servlet", "servlet-response");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
|
||||||
// Optimization for expensive typeMatcher.
|
|
||||||
return hasClassesNamed("javax.servlet.http.HttpServletResponse");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
|
||||||
return implementsInterface(named("javax.servlet.http.HttpServletResponse"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
|
@ -52,8 +44,26 @@ public final class HttpServletResponseInstrumentation extends Instrumenter.Defau
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
return singletonMap(namedOneOf("sendError", "sendRedirect"), SendAdvice.class.getName());
|
return singletonList(new HttpServletResponseInstrumentation());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class HttpServletResponseInstrumentation implements TypeInstrumentation {
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
|
// Optimization for expensive typeMatcher.
|
||||||
|
return hasClassesNamed("javax.servlet.http.HttpServletResponse");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
return implementsInterface(named("javax.servlet.http.HttpServletResponse"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return singletonMap(namedOneOf("sendError", "sendRedirect"), SendAdvice.class.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SendAdvice {
|
public static class SendAdvice {
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.sparkjava;
|
package io.opentelemetry.javaagent.instrumentation.sparkjava;
|
||||||
|
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.Collections.singletonMap;
|
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;
|
||||||
|
@ -12,11 +13,11 @@ 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 com.google.auto.service.AutoService;
|
||||||
import io.opentelemetry.api.OpenTelemetry;
|
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
import io.opentelemetry.api.trace.Tracer;
|
|
||||||
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 net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
import net.bytebuddy.description.method.MethodDescription;
|
import net.bytebuddy.description.method.MethodDescription;
|
||||||
|
@ -24,41 +25,32 @@ import net.bytebuddy.description.type.TypeDescription;
|
||||||
import net.bytebuddy.matcher.ElementMatcher;
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
import spark.routematch.RouteMatch;
|
import spark.routematch.RouteMatch;
|
||||||
|
|
||||||
@AutoService(Instrumenter.class)
|
@AutoService(InstrumentationModule.class)
|
||||||
public class RoutesInstrumentation extends Instrumenter.Default {
|
public class SparkInstrumentationModule extends InstrumentationModule {
|
||||||
|
|
||||||
public RoutesInstrumentation() {
|
public SparkInstrumentationModule() {
|
||||||
super("sparkjava", "sparkjava-2.4");
|
super("sparkjava", "sparkjava-2.4");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
return named("spark.route.Routes");
|
return singletonList(new RoutesInstrumentation());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private static final class RoutesInstrumentation implements TypeInstrumentation {
|
||||||
public String[] helperClassNames() {
|
@Override
|
||||||
return new String[] {
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
RoutesInstrumentation.class.getName() + "$TracerHolder",
|
return named("spark.route.Routes");
|
||||||
};
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
return singletonMap(
|
return singletonMap(
|
||||||
named("find")
|
named("find")
|
||||||
.and(takesArgument(0, named("spark.route.HttpMethod")))
|
.and(takesArgument(0, named("spark.route.HttpMethod")))
|
||||||
.and(returns(named("spark.routematch.RouteMatch")))
|
.and(returns(named("spark.routematch.RouteMatch")))
|
||||||
.and(isPublic()),
|
.and(isPublic()),
|
||||||
RoutesInstrumentation.class.getName() + "$RoutesAdvice");
|
SparkInstrumentationModule.class.getName() + "$RoutesAdvice");
|
||||||
}
|
|
||||||
|
|
||||||
public static class TracerHolder {
|
|
||||||
private static final Tracer TRACER =
|
|
||||||
OpenTelemetry.getGlobalTracer("io.opentelemetry.auto.sparkjava-2.3");
|
|
||||||
|
|
||||||
public static Tracer tracer() {
|
|
||||||
return TRACER;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
package io.opentelemetry.javaagent.instrumentation.spring.data;
|
package io.opentelemetry.javaagent.instrumentation.spring.data;
|
||||||
|
|
||||||
import static io.opentelemetry.javaagent.instrumentation.spring.data.SpringDataTracer.tracer;
|
import static io.opentelemetry.javaagent.instrumentation.spring.data.SpringDataTracer.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.isConstructor;
|
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
@ -13,8 +14,10 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
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 io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
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;
|
||||||
|
@ -28,18 +31,13 @@ import org.springframework.data.repository.core.RepositoryInformation;
|
||||||
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
|
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
|
||||||
import org.springframework.data.repository.core.support.RepositoryProxyPostProcessor;
|
import org.springframework.data.repository.core.support.RepositoryProxyPostProcessor;
|
||||||
|
|
||||||
@AutoService(Instrumenter.class)
|
@AutoService(InstrumentationModule.class)
|
||||||
public final class SpringRepositoryInstrumentation extends Instrumenter.Default {
|
public final class SpringDataInstrumentationModule extends InstrumentationModule {
|
||||||
|
|
||||||
public SpringRepositoryInstrumentation() {
|
public SpringDataInstrumentationModule() {
|
||||||
super("spring-data");
|
super("spring-data");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
|
||||||
return named("org.springframework.data.repository.core.support.RepositoryFactorySupport");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
|
@ -50,10 +48,23 @@ public final class SpringRepositoryInstrumentation extends Instrumenter.Default
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
return singletonMap(
|
return singletonList(new RepositoryFactorySupportInstrumentation());
|
||||||
isConstructor(),
|
}
|
||||||
SpringRepositoryInstrumentation.class.getName() + "$RepositoryFactorySupportAdvice");
|
|
||||||
|
private static final class RepositoryFactorySupportInstrumentation
|
||||||
|
implements TypeInstrumentation {
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
return named("org.springframework.data.repository.core.support.RepositoryFactorySupport");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return singletonMap(
|
||||||
|
isConstructor(),
|
||||||
|
SpringDataInstrumentationModule.class.getName() + "$RepositoryFactorySupportAdvice");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RepositoryFactorySupportAdvice {
|
public static class RepositoryFactorySupportAdvice {
|
|
@ -5,31 +5,29 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.spring.scheduling;
|
package io.opentelemetry.javaagent.instrumentation.spring.scheduling;
|
||||||
|
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.Collections.singletonMap;
|
import static java.util.Collections.singletonMap;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
|
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
|
||||||
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 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 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 SpringSchedulingInstrumentation extends Instrumenter.Default {
|
public final class SpringSchedulingInstrumentationModule extends InstrumentationModule {
|
||||||
|
|
||||||
public SpringSchedulingInstrumentation() {
|
public SpringSchedulingInstrumentationModule() {
|
||||||
super("spring-scheduling");
|
super("spring-scheduling");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
|
||||||
return named("org.springframework.scheduling.config.Task");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
|
@ -38,10 +36,22 @@ public final class SpringSchedulingInstrumentation extends Instrumenter.Default
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
return singletonMap(
|
return singletonList(new TaskInstrumentation());
|
||||||
isConstructor().and(takesArgument(0, Runnable.class)),
|
}
|
||||||
SpringSchedulingInstrumentation.class.getName() + "$SpringSchedulingAdvice");
|
|
||||||
|
private static final class TaskInstrumentation implements TypeInstrumentation {
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
return named("org.springframework.scheduling.config.Task");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return singletonMap(
|
||||||
|
isConstructor().and(takesArgument(0, Runnable.class)),
|
||||||
|
SpringSchedulingInstrumentationModule.class.getName() + "$SpringSchedulingAdvice");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SpringSchedulingAdvice {
|
public static class SpringSchedulingAdvice {
|
|
@ -7,31 +7,28 @@ package io.opentelemetry.javaagent.instrumentation.spring.webflux.client;
|
||||||
|
|
||||||
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.singletonList;
|
||||||
import static java.util.Collections.singletonMap;
|
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;
|
||||||
|
|
||||||
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 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 class WebClientFilterInstrumentation extends Instrumenter.Default {
|
public class WebfluxClientInstrumentationModule extends InstrumentationModule {
|
||||||
|
|
||||||
public WebClientFilterInstrumentation() {
|
public WebfluxClientInstrumentationModule() {
|
||||||
super("spring-webflux", "spring-webflux-client");
|
super("spring-webflux", "spring-webflux-client");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
|
||||||
// Optimization for expensive typeMatcher.
|
|
||||||
return hasClassesNamed("org.springframework.web.reactive.function.client.WebClient");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
|
@ -44,14 +41,27 @@ public class WebClientFilterInstrumentation extends Instrumenter.Default {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
return implementsInterface(
|
return singletonList(new WebClientBuilderInstrumentation());
|
||||||
named("org.springframework.web.reactive.function.client.WebClient$Builder"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private static final class WebClientBuilderInstrumentation implements TypeInstrumentation {
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
@Override
|
||||||
return singletonMap(
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
isMethod().and(isPublic()).and(named("build")), packageName + ".WebClientFilterAdvice");
|
// Optimization for expensive typeMatcher.
|
||||||
|
return hasClassesNamed("org.springframework.web.reactive.function.client.WebClient");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
||||||
|
return implementsInterface(
|
||||||
|
named("org.springframework.web.reactive.function.client.WebClient$Builder"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return singletonMap(
|
||||||
|
isMethod().and(isPublic()).and(named("build")), WebClientFilterAdvice.class.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.spring.webflux.server;
|
|
||||||
|
|
||||||
import io.opentelemetry.javaagent.tooling.Instrumenter;
|
|
||||||
|
|
||||||
public abstract class AbstractWebfluxInstrumentation extends Instrumenter.Default {
|
|
||||||
|
|
||||||
public AbstractWebfluxInstrumentation(String... additionalNames) {
|
|
||||||
super("spring-webflux", additionalNames);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] helperClassNames() {
|
|
||||||
return new String[] {
|
|
||||||
packageName + ".SpringWebfluxHttpServerTracer",
|
|
||||||
packageName + ".AdviceUtils",
|
|
||||||
packageName + ".AdviceUtils$SpanFinishingSubscriber",
|
|
||||||
packageName + ".RouteOnSuccessOrError"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,15 +12,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 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 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)
|
final class DispatcherHandlerInstrumentation implements TypeInstrumentation {
|
||||||
public final class DispatcherHandlerInstrumentation extends AbstractWebfluxInstrumentation {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
@ -35,7 +33,6 @@ public final class DispatcherHandlerInstrumentation extends AbstractWebfluxInstr
|
||||||
.and(named("handle"))
|
.and(named("handle"))
|
||||||
.and(takesArgument(0, named("org.springframework.web.server.ServerWebExchange")))
|
.and(takesArgument(0, named("org.springframework.web.server.ServerWebExchange")))
|
||||||
.and(takesArguments(1)),
|
.and(takesArguments(1)),
|
||||||
// Cannot reference class directly here because it would lead to class load failure on Java7
|
DispatcherHandlerAdvice.class.getName());
|
||||||
packageName + ".DispatcherHandlerAdvice");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,15 +16,13 @@ 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.tooling.TypeInstrumentation;
|
||||||
import io.opentelemetry.javaagent.tooling.Instrumenter;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
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)
|
final class HandlerAdapterInstrumentation implements TypeInstrumentation {
|
||||||
public final class HandlerAdapterInstrumentation extends AbstractWebfluxInstrumentation {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
|
@ -47,7 +45,6 @@ public final class HandlerAdapterInstrumentation extends AbstractWebfluxInstrume
|
||||||
.and(takesArgument(0, named("org.springframework.web.server.ServerWebExchange")))
|
.and(takesArgument(0, named("org.springframework.web.server.ServerWebExchange")))
|
||||||
.and(takesArgument(1, named("java.lang.Object")))
|
.and(takesArgument(1, named("java.lang.Object")))
|
||||||
.and(takesArguments(2)),
|
.and(takesArguments(2)),
|
||||||
// Cannot reference class directly here because it would lead to class load failure on Java7
|
HandlerAdapterAdvice.class.getName());
|
||||||
packageName + ".HandlerAdapterAdvice");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,19 +16,13 @@ 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.tooling.TypeInstrumentation;
|
||||||
import io.opentelemetry.javaagent.tooling.Instrumenter;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
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)
|
final class RouterFunctionInstrumentation implements TypeInstrumentation {
|
||||||
public final class RouterFunctionInstrumentation extends AbstractWebfluxInstrumentation {
|
|
||||||
|
|
||||||
public RouterFunctionInstrumentation() {
|
|
||||||
super("spring-webflux-functional");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
|
@ -56,7 +50,6 @@ public final class RouterFunctionInstrumentation extends AbstractWebfluxInstrume
|
||||||
takesArgument(
|
takesArgument(
|
||||||
0, named("org.springframework.web.reactive.function.server.ServerRequest")))
|
0, named("org.springframework.web.reactive.function.server.ServerRequest")))
|
||||||
.and(takesArguments(1)),
|
.and(takesArguments(1)),
|
||||||
// Cannot reference class directly here because it would lead to class load failure on Java7
|
RouterFunctionAdvice.class.getName());
|
||||||
packageName + ".RouterFunctionAdvice");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.spring.webflux.server;
|
||||||
|
|
||||||
|
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 WebfluxServerInstrumentationModule extends InstrumentationModule {
|
||||||
|
|
||||||
|
public WebfluxServerInstrumentationModule() {
|
||||||
|
super("spring-webflux", "spring-webflux-server");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] helperClassNames() {
|
||||||
|
return new String[] {
|
||||||
|
packageName + ".SpringWebfluxHttpServerTracer",
|
||||||
|
packageName + ".AdviceUtils",
|
||||||
|
packageName + ".AdviceUtils$SpanFinishingSubscriber",
|
||||||
|
packageName + ".RouteOnSuccessOrError"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
|
return asList(
|
||||||
|
new DispatcherHandlerInstrumentation(),
|
||||||
|
new HandlerAdapterInstrumentation(),
|
||||||
|
new RouterFunctionInstrumentation());
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
package io.opentelemetry.javaagent.instrumentation.spymemcached;
|
package io.opentelemetry.javaagent.instrumentation.spymemcached;
|
||||||
|
|
||||||
import static io.opentelemetry.javaagent.tooling.matcher.NameMatchers.namedOneOf;
|
import static io.opentelemetry.javaagent.tooling.matcher.NameMatchers.namedOneOf;
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
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 +15,10 @@ import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
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.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;
|
||||||
|
@ -26,20 +29,13 @@ import net.spy.memcached.internal.BulkFuture;
|
||||||
import net.spy.memcached.internal.GetFuture;
|
import net.spy.memcached.internal.GetFuture;
|
||||||
import net.spy.memcached.internal.OperationFuture;
|
import net.spy.memcached.internal.OperationFuture;
|
||||||
|
|
||||||
@AutoService(Instrumenter.class)
|
@AutoService(InstrumentationModule.class)
|
||||||
public final class MemcachedClientInstrumentation extends Instrumenter.Default {
|
public final class SpymemcachedInstrumentationModule extends InstrumentationModule {
|
||||||
|
|
||||||
private static final String MEMCACHED_PACKAGE = "net.spy.memcached";
|
public SpymemcachedInstrumentationModule() {
|
||||||
|
|
||||||
public MemcachedClientInstrumentation() {
|
|
||||||
super("spymemcached");
|
super("spymemcached");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
|
||||||
return named(MEMCACHED_PACKAGE + ".MemcachedClient");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
|
@ -53,28 +49,40 @@ public final class MemcachedClientInstrumentation extends Instrumenter.Default {
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 MemcachedClientInstrumentation());
|
||||||
transformers.put(
|
}
|
||||||
isMethod()
|
|
||||||
.and(isPublic())
|
private static final class MemcachedClientInstrumentation implements TypeInstrumentation {
|
||||||
.and(returns(named(MEMCACHED_PACKAGE + ".internal.OperationFuture")))
|
@Override
|
||||||
/*
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
Flush seems to have a bug when listeners may not be always called.
|
return named("net.spy.memcached.MemcachedClient");
|
||||||
Also tracing flush is probably of a very limited value.
|
}
|
||||||
*/
|
|
||||||
.and(not(named("flush"))),
|
@Override
|
||||||
MemcachedClientInstrumentation.class.getName() + "$AsyncOperationAdvice");
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
transformers.put(
|
Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>();
|
||||||
isMethod().and(isPublic()).and(returns(named(MEMCACHED_PACKAGE + ".internal.GetFuture"))),
|
transformers.put(
|
||||||
MemcachedClientInstrumentation.class.getName() + "$AsyncGetAdvice");
|
isMethod()
|
||||||
transformers.put(
|
.and(isPublic())
|
||||||
isMethod().and(isPublic()).and(returns(named(MEMCACHED_PACKAGE + ".internal.BulkFuture"))),
|
.and(returns(named("net.spy.memcached.internal.OperationFuture")))
|
||||||
MemcachedClientInstrumentation.class.getName() + "$AsyncBulkAdvice");
|
/*
|
||||||
transformers.put(
|
Flush seems to have a bug when listeners may not be always called.
|
||||||
isMethod().and(isPublic()).and(namedOneOf("incr", "decr")),
|
Also tracing flush is probably of a very limited value.
|
||||||
MemcachedClientInstrumentation.class.getName() + "$SyncOperationAdvice");
|
*/
|
||||||
return transformers;
|
.and(not(named("flush"))),
|
||||||
|
SpymemcachedInstrumentationModule.class.getName() + "$AsyncOperationAdvice");
|
||||||
|
transformers.put(
|
||||||
|
isMethod().and(isPublic()).and(returns(named("net.spy.memcached.internal.GetFuture"))),
|
||||||
|
SpymemcachedInstrumentationModule.class.getName() + "$AsyncGetAdvice");
|
||||||
|
transformers.put(
|
||||||
|
isMethod().and(isPublic()).and(returns(named("net.spy.memcached.internal.BulkFuture"))),
|
||||||
|
SpymemcachedInstrumentationModule.class.getName() + "$AsyncBulkAdvice");
|
||||||
|
transformers.put(
|
||||||
|
isMethod().and(isPublic()).and(namedOneOf("incr", "decr")),
|
||||||
|
SpymemcachedInstrumentationModule.class.getName() + "$SyncOperationAdvice");
|
||||||
|
return transformers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AsyncOperationAdvice {
|
public static class AsyncOperationAdvice {
|
||||||
|
@ -89,7 +97,7 @@ public final class MemcachedClientInstrumentation extends Instrumenter.Default {
|
||||||
@Advice.Enter int callDepth,
|
@Advice.Enter int callDepth,
|
||||||
@Advice.This MemcachedClient client,
|
@Advice.This MemcachedClient client,
|
||||||
@Advice.Origin("#m") String methodName,
|
@Advice.Origin("#m") String methodName,
|
||||||
@Advice.Return OperationFuture future) {
|
@Advice.Return OperationFuture<?> future) {
|
||||||
if (callDepth > 0) {
|
if (callDepth > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +123,7 @@ public final class MemcachedClientInstrumentation extends Instrumenter.Default {
|
||||||
@Advice.Enter int callDepth,
|
@Advice.Enter int callDepth,
|
||||||
@Advice.This MemcachedClient client,
|
@Advice.This MemcachedClient client,
|
||||||
@Advice.Origin("#m") String methodName,
|
@Advice.Origin("#m") String methodName,
|
||||||
@Advice.Return GetFuture future) {
|
@Advice.Return GetFuture<?> future) {
|
||||||
if (callDepth > 0) {
|
if (callDepth > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -141,7 +149,7 @@ public final class MemcachedClientInstrumentation extends Instrumenter.Default {
|
||||||
@Advice.Enter int callDepth,
|
@Advice.Enter int callDepth,
|
||||||
@Advice.This MemcachedClient client,
|
@Advice.This MemcachedClient client,
|
||||||
@Advice.Origin("#m") String methodName,
|
@Advice.Origin("#m") String methodName,
|
||||||
@Advice.Return BulkFuture future) {
|
@Advice.Return BulkFuture<?> future) {
|
||||||
if (callDepth > 0) {
|
if (callDepth > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
|
@ -19,7 +19,6 @@ 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.returns;
|
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
@ -27,19 +26,14 @@ import com.twilio.Twilio;
|
||||||
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.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.matcher.ElementMatcher;
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
|
|
||||||
/** Instrument the Twilio SDK to identify calls as a seperate service. */
|
/** Instrument the Twilio SDK to identify calls as a separate service. */
|
||||||
@AutoService(Instrumenter.class)
|
final class TwilioAsyncInstrumentation implements TypeInstrumentation {
|
||||||
public class TwilioAsyncInstrumentation extends Instrumenter.Default {
|
|
||||||
|
|
||||||
public TwilioAsyncInstrumentation() {
|
|
||||||
super("twilio-sdk");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
|
@ -59,15 +53,6 @@ public class TwilioAsyncInstrumentation extends Instrumenter.Default {
|
||||||
"com.twilio.base.Updater"));
|
"com.twilio.base.Updater"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the helper classes which will be available for use in instrumentation. */
|
|
||||||
@Override
|
|
||||||
public String[] helperClassNames() {
|
|
||||||
return new String[] {
|
|
||||||
packageName + ".TwilioClientDecorator",
|
|
||||||
packageName + ".TwilioAsyncInstrumentation$SpanFinishingCallback",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return bytebuddy transformers for instrumenting the Twilio SDK. */
|
/** Return bytebuddy transformers for instrumenting the Twilio SDK. */
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
@ -122,7 +107,7 @@ public class TwilioAsyncInstrumentation extends Instrumenter.Default {
|
||||||
public static void methodExit(
|
public static void methodExit(
|
||||||
@Advice.Enter SpanWithScope spanWithScope,
|
@Advice.Enter SpanWithScope spanWithScope,
|
||||||
@Advice.Thrown Throwable throwable,
|
@Advice.Thrown Throwable throwable,
|
||||||
@Advice.Return ListenableFuture response) {
|
@Advice.Return ListenableFuture<?> response) {
|
||||||
if (spanWithScope == null) {
|
if (spanWithScope == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -142,7 +127,7 @@ public class TwilioAsyncInstrumentation extends Instrumenter.Default {
|
||||||
// We're calling an async operation, we still need to finish the span when it's
|
// We're calling an async operation, we still need to finish the span when it's
|
||||||
// complete and report the results; set an appropriate callback
|
// complete and report the results; set an appropriate callback
|
||||||
Futures.addCallback(
|
Futures.addCallback(
|
||||||
response, new SpanFinishingCallback(span), Twilio.getExecutorService());
|
response, new SpanFinishingCallback<>(span), Twilio.getExecutorService());
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
spanWithScope.closeScope();
|
spanWithScope.closeScope();
|
||||||
|
@ -155,7 +140,7 @@ public class TwilioAsyncInstrumentation extends Instrumenter.Default {
|
||||||
* FutureCallback, which automatically finishes the span and annotates with any appropriate
|
* FutureCallback, which automatically finishes the span and annotates with any appropriate
|
||||||
* metadata on a potential failure.
|
* metadata on a potential failure.
|
||||||
*/
|
*/
|
||||||
public static class SpanFinishingCallback implements FutureCallback {
|
public static class SpanFinishingCallback<T> implements FutureCallback<T> {
|
||||||
|
|
||||||
/** Span that we should finish and annotate when the future is complete. */
|
/** Span that we should finish and annotate when the future is complete. */
|
||||||
private final Span span;
|
private final Span span;
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.twilio;
|
||||||
|
|
||||||
|
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 TwilioInstrumentationModule extends InstrumentationModule {
|
||||||
|
public TwilioInstrumentationModule() {
|
||||||
|
super("twilio-sdk");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] helperClassNames() {
|
||||||
|
return new String[] {
|
||||||
|
packageName + ".TwilioClientDecorator",
|
||||||
|
packageName + ".TwilioAsyncInstrumentation$SpanFinishingCallback",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
|
return asList(new TwilioAsyncInstrumentation(), new TwilioSyncInstrumentation());
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,24 +17,18 @@ 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.not;
|
import static net.bytebuddy.matcher.ElementMatchers.not;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
|
||||||
import com.twilio.Twilio;
|
import com.twilio.Twilio;
|
||||||
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.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.matcher.ElementMatcher;
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
|
|
||||||
/** Instrument the Twilio SDK to identify calls as a seperate service. */
|
/** Instrument the Twilio SDK to identify calls as a separate service. */
|
||||||
@AutoService(Instrumenter.class)
|
final class TwilioSyncInstrumentation implements TypeInstrumentation {
|
||||||
public class TwilioSyncInstrumentation extends Instrumenter.Default {
|
|
||||||
|
|
||||||
public TwilioSyncInstrumentation() {
|
|
||||||
super("twilio-sdk");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
|
@ -56,14 +50,6 @@ public class TwilioSyncInstrumentation extends Instrumenter.Default {
|
||||||
"com.twilio.base.Updater"));
|
"com.twilio.base.Updater"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the helper classes which will be available for use in instrumentation. */
|
|
||||||
@Override
|
|
||||||
public String[] helperClassNames() {
|
|
||||||
return new String[] {
|
|
||||||
packageName + ".TwilioClientDecorator",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return bytebuddy transformers for instrumenting the Twilio SDK. */
|
/** Return bytebuddy transformers for instrumenting the Twilio SDK. */
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
|
|
@ -7,6 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.vertx;
|
||||||
|
|
||||||
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.safeHasSuperType;
|
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.safeHasSuperType;
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.Collections.singletonMap;
|
import static java.util.Collections.singletonMap;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
|
@ -15,32 +16,24 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||||
|
|
||||||
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 io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
|
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 RouteInstrumentation extends Instrumenter.Default {
|
public final class VertxInstrumentationModule extends InstrumentationModule {
|
||||||
|
|
||||||
public RouteInstrumentation() {
|
public VertxInstrumentationModule() {
|
||||||
super("vertx");
|
super("vertx");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
|
||||||
return hasClassesNamed("io.vertx.ext.web.Route");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
|
||||||
return not(isInterface()).and(safeHasSuperType(named("io.vertx.ext.web.Route")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
|
@ -49,10 +42,27 @@ public final class RouteInstrumentation extends Instrumenter.Default {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
return singletonMap(
|
return singletonList(new RouteInstrumentation());
|
||||||
isMethod().and(named("handler")).and(takesArgument(0, named("io.vertx.core.Handler"))),
|
}
|
||||||
RouteInstrumentation.class.getName() + "$RouteAdvice");
|
|
||||||
|
private static final class RouteInstrumentation implements TypeInstrumentation {
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
|
return hasClassesNamed("io.vertx.ext.web.Route");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
return not(isInterface()).and(safeHasSuperType(named("io.vertx.ext.web.Route")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return singletonMap(
|
||||||
|
isMethod().and(named("handler")).and(takesArgument(0, named("io.vertx.core.Handler"))),
|
||||||
|
VertxInstrumentationModule.class.getName() + "$RouteAdvice");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RouteAdvice {
|
public static class RouteAdvice {
|
|
@ -2,9 +2,9 @@
|
||||||
* The majority of monitoring needs of Vert.x application is covered by generic instrumentations.
|
* The majority of monitoring needs of Vert.x application is covered by generic instrumentations.
|
||||||
* Such as those of netty or JDBC.
|
* Such as those of netty or JDBC.
|
||||||
*
|
*
|
||||||
* <p>{@link io.opentelemetry.javaagent.instrumentation.vertx.RouteInstrumentation} wraps all Vert.x
|
* <p>{@link io.opentelemetry.javaagent.instrumentation.vertx.VertxInstrumentationModule} wraps all
|
||||||
* route handlers in order to update the name of the currently active SERVER span with the name of
|
* Vert.x route handlers in order to update the name of the currently active SERVER span with the
|
||||||
* route. This is, arguably, a much more user-friendly name that defaults provided by HTTP server
|
* name of route. This is, arguably, a much more user-friendly name that defaults provided by HTTP
|
||||||
* instrumentations.
|
* server instrumentations.
|
||||||
*/
|
*/
|
||||||
package io.opentelemetry.javaagent.instrumentation.vertx;
|
package io.opentelemetry.javaagent.instrumentation.vertx;
|
||||||
|
|
|
@ -6,16 +6,19 @@
|
||||||
package io.opentelemetry.javaagent.instrumentation.vertx.reactive;
|
package io.opentelemetry.javaagent.instrumentation.vertx.reactive;
|
||||||
|
|
||||||
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.isConstructor;
|
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
|
||||||
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 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.InstrumentationModule;
|
||||||
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import io.vertx.core.AsyncResult;
|
import io.vertx.core.AsyncResult;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
|
@ -24,26 +27,13 @@ import net.bytebuddy.description.type.TypeDescription;
|
||||||
import net.bytebuddy.matcher.ElementMatcher;
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
|
|
||||||
/** This instrumentation allows span context propagation across Vert.x reactive executions. */
|
/** This instrumentation allows span context propagation across Vert.x reactive executions. */
|
||||||
@AutoService(Instrumenter.class)
|
@AutoService(InstrumentationModule.class)
|
||||||
public class VertxRxInstrumentation extends Instrumenter.Default {
|
public class VertxRxInstrumentationModule extends InstrumentationModule {
|
||||||
|
|
||||||
public VertxRxInstrumentation() {
|
public VertxRxInstrumentationModule() {
|
||||||
super("vertx");
|
super("vertx");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
|
||||||
// Different versions of Vert.x has this class in different packages
|
|
||||||
return hasClassesNamed("io.vertx.reactivex.core.impl.AsyncResultSingle")
|
|
||||||
.or(hasClassesNamed("io.vertx.reactivex.impl.AsyncResultSingle"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
|
||||||
return named("io.vertx.reactivex.core.impl.AsyncResultSingle")
|
|
||||||
.or(named("io.vertx.reactivex.impl.AsyncResultSingle"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
|
@ -52,15 +42,35 @@ public class VertxRxInstrumentation extends Instrumenter.Default {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
Map<ElementMatcher<? super MethodDescription>, String> result = new HashMap<>();
|
return singletonList(new AsyncResultSingleInstrumentation());
|
||||||
result.put(
|
}
|
||||||
isConstructor().and(takesArgument(0, named("io.vertx.core.Handler"))),
|
|
||||||
this.getClass().getName() + "$AsyncResultSingleHandlerAdvice");
|
private static final class AsyncResultSingleInstrumentation implements TypeInstrumentation {
|
||||||
result.put(
|
@Override
|
||||||
isConstructor().and(takesArgument(0, named("java.util.function.Consumer"))),
|
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||||
this.getClass().getName() + "$AsyncResultSingleConsumerAdvice");
|
// Different versions of Vert.x has this class in different packages
|
||||||
return result;
|
return hasClassesNamed("io.vertx.reactivex.core.impl.AsyncResultSingle")
|
||||||
|
.or(hasClassesNamed("io.vertx.reactivex.impl.AsyncResultSingle"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
||||||
|
return named("io.vertx.reactivex.core.impl.AsyncResultSingle")
|
||||||
|
.or(named("io.vertx.reactivex.impl.AsyncResultSingle"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
Map<ElementMatcher<? super MethodDescription>, String> result = new HashMap<>();
|
||||||
|
result.put(
|
||||||
|
isConstructor().and(takesArgument(0, named("io.vertx.core.Handler"))),
|
||||||
|
VertxRxInstrumentationModule.class.getName() + "$AsyncResultSingleHandlerAdvice");
|
||||||
|
result.put(
|
||||||
|
isConstructor().and(takesArgument(0, named("java.util.function.Consumer"))),
|
||||||
|
VertxRxInstrumentationModule.class.getName() + "$AsyncResultSingleConsumerAdvice");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AsyncResultSingleHandlerAdvice {
|
public static class AsyncResultSingleHandlerAdvice {
|
|
@ -2,8 +2,8 @@
|
||||||
* The majority of monitoring needs of Vert.x application is covered by generic instrumentations.
|
* The majority of monitoring needs of Vert.x application is covered by generic instrumentations.
|
||||||
* Such as those of netty or JDBC.
|
* Such as those of netty or JDBC.
|
||||||
*
|
*
|
||||||
* <p>{@link io.opentelemetry.javaagent.instrumentation.vertx.reactive.VertxRxInstrumentation} wraps
|
* <p>{@link io.opentelemetry.javaagent.instrumentation.vertx.reactive.VertxRxInstrumentationModule}
|
||||||
* {code AsyncResultSingle} classes from Vert.x RxJava library to ensure proper span context
|
* wraps {code AsyncResultSingle} classes from Vert.x RxJava library to ensure proper span context
|
||||||
* propagation in reactive Vert.x applications.
|
* propagation in reactive Vert.x applications.
|
||||||
*/
|
*/
|
||||||
package io.opentelemetry.javaagent.instrumentation.vertx.reactive;
|
package io.opentelemetry.javaagent.instrumentation.vertx.reactive;
|
||||||
|
|
Loading…
Reference in New Issue