New Instrumentation API
This commit is contained in:
parent
33a139cdcb
commit
02a3e6a5d3
|
@ -1,23 +1,50 @@
|
|||
package datadog.trace.agent.tooling;
|
||||
|
||||
import static datadog.trace.agent.tooling.Utils.getConfigEnabled;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.any;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
/**
|
||||
* Built-in bytebuddy-based instrumentation for the datadog javaagent.
|
||||
*
|
||||
* <p>It is strongly recommended to extend {@link Default} rather than implement this interface
|
||||
* directly.
|
||||
*/
|
||||
public interface Instrumenter {
|
||||
|
||||
/**
|
||||
* Add this instrumentation to an AgentBuilder.
|
||||
*
|
||||
* @param agentBuilder AgentBuilder to base instrumentation config off of.
|
||||
* @return the original agentBuilder and this instrumentation
|
||||
*/
|
||||
AgentBuilder instrument(AgentBuilder agentBuilder);
|
||||
|
||||
/** @return A type matcher used to match the class under transform. */
|
||||
ElementMatcher typeMatcher();
|
||||
|
||||
/** @return A type matcher used to match the classloader under transform */
|
||||
ElementMatcher<? super ClassLoader> classLoaderMatcher();
|
||||
|
||||
/** @return Class names of helpers to inject into the user's classloader */
|
||||
String[] helperClassNames();
|
||||
|
||||
Map<ElementMatcher, String> transformers();
|
||||
|
||||
@Slf4j
|
||||
abstract class Configurable implements Instrumenter {
|
||||
abstract class Default implements Instrumenter {
|
||||
private final Set<String> instrumentationNames;
|
||||
protected final boolean enabled;
|
||||
|
||||
public Configurable(final String instrumentationName, final String... additionalNames) {
|
||||
public Default(final String instrumentationName, final String... additionalNames) {
|
||||
this.instrumentationNames = new HashSet<>(Arrays.asList(additionalNames));
|
||||
instrumentationNames.add(instrumentationName);
|
||||
|
||||
|
@ -37,21 +64,46 @@ public interface Instrumenter {
|
|||
enabled = anyEnabled;
|
||||
}
|
||||
|
||||
protected boolean defaultEnabled() {
|
||||
return getConfigEnabled("dd.integrations.enabled", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final AgentBuilder instrument(final AgentBuilder agentBuilder) {
|
||||
if (enabled) {
|
||||
return apply(agentBuilder);
|
||||
} else {
|
||||
public AgentBuilder instrument(final AgentBuilder agentBuilder) {
|
||||
if (!enabled) {
|
||||
log.debug("Instrumentation {} is disabled", this);
|
||||
return agentBuilder;
|
||||
}
|
||||
|
||||
AgentBuilder.Identified.Extendable advice =
|
||||
agentBuilder
|
||||
.type(typeMatcher(), classLoaderMatcher())
|
||||
.transform(DDTransformers.defaultTransformers());
|
||||
final String[] helperClassNames = helperClassNames();
|
||||
if (helperClassNames.length > 0) {
|
||||
advice = advice.transform(new HelperInjector(helperClassNames));
|
||||
}
|
||||
for (Map.Entry<ElementMatcher, String> entry : transformers().entrySet()) {
|
||||
advice = advice.transform(DDAdvice.create().advice(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
return advice.asDecorator();
|
||||
}
|
||||
|
||||
protected abstract AgentBuilder apply(AgentBuilder agentBuilder);
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return any();
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract ElementMatcher<? super TypeDescription> typeMatcher();
|
||||
|
||||
@Override
|
||||
public abstract Map<ElementMatcher, String> transformers();
|
||||
|
||||
protected boolean defaultEnabled() {
|
||||
return getConfigEnabled("dd.integrations.enabled", true);
|
||||
}
|
||||
|
||||
protected static String getPropOrEnv(final String name) {
|
||||
return System.getProperty(name, System.getenv(propToEnvName(name)));
|
||||
|
|
|
@ -1,130 +0,0 @@
|
|||
package datadog.trace.agent.tooling;
|
||||
|
||||
import static datadog.trace.agent.tooling.Utils.getConfigEnabled;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder.Matchable;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
/**
|
||||
* Built-in bytebuddy-based instrumentation for the datadog javaagent.
|
||||
*
|
||||
* It is strongly recommended to extend {@link Configurable} rather than implement this interface directly.
|
||||
*/
|
||||
public interface NewInstrumenter {
|
||||
|
||||
/**
|
||||
* Add this instrumentation to an AgentBuilder.
|
||||
*
|
||||
* @param agentBuilder AgentBuilder to base instrumentation config off of.
|
||||
* @return the original agentBuilder and this instrumentation
|
||||
*/
|
||||
AgentBuilder instrument(AgentBuilder agentBuilder);
|
||||
|
||||
// the following methods would be implemented by the instrumentation author
|
||||
|
||||
/**
|
||||
* @return A type matcher used to match the class under transform.
|
||||
*/
|
||||
ElementMatcher<? super TypeDescription> getTypeMatcher();
|
||||
|
||||
/**
|
||||
* @return A type matcher used to match the classloader under transform
|
||||
*/
|
||||
ElementMatcher<? super ClassLoaderMatcher> getClassLoaderMatcher();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Set<String> getHelperClassNames();
|
||||
|
||||
Map<ElementMatcher, String> getTransformers();
|
||||
|
||||
// TODO: rename Configurable -> Default
|
||||
@Slf4j
|
||||
abstract class Configurable implements NewInstrumenter {
|
||||
// omitted: config and name logic
|
||||
|
||||
@Override
|
||||
public final AgentBuilder instrument(final AgentBuilder agentBuilder) {
|
||||
if (!enabled) {
|
||||
log.debug("Instrumentation {} is disabled", this);
|
||||
return agentBuilder;
|
||||
}
|
||||
|
||||
/*
|
||||
Transformer transformer = AgentBuilder.type(createTypeMatcher(), <all-cl>)
|
||||
.and(safeToInject()) // implementation generated by muzzle
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(new HelperInjector(getHelperClassNames()));
|
||||
Map<ElementMatcher, String> advice = getTransformers();
|
||||
for (Entry<ElementMatcher, String> entry : advice.getEntrySet()) {
|
||||
transformer = transformer.transform(DDAdvice.create().advice(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
return transformer.asDecorator()
|
||||
*/
|
||||
// FIXME
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getHelperClassNames() {
|
||||
// FIXME
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract ElementMatcher<? super TypeDescription> getTypeMatcher();
|
||||
|
||||
public abstract ElementMatcher<? super ClassLoaderMatcher> getClassLoaderMatcher();
|
||||
|
||||
public abstract Map<ElementMatcher, String> getTransformers();
|
||||
|
||||
|
||||
// TODO merge in config logic from previous instrumenter
|
||||
|
||||
private final Set<String> instrumentationNames;
|
||||
protected final boolean enabled;
|
||||
|
||||
public Configurable(final String instrumentationName, final String... additionalNames) {
|
||||
this.instrumentationNames = new HashSet<>(Arrays.asList(additionalNames));
|
||||
instrumentationNames.add(instrumentationName);
|
||||
|
||||
// If default is enabled, we want to enable individually,
|
||||
// if default is disabled, we want to disable individually.
|
||||
final boolean defaultEnabled = defaultEnabled();
|
||||
boolean anyEnabled = defaultEnabled;
|
||||
for (final String name : instrumentationNames) {
|
||||
final boolean configEnabled =
|
||||
getConfigEnabled("dd.integration." + name + ".enabled", defaultEnabled);
|
||||
if (defaultEnabled) {
|
||||
anyEnabled &= configEnabled;
|
||||
} else {
|
||||
anyEnabled |= configEnabled;
|
||||
}
|
||||
}
|
||||
enabled = anyEnabled;
|
||||
}
|
||||
|
||||
protected boolean defaultEnabled() {
|
||||
return getConfigEnabled("dd.integrations.enabled", true);
|
||||
}
|
||||
|
||||
protected abstract AgentBuilder apply(AgentBuilder agentBuilder);
|
||||
|
||||
protected static String getPropOrEnv(final String name) {
|
||||
return System.getProperty(name, System.getenv(propToEnvName(name)));
|
||||
}
|
||||
|
||||
private static String propToEnvName(final String name) {
|
||||
return name.toUpperCase().replace(".", "_");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,12 +2,14 @@ package datadog.trace.agent.test
|
|||
|
||||
import datadog.trace.agent.tooling.Instrumenter
|
||||
import net.bytebuddy.agent.builder.AgentBuilder
|
||||
import net.bytebuddy.description.type.TypeDescription
|
||||
import net.bytebuddy.matcher.ElementMatcher
|
||||
import org.junit.Rule
|
||||
import org.junit.contrib.java.lang.system.EnvironmentVariables
|
||||
import org.junit.contrib.java.lang.system.RestoreSystemProperties
|
||||
import spock.lang.Specification
|
||||
|
||||
class ConfigurableInstrumenterTest extends Specification {
|
||||
class DefaultInstrumenterTest extends Specification {
|
||||
@Rule
|
||||
public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties()
|
||||
@Rule
|
||||
|
@ -20,8 +22,8 @@ class ConfigurableInstrumenterTest extends Specification {
|
|||
|
||||
def "default enabled"() {
|
||||
setup:
|
||||
def target = new TestConfigurableInstrumenter("test")
|
||||
target.instrument(null)
|
||||
def target = new TestDefaultInstrumenter("test")
|
||||
target.instrument(new AgentBuilder.Default())
|
||||
|
||||
expect:
|
||||
target.enabled
|
||||
|
@ -29,20 +31,22 @@ class ConfigurableInstrumenterTest extends Specification {
|
|||
}
|
||||
|
||||
def "default enabled override"() {
|
||||
setup:
|
||||
target.instrument(new AgentBuilder.Default())
|
||||
|
||||
expect:
|
||||
target.instrument(null) == null
|
||||
target.enabled == enabled
|
||||
target.applyCalled == enabled
|
||||
|
||||
where:
|
||||
enabled | target
|
||||
true | new TestConfigurableInstrumenter("test") {
|
||||
true | new TestDefaultInstrumenter("test") {
|
||||
@Override
|
||||
protected boolean defaultEnabled() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
false | new TestConfigurableInstrumenter("test") {
|
||||
false | new TestDefaultInstrumenter("test") {
|
||||
@Override
|
||||
protected boolean defaultEnabled() {
|
||||
return false
|
||||
|
@ -53,15 +57,15 @@ class ConfigurableInstrumenterTest extends Specification {
|
|||
def "default disabled can override to enabled"() {
|
||||
setup:
|
||||
System.setProperty("dd.integration.test.enabled", "$enabled")
|
||||
def target = new TestConfigurableInstrumenter("test") {
|
||||
def target = new TestDefaultInstrumenter("test") {
|
||||
@Override
|
||||
protected boolean defaultEnabled() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
target.instrument(new AgentBuilder.Default())
|
||||
|
||||
expect:
|
||||
target.instrument(null) == null
|
||||
target.enabled == enabled
|
||||
target.applyCalled == enabled
|
||||
|
||||
|
@ -72,10 +76,10 @@ class ConfigurableInstrumenterTest extends Specification {
|
|||
def "configure default sys prop as #value"() {
|
||||
setup:
|
||||
System.setProperty("dd.integrations.enabled", value)
|
||||
def target = new TestConfigurableInstrumenter("test")
|
||||
def target = new TestDefaultInstrumenter("test")
|
||||
target.instrument(new AgentBuilder.Default())
|
||||
|
||||
expect:
|
||||
target.instrument(null) == null
|
||||
target.enabled == enabled
|
||||
target.applyCalled == enabled
|
||||
|
||||
|
@ -89,10 +93,10 @@ class ConfigurableInstrumenterTest extends Specification {
|
|||
def "configure default env var as #value"() {
|
||||
setup:
|
||||
environmentVariables.set("DD_INTEGRATIONS_ENABLED", value)
|
||||
def target = new TestConfigurableInstrumenter("test")
|
||||
def target = new TestDefaultInstrumenter("test")
|
||||
target.instrument(new AgentBuilder.Default())
|
||||
|
||||
expect:
|
||||
target.instrument(null) == null
|
||||
target.enabled == enabled
|
||||
target.applyCalled == enabled
|
||||
|
||||
|
@ -107,10 +111,10 @@ class ConfigurableInstrumenterTest extends Specification {
|
|||
setup:
|
||||
System.setProperty("dd.integrations.enabled", "false")
|
||||
System.setProperty("dd.integration.${value}.enabled", "true")
|
||||
def target = new TestConfigurableInstrumenter(name, altName)
|
||||
def target = new TestDefaultInstrumenter(name, altName)
|
||||
target.instrument(new AgentBuilder.Default())
|
||||
|
||||
expect:
|
||||
target.instrument(null) == null
|
||||
target.enabled == enabled
|
||||
target.applyCalled == enabled
|
||||
|
||||
|
@ -129,11 +133,11 @@ class ConfigurableInstrumenterTest extends Specification {
|
|||
setup:
|
||||
environmentVariables.set("DD_INTEGRATIONS_ENABLED", "false")
|
||||
environmentVariables.set("DD_INTEGRATION_${value}_ENABLED", "true")
|
||||
def target = new TestConfigurableInstrumenter(name, altName)
|
||||
def target = new TestDefaultInstrumenter(name, altName)
|
||||
target.instrument(new AgentBuilder.Default())
|
||||
|
||||
expect:
|
||||
System.getenv("DD_INTEGRATION_${value}_ENABLED") == "true"
|
||||
target.instrument(null) == null
|
||||
target.enabled == enabled
|
||||
target.applyCalled == enabled
|
||||
|
||||
|
@ -148,27 +152,37 @@ class ConfigurableInstrumenterTest extends Specification {
|
|||
"PERIOD_TEST" | true | "period.test" | "asdf"
|
||||
}
|
||||
|
||||
class TestConfigurableInstrumenter extends Instrumenter.Configurable {
|
||||
class TestDefaultInstrumenter extends Instrumenter.Default {
|
||||
boolean applyCalled = false
|
||||
|
||||
TestConfigurableInstrumenter(
|
||||
TestDefaultInstrumenter(
|
||||
String instrumentationName) {
|
||||
super(instrumentationName)
|
||||
}
|
||||
|
||||
TestConfigurableInstrumenter(
|
||||
TestDefaultInstrumenter(
|
||||
String instrumentationName, String additionalName) {
|
||||
super(instrumentationName, [additionalName])
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AgentBuilder apply(AgentBuilder agentBuilder) {
|
||||
applyCalled = true
|
||||
return null
|
||||
}
|
||||
|
||||
def getEnabled() {
|
||||
return super.enabled
|
||||
}
|
||||
|
||||
@Override
|
||||
ElementMatcher<? super TypeDescription> typeMatcher() {
|
||||
applyCalled = true
|
||||
return new ElementMatcher() {
|
||||
@Override
|
||||
boolean matches(Object target) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
Map<ElementMatcher, String> transformers() {
|
||||
return Collections.emptyMap()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,13 +18,11 @@ import io.opentracing.propagation.Format;
|
|||
import io.opentracing.propagation.TextMap;
|
||||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import scala.Function1;
|
||||
import scala.concurrent.ExecutionContext;
|
||||
import scala.concurrent.Future;
|
||||
|
@ -32,7 +30,7 @@ import scala.runtime.AbstractFunction1;
|
|||
|
||||
@Slf4j
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class AkkaHttpServerInstrumentation extends Instrumenter.Configurable {
|
||||
public final class AkkaHttpServerInstrumentation extends Instrumenter.Default {
|
||||
public AkkaHttpServerInstrumentation() {
|
||||
super("akka-http", "akka-http-server");
|
||||
}
|
||||
|
@ -42,38 +40,39 @@ public final class AkkaHttpServerInstrumentation extends Instrumenter.Configurab
|
|||
return false;
|
||||
}
|
||||
|
||||
private static final HelperInjector akkaHttpHelperInjector =
|
||||
new HelperInjector(
|
||||
AkkaHttpServerInstrumentation.class.getName() + "$DatadogWrapperHelper",
|
||||
AkkaHttpServerInstrumentation.class.getName() + "$DatadogSyncWrapper",
|
||||
AkkaHttpServerInstrumentation.class.getName() + "$DatadogAsyncWrapper",
|
||||
AkkaHttpServerInstrumentation.class.getName() + "$DatadogAsyncWrapper$1",
|
||||
AkkaHttpServerInstrumentation.class.getName() + "$DatadogAsyncWrapper$2",
|
||||
AkkaHttpServerInstrumentation.class.getName() + "$AkkaHttpServerHeaders");
|
||||
@Override
|
||||
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
||||
return named("akka.http.scaladsl.HttpExt");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(named("akka.http.scaladsl.HttpExt"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(akkaHttpHelperInjector)
|
||||
// Instrumenting akka-streams bindAndHandle api was previously attempted.
|
||||
// This proved difficult as there was no clean way to close the async scope
|
||||
// in the graph logic after the user's request handler completes.
|
||||
//
|
||||
// Instead, we're instrumenting the bindAndHandle function helpers by
|
||||
// wrapping the scala functions with our own handlers.
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("bindAndHandleSync").and(takesArgument(0, named("scala.Function1"))),
|
||||
AkkaHttpSyncAdvice.class.getName()))
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("bindAndHandleAsync").and(takesArgument(0, named("scala.Function1"))),
|
||||
AkkaHttpAsyncAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
AkkaHttpServerInstrumentation.class.getName() + "$DatadogWrapperHelper",
|
||||
AkkaHttpServerInstrumentation.class.getName() + "$DatadogSyncWrapper",
|
||||
AkkaHttpServerInstrumentation.class.getName() + "$DatadogAsyncWrapper",
|
||||
AkkaHttpServerInstrumentation.class.getName() + "$DatadogAsyncWrapper$1",
|
||||
AkkaHttpServerInstrumentation.class.getName() + "$DatadogAsyncWrapper$2",
|
||||
AkkaHttpServerInstrumentation.class.getName() + "$AkkaHttpServerHeaders"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
// Instrumenting akka-streams bindAndHandle api was previously attempted.
|
||||
// This proved difficult as there was no clean way to close the async scope
|
||||
// in the graph logic after the user's request handler completes.
|
||||
//
|
||||
// Instead, we're instrumenting the bindAndHandle function helpers by
|
||||
// wrapping the scala functions with our own handlers.
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("bindAndHandleSync").and(takesArgument(0, named("scala.Function1"))),
|
||||
AkkaHttpSyncAdvice.class.getName());
|
||||
transformers.put(
|
||||
named("bindAndHandleAsync").and(takesArgument(0, named("scala.Function1"))),
|
||||
AkkaHttpAsyncAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class AkkaHttpSyncAdvice {
|
||||
|
|
|
@ -5,49 +5,56 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.apache.http.impl.client.DefaultRedirectStrategy;
|
||||
import org.apache.http.impl.execchain.ClientExecChain;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class ApacheHttpClientInstrumentation extends Instrumenter.Configurable {
|
||||
public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public ApacheHttpClientInstrumentation() {
|
||||
super("httpclient");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("org.apache.http.impl.client.HttpClientBuilder"),
|
||||
classLoaderHasClasses(
|
||||
"org.apache.http.HttpException",
|
||||
"org.apache.http.HttpRequest",
|
||||
"org.apache.http.client.RedirectStrategy",
|
||||
"org.apache.http.client.methods.CloseableHttpResponse",
|
||||
"org.apache.http.client.methods.HttpExecutionAware",
|
||||
"org.apache.http.client.methods.HttpRequestWrapper",
|
||||
"org.apache.http.client.protocol.HttpClientContext",
|
||||
"org.apache.http.conn.routing.HttpRoute",
|
||||
"org.apache.http.impl.execchain.ClientExecChain"))
|
||||
.transform(
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.apachehttpclient.DDTracingClientExec",
|
||||
"datadog.trace.instrumentation.apachehttpclient.DDTracingClientExec$HttpHeadersInjectAdapter"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod().and(named("decorateProtocolExec")),
|
||||
ApacheHttpClientAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
||||
return named("org.apache.http.impl.client.HttpClientBuilder");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses(
|
||||
"org.apache.http.HttpException",
|
||||
"org.apache.http.HttpRequest",
|
||||
"org.apache.http.client.RedirectStrategy",
|
||||
"org.apache.http.client.methods.CloseableHttpResponse",
|
||||
"org.apache.http.client.methods.HttpExecutionAware",
|
||||
"org.apache.http.client.methods.HttpRequestWrapper",
|
||||
"org.apache.http.client.protocol.HttpClientContext",
|
||||
"org.apache.http.conn.routing.HttpRoute",
|
||||
"org.apache.http.impl.execchain.ClientExecChain");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"datadog.trace.instrumentation.apachehttpclient.DDTracingClientExec",
|
||||
"datadog.trace.instrumentation.apachehttpclient.DDTracingClientExec$HttpHeadersInjectAdapter"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod().and(named("decorateProtocolExec")), ApacheHttpClientAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class ApacheHttpClientAdvice {
|
||||
|
|
|
@ -2,53 +2,59 @@ package datadog.trace.instrumentation.aws.v0;
|
|||
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.declaresField;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isAbstract;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.not;
|
||||
|
||||
import com.amazonaws.handlers.RequestHandler2;
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
/**
|
||||
* This instrumentation might work with versions before 1.11.0, but this was the first version that
|
||||
* is tested. It could possibly be extended earlier.
|
||||
*/
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class AWSClientInstrumentation extends Instrumenter.Configurable {
|
||||
public final class AWSClientInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public AWSClientInstrumentation() {
|
||||
super("aws-sdk");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
isAbstract()
|
||||
.and(
|
||||
named("com.amazonaws.AmazonWebServiceClient")
|
||||
.and(declaresField(named("requestHandler2s")))),
|
||||
classLoaderHasClasses("com.amazonaws.http.client.HttpClientFactory")
|
||||
.and(
|
||||
not(
|
||||
classLoaderHasClasses(
|
||||
"com.amazonaws.client.builder.AwsClientBuilder$EndpointConfiguration"))))
|
||||
.transform(
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.aws.v0.TracingRequestHandler",
|
||||
"datadog.trace.instrumentation.aws.v0.SpanDecorator"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(DDAdvice.create().advice(isConstructor(), AWSClientAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("com.amazonaws.AmazonWebServiceClient")
|
||||
.and(declaresField(named("requestHandler2s")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("com.amazonaws.http.client.HttpClientFactory")
|
||||
.and(
|
||||
not(
|
||||
classLoaderHasClasses(
|
||||
"com.amazonaws.client.builder.AwsClientBuilder$EndpointConfiguration")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"datadog.trace.instrumentation.aws.v0.TracingRequestHandler",
|
||||
"datadog.trace.instrumentation.aws.v0.SpanDecorator"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(isConstructor(), AWSClientAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class AWSClientAdvice {
|
||||
|
|
|
@ -8,14 +8,13 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||
|
||||
import com.amazonaws.handlers.RequestHandler2;
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
/**
|
||||
* The interface for com.amazonaws.Request changed in 106. The method addHandlerContext which is
|
||||
|
@ -23,28 +22,38 @@ import net.bytebuddy.asm.Advice;
|
|||
* bytecode compatible. The instrumentation is the same, but the compiled output is different.
|
||||
*/
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class AWSClientInstrumentation extends Instrumenter.Configurable {
|
||||
public final class AWSClientInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public AWSClientInstrumentation() {
|
||||
super("aws-sdk");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
isAbstract()
|
||||
.and(
|
||||
named("com.amazonaws.AmazonWebServiceClient")
|
||||
.and(declaresField(named("requestHandler2s")))),
|
||||
classLoaderHasClasses("com.amazonaws.HandlerContextAware"))
|
||||
.transform(
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.aws.v106.TracingRequestHandler",
|
||||
"datadog.trace.instrumentation.aws.v106.SpanDecorator"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(DDAdvice.create().advice(isConstructor(), AWSClientAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return isAbstract()
|
||||
.and(
|
||||
named("com.amazonaws.AmazonWebServiceClient")
|
||||
.and(declaresField(named("requestHandler2s"))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("com.amazonaws.HandlerContextAware");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"datadog.trace.instrumentation.aws.v106.TracingRequestHandler",
|
||||
"datadog.trace.instrumentation.aws.v106.SpanDecorator"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(isConstructor(), AWSClientAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class AWSClientAdvice {
|
||||
|
|
|
@ -1,23 +1,21 @@
|
|||
package datadog.trace.instrumentation.classloaders;
|
||||
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.failSafe;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.opentracing.DDTracer;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.lang.reflect.Field;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class ClassLoaderInstrumentation extends Instrumenter.Configurable {
|
||||
public final class ClassLoaderInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public ClassLoaderInstrumentation() {
|
||||
super("classloader");
|
||||
|
@ -29,14 +27,15 @@ public final class ClassLoaderInstrumentation extends Instrumenter.Configurable
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
failSafe(isSubTypeOf(ClassLoader.class)),
|
||||
classLoaderHasClasses("io.opentracing.util.GlobalTracer"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(DDAdvice.create().advice(isConstructor(), ClassloaderAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return isSubTypeOf(ClassLoader.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(isConstructor(), ClassloaderAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class ClassloaderAdvice {
|
||||
|
@ -60,6 +59,7 @@ public final class ClassLoaderInstrumentation extends Instrumenter.Configurable
|
|||
field.setAccessible(true);
|
||||
|
||||
final Object o = field.get(null);
|
||||
// FIXME: This instrumentation will never work. Referencing class DDTracer will throw an exception.
|
||||
if (o instanceof DDTracer) {
|
||||
final DDTracer tracer = (DDTracer) o;
|
||||
tracer.registerClassLoader(cl);
|
||||
|
|
|
@ -8,41 +8,48 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
|||
|
||||
import com.datastax.driver.core.Session;
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import io.opentracing.Tracer;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.lang.reflect.Constructor;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class CassandraClientInstrumentation extends Instrumenter.Configurable {
|
||||
public class CassandraClientInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public CassandraClientInstrumentation() {
|
||||
super("cassandra");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("com.datastax.driver.core.Cluster$Manager"),
|
||||
classLoaderHasClasses("com.datastax.driver.core.Duration"))
|
||||
.transform(
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.datastax.cassandra.TracingSession",
|
||||
"datadog.trace.instrumentation.datastax.cassandra.TracingSession$1",
|
||||
"datadog.trace.instrumentation.datastax.cassandra.TracingSession$2"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod().and(isPrivate()).and(named("newSession")).and(takesArguments(0)),
|
||||
CassandraClientAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("com.datastax.driver.core.Cluster$Manager");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("com.datastax.driver.core.Duration");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"datadog.trace.instrumentation.datastax.cassandra.TracingSession",
|
||||
"datadog.trace.instrumentation.datastax.cassandra.TracingSession$1",
|
||||
"datadog.trace.instrumentation.datastax.cassandra.TracingSession$2"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod().and(isPrivate()).and(named("newSession")).and(takesArguments(0)),
|
||||
CassandraClientAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class CassandraClientAdvice {
|
||||
|
|
|
@ -10,8 +10,6 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDTags;
|
||||
import io.opentracing.Scope;
|
||||
|
@ -19,12 +17,14 @@ import io.opentracing.Span;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.elasticsearch.client.ResponseListener;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class Elasticsearch5RestClientInstrumentation extends Instrumenter.Configurable {
|
||||
public class Elasticsearch5RestClientInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public Elasticsearch5RestClientInstrumentation() {
|
||||
super("elasticsearch", "elasticsearch-rest", "elasticsearch-rest-5");
|
||||
|
@ -36,22 +36,23 @@ public class Elasticsearch5RestClientInstrumentation extends Instrumenter.Config
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(not(isInterface()).and(named("org.elasticsearch.client.RestClient")))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(named("performRequestAsync"))
|
||||
.and(takesArguments(7))
|
||||
.and(takesArgument(0, named("java.lang.String"))) // method
|
||||
.and(takesArgument(1, named("java.lang.String"))) // endpoint
|
||||
.and(takesArgument(5, named("org.elasticsearch.client.ResponseListener"))),
|
||||
ElasticsearchRestClientAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(named("org.elasticsearch.client.RestClient"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(named("performRequestAsync"))
|
||||
.and(takesArguments(7))
|
||||
.and(takesArgument(0, named("java.lang.String"))) // method
|
||||
.and(takesArgument(1, named("java.lang.String"))) // endpoint
|
||||
.and(takesArgument(5, named("org.elasticsearch.client.ResponseListener"))),
|
||||
ElasticsearchRestClientAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class ElasticsearchRestClientAdvice {
|
||||
|
|
|
@ -9,9 +9,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDTags;
|
||||
import io.opentracing.Scope;
|
||||
|
@ -19,15 +16,17 @@ import io.opentracing.Span;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.elasticsearch.action.Action;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.ActionRequest;
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class Elasticsearch2TransportClientInstrumentation extends Instrumenter.Configurable {
|
||||
public class Elasticsearch2TransportClientInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public Elasticsearch2TransportClientInstrumentation() {
|
||||
super("elasticsearch", "elasticsearch-transport", "elasticsearch-transport-2");
|
||||
|
@ -39,32 +38,40 @@ public class Elasticsearch2TransportClientInstrumentation extends Instrumenter.C
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface()).and(named("org.elasticsearch.client.support.AbstractClient")),
|
||||
// If we want to be more generic, we could instrument the interface instead:
|
||||
// .and(hasSuperType(named("org.elasticsearch.client.ElasticsearchClient"))))
|
||||
classLoaderHasClasses("org.elasticsearch.plugins.SitePlugin"))
|
||||
.transform(
|
||||
new HelperInjector(
|
||||
"com.google.common.base.Preconditions",
|
||||
"com.google.common.base.Joiner",
|
||||
"com.google.common.base.Joiner$1",
|
||||
"com.google.common.base.Joiner$2",
|
||||
"com.google.common.base.Joiner$MapJoiner",
|
||||
"datadog.trace.instrumentation.elasticsearch2.TransportActionListener"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(named("execute"))
|
||||
.and(takesArgument(0, named("org.elasticsearch.action.Action")))
|
||||
.and(takesArgument(1, named("org.elasticsearch.action.ActionRequest")))
|
||||
.and(takesArgument(2, named("org.elasticsearch.action.ActionListener"))),
|
||||
ElasticsearchTransportClientAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
// If we want to be more generic, we could instrument the interface instead:
|
||||
// .and(hasSuperType(named("org.elasticsearch.client.ElasticsearchClient"))))
|
||||
return not(isInterface()).and(named("org.elasticsearch.client.support.AbstractClient"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("org.elasticsearch.plugins.SitePlugin");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"com.google.common.base.Preconditions",
|
||||
"com.google.common.base.Joiner",
|
||||
"com.google.common.base.Joiner$1",
|
||||
"com.google.common.base.Joiner$2",
|
||||
"com.google.common.base.Joiner$MapJoiner",
|
||||
"datadog.trace.instrumentation.elasticsearch2.TransportActionListener"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(named("execute"))
|
||||
.and(takesArgument(0, named("org.elasticsearch.action.Action")))
|
||||
.and(takesArgument(1, named("org.elasticsearch.action.ActionRequest")))
|
||||
.and(takesArgument(2, named("org.elasticsearch.action.ActionListener"))),
|
||||
ElasticsearchTransportClientAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class ElasticsearchTransportClientAdvice {
|
||||
|
|
|
@ -9,9 +9,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDTags;
|
||||
import io.opentracing.Scope;
|
||||
|
@ -19,15 +16,17 @@ import io.opentracing.Span;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.elasticsearch.action.Action;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.ActionRequest;
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class Elasticsearch5TransportClientInstrumentation extends Instrumenter.Configurable {
|
||||
public class Elasticsearch5TransportClientInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public Elasticsearch5TransportClientInstrumentation() {
|
||||
super("elasticsearch", "elasticsearch-transport", "elasticsearch-transport-5");
|
||||
|
@ -39,32 +38,40 @@ public class Elasticsearch5TransportClientInstrumentation extends Instrumenter.C
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface()).and(named("org.elasticsearch.client.support.AbstractClient")),
|
||||
// If we want to be more generic, we could instrument the interface instead:
|
||||
// .and(hasSuperType(named("org.elasticsearch.client.ElasticsearchClient"))))
|
||||
classLoaderHasClasses("org.elasticsearch.percolator.TransportMultiPercolateAction"))
|
||||
.transform(
|
||||
new HelperInjector(
|
||||
"com.google.common.base.Preconditions",
|
||||
"com.google.common.base.Joiner",
|
||||
"com.google.common.base.Joiner$1",
|
||||
"com.google.common.base.Joiner$2",
|
||||
"com.google.common.base.Joiner$MapJoiner",
|
||||
"datadog.trace.instrumentation.elasticsearch5.TransportActionListener"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(named("execute"))
|
||||
.and(takesArgument(0, named("org.elasticsearch.action.Action")))
|
||||
.and(takesArgument(1, named("org.elasticsearch.action.ActionRequest")))
|
||||
.and(takesArgument(2, named("org.elasticsearch.action.ActionListener"))),
|
||||
ElasticsearchTransportClientAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
// If we want to be more generic, we could instrument the interface instead:
|
||||
// .and(hasSuperType(named("org.elasticsearch.client.ElasticsearchClient"))))
|
||||
return not(isInterface()).and(named("org.elasticsearch.client.support.AbstractClient"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("org.elasticsearch.percolator.TransportMultiPercolateAction");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"com.google.common.base.Preconditions",
|
||||
"com.google.common.base.Joiner",
|
||||
"com.google.common.base.Joiner$1",
|
||||
"com.google.common.base.Joiner$2",
|
||||
"com.google.common.base.Joiner$MapJoiner",
|
||||
"datadog.trace.instrumentation.elasticsearch5.TransportActionListener"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(named("execute"))
|
||||
.and(takesArgument(0, named("org.elasticsearch.action.Action")))
|
||||
.and(takesArgument(1, named("org.elasticsearch.action.ActionRequest")))
|
||||
.and(takesArgument(2, named("org.elasticsearch.action.ActionListener"))),
|
||||
ElasticsearchTransportClientAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class ElasticsearchTransportClientAdvice {
|
||||
|
|
|
@ -9,9 +9,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDTags;
|
||||
import io.opentracing.Scope;
|
||||
|
@ -19,8 +16,10 @@ import io.opentracing.Span;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.elasticsearch.action.Action;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.ActionRequest;
|
||||
|
@ -31,7 +30,7 @@ import org.elasticsearch.action.ActionResponse;
|
|||
* an abstract class, so the bytecode isn't directly compatible.
|
||||
*/
|
||||
@AutoService(Instrumenter.class)
|
||||
public class Elasticsearch6TransportClientInstrumentation extends Instrumenter.Configurable {
|
||||
public class Elasticsearch6TransportClientInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public Elasticsearch6TransportClientInstrumentation() {
|
||||
super("elasticsearch", "elasticsearch-transport", "elasticsearch-transport-6");
|
||||
|
@ -43,32 +42,40 @@ public class Elasticsearch6TransportClientInstrumentation extends Instrumenter.C
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface()).and(named("org.elasticsearch.client.support.AbstractClient")),
|
||||
// If we want to be more generic, we could instrument the interface instead:
|
||||
// .and(hasSuperType(named("org.elasticsearch.client.ElasticsearchClient"))))
|
||||
classLoaderHasClasses("org.elasticsearch.client.RestClientBuilder$2"))
|
||||
.transform(
|
||||
new HelperInjector(
|
||||
"com.google.common.base.Preconditions",
|
||||
"com.google.common.base.Joiner",
|
||||
"com.google.common.base.Joiner$1",
|
||||
"com.google.common.base.Joiner$2",
|
||||
"com.google.common.base.Joiner$MapJoiner",
|
||||
"datadog.trace.instrumentation.elasticsearch6.TransportActionListener"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(named("execute"))
|
||||
.and(takesArgument(0, named("org.elasticsearch.action.Action")))
|
||||
.and(takesArgument(1, named("org.elasticsearch.action.ActionRequest")))
|
||||
.and(takesArgument(2, named("org.elasticsearch.action.ActionListener"))),
|
||||
Elasticsearch6TransportClientAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
// If we want to be more generic, we could instrument the interface instead:
|
||||
// .and(hasSuperType(named("org.elasticsearch.client.ElasticsearchClient"))))
|
||||
return not(isInterface()).and(named("org.elasticsearch.client.support.AbstractClient"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("org.elasticsearch.client.RestClientBuilder$2");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"com.google.common.base.Preconditions",
|
||||
"com.google.common.base.Joiner",
|
||||
"com.google.common.base.Joiner$1",
|
||||
"com.google.common.base.Joiner$2",
|
||||
"com.google.common.base.Joiner$MapJoiner",
|
||||
"datadog.trace.instrumentation.elasticsearch6.TransportActionListener"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(named("execute"))
|
||||
.and(takesArgument(0, named("org.elasticsearch.action.Action")))
|
||||
.and(takesArgument(1, named("org.elasticsearch.action.ActionRequest")))
|
||||
.and(takesArgument(2, named("org.elasticsearch.action.ActionListener"))),
|
||||
Elasticsearch6TransportClientAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class Elasticsearch6TransportClientAdvice {
|
||||
|
|
|
@ -8,9 +8,6 @@ import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -24,12 +21,14 @@ import io.opentracing.util.GlobalTracer;
|
|||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class HttpUrlConnectionInstrumentation extends Instrumenter.Configurable {
|
||||
public class HttpUrlConnectionInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public HttpUrlConnectionInstrumentation() {
|
||||
super("httpurlconnection");
|
||||
|
@ -41,25 +40,30 @@ public class HttpUrlConnectionInstrumentation extends Instrumenter.Configurable
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(isSubTypeOf(HttpURLConnection.class))
|
||||
.transform(
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.http_url_connection.MessageHeadersInjectAdapter"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(
|
||||
named("getResponseCode")
|
||||
.or(named("getOutputStream"))
|
||||
.or(named("getInputStream"))
|
||||
.or(nameStartsWith("getHeaderField"))),
|
||||
HttpUrlConnectionAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return isSubTypeOf(HttpURLConnection.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"datadog.trace.instrumentation.http_url_connection.MessageHeadersInjectAdapter"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(
|
||||
named("getResponseCode")
|
||||
.or(named("getOutputStream"))
|
||||
.or(named("getInputStream"))
|
||||
.or(nameStartsWith("getHeaderField"))),
|
||||
HttpUrlConnectionAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class HttpUrlConnectionAdvice {
|
||||
|
|
|
@ -7,8 +7,6 @@ import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -18,11 +16,13 @@ import io.opentracing.tag.Tags;
|
|||
import io.opentracing.util.GlobalTracer;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class UrlInstrumentation extends Instrumenter.Configurable {
|
||||
public class UrlInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public UrlInstrumentation() {
|
||||
super("urlconnection", "httpurlconnection");
|
||||
|
@ -34,16 +34,17 @@ public class UrlInstrumentation extends Instrumenter.Configurable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(is(URL.class))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod().and(isPublic()).and(named("openConnection")),
|
||||
ConnectionErrorAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return is(URL.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod().and(isPublic()).and(named("openConnection")),
|
||||
ConnectionErrorAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class ConnectionErrorAdvice {
|
||||
|
|
|
@ -8,37 +8,35 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.not;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import io.opentracing.Scope;
|
||||
import io.opentracing.Span;
|
||||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.*;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class HystrixCommandInstrumentation extends Instrumenter.Configurable {
|
||||
public class HystrixCommandInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public HystrixCommandInstrumentation() {
|
||||
super("hystrix");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(not(isInterface()).and(hasSuperType(named("com.netflix.hystrix.HystrixCommand"))))
|
||||
// Not adding a version restriction because this should work with any version and add some benefit.
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod().and(named("run").or(named("getFallback"))),
|
||||
TraceAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
// Not adding a version restriction because this should work with any version and add some benefit.
|
||||
return not(isInterface()).and(hasSuperType(named("com.netflix.hystrix.HystrixCommand")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod().and(named("run").or(named("getFallback"))), TraceAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class TraceAdvice {
|
||||
|
|
|
@ -6,36 +6,39 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.context.TraceScope;
|
||||
import io.opentracing.Scope;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.*;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class HystrixThreadPoolInstrumentation extends Instrumenter.Configurable {
|
||||
public class HystrixThreadPoolInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public HystrixThreadPoolInstrumentation() {
|
||||
super("hystrix");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named(
|
||||
"com.netflix.hystrix.strategy.concurrency.HystrixContextScheduler$ThreadPoolWorker"),
|
||||
classLoaderHasClasses("com.netflix.hystrix.AbstractCommand"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod().and(named("schedule")).and(takesArguments(1)),
|
||||
EnableAsyncAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named(
|
||||
"com.netflix.hystrix.strategy.concurrency.HystrixContextScheduler$ThreadPoolWorker");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("com.netflix.hystrix.AbstractCommand");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod().and(named("schedule")).and(takesArguments(1)),
|
||||
EnableAsyncAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class EnableAsyncAdvice {
|
||||
|
|
|
@ -8,42 +8,27 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.agent.tooling.*;
|
||||
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
|
||||
import datadog.trace.context.TraceScope;
|
||||
import io.opentracing.Scope;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@Slf4j
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class ExecutorInstrumentation extends Instrumenter.Configurable {
|
||||
public final class ExecutorInstrumentation extends Instrumenter.Default {
|
||||
public static final String EXEC_NAME = "java_concurrent";
|
||||
public static final HelperInjector EXEC_HELPER_INJECTOR =
|
||||
new HelperInjector(
|
||||
ExecutorInstrumentation.class.getName() + "$ConcurrentUtils",
|
||||
ExecutorInstrumentation.class.getName() + "$DatadogWrapper",
|
||||
ExecutorInstrumentation.class.getName() + "$CallableWrapper",
|
||||
ExecutorInstrumentation.class.getName() + "$RunnableWrapper");
|
||||
|
||||
/**
|
||||
* Only apply executor instrumentation to whitelisted executors. In the future, this restriction
|
||||
|
@ -102,9 +87,9 @@ public final class ExecutorInstrumentation extends Instrumenter.Configurable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(not(isInterface()).and(hasSuperType(named(Executor.class.getName()))))
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface())
|
||||
.and(hasSuperType(named(Executor.class.getName())))
|
||||
.and(
|
||||
new ElementMatcher<TypeDescription>() {
|
||||
@Override
|
||||
|
@ -126,34 +111,32 @@ public final class ExecutorInstrumentation extends Instrumenter.Configurable {
|
|||
}
|
||||
return whitelisted;
|
||||
}
|
||||
})
|
||||
.transform(EXEC_HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("execute").and(takesArgument(0, Runnable.class)),
|
||||
WrapRunnableAdvice.class.getName()))
|
||||
.asDecorator()
|
||||
.type(not(isInterface()).and(hasSuperType(named(ExecutorService.class.getName()))))
|
||||
.transform(EXEC_HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("submit").and(takesArgument(0, Runnable.class)),
|
||||
WrapRunnableAdvice.class.getName()))
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("submit").and(takesArgument(0, Callable.class)),
|
||||
WrapCallableAdvice.class.getName()))
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
nameMatches("invoke(Any|All)$").and(takesArgument(0, Callable.class)),
|
||||
WrapCallableCollectionAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
ExecutorInstrumentation.class.getName() + "$ConcurrentUtils",
|
||||
ExecutorInstrumentation.class.getName() + "$DatadogWrapper",
|
||||
ExecutorInstrumentation.class.getName() + "$CallableWrapper",
|
||||
ExecutorInstrumentation.class.getName() + "$RunnableWrapper"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("execute").and(takesArgument(0, Runnable.class)), WrapRunnableAdvice.class.getName());
|
||||
transformers.put(
|
||||
named("submit").and(takesArgument(0, Runnable.class)), WrapRunnableAdvice.class.getName());
|
||||
transformers.put(
|
||||
named("submit").and(takesArgument(0, Callable.class)), WrapCallableAdvice.class.getName());
|
||||
transformers.put(
|
||||
nameMatches("invoke(Any|All)$").and(takesArgument(0, Callable.class)),
|
||||
WrapCallableCollectionAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class WrapRunnableAdvice {
|
||||
|
|
|
@ -7,25 +7,19 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.instrumentation.java.concurrent.ExecutorInstrumentation.ConcurrentUtils;
|
||||
import datadog.trace.instrumentation.java.concurrent.ExecutorInstrumentation.DatadogWrapper;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Future;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@Slf4j
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class FutureInstrumentation extends Instrumenter.Configurable {
|
||||
public final class FutureInstrumentation extends Instrumenter.Default {
|
||||
|
||||
/**
|
||||
* Only apply executor instrumentation to whitelisted executors. In the future, this restriction
|
||||
|
@ -69,9 +63,9 @@ public final class FutureInstrumentation extends Instrumenter.Configurable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(not(isInterface()).and(hasSuperType(named(Future.class.getName()))))
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface())
|
||||
.and(hasSuperType(named(Future.class.getName())))
|
||||
.and(
|
||||
new ElementMatcher<TypeDescription>() {
|
||||
@Override
|
||||
|
@ -82,15 +76,25 @@ public final class FutureInstrumentation extends Instrumenter.Configurable {
|
|||
}
|
||||
return whitelisted;
|
||||
}
|
||||
})
|
||||
.transform(ExecutorInstrumentation.EXEC_HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("cancel").and(returns(boolean.class)),
|
||||
CanceledFutureAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
ExecutorInstrumentation.class.getName() + "$ConcurrentUtils",
|
||||
ExecutorInstrumentation.class.getName() + "$DatadogWrapper",
|
||||
ExecutorInstrumentation.class.getName() + "$CallableWrapper",
|
||||
ExecutorInstrumentation.class.getName() + "$RunnableWrapper"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("cancel").and(returns(boolean.class)), CanceledFutureAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class CanceledFutureAdvice {
|
||||
|
|
|
@ -7,8 +7,6 @@ import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDTags;
|
||||
import io.opentracing.Scope;
|
||||
|
@ -16,43 +14,42 @@ import io.opentracing.tag.Tags;
|
|||
import io.opentracing.util.GlobalTracer;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.LinkedList;
|
||||
import java.util.*;
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.Path;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class JaxRsAnnotationsInstrumentation extends Instrumenter.Configurable {
|
||||
public final class JaxRsAnnotationsInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public JaxRsAnnotationsInstrumentation() {
|
||||
super("jax-rs", "jaxrs", "jax-rs-annotations");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
hasSuperType(
|
||||
isAnnotatedWith(named("javax.ws.rs.Path"))
|
||||
.or(
|
||||
failSafe(
|
||||
hasSuperType(
|
||||
declaresMethod(isAnnotatedWith(named("javax.ws.rs.Path"))))))))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isAnnotatedWith(
|
||||
named("javax.ws.rs.Path")
|
||||
.or(named("javax.ws.rs.DELETE"))
|
||||
.or(named("javax.ws.rs.GET"))
|
||||
.or(named("javax.ws.rs.HEAD"))
|
||||
.or(named("javax.ws.rs.OPTIONS"))
|
||||
.or(named("javax.ws.rs.POST"))
|
||||
.or(named("javax.ws.rs.PUT"))),
|
||||
JaxRsAnnotationsAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return hasSuperType(
|
||||
isAnnotatedWith(named("javax.ws.rs.Path"))
|
||||
.or(
|
||||
failSafe(
|
||||
hasSuperType(declaresMethod(isAnnotatedWith(named("javax.ws.rs.Path")))))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isAnnotatedWith(
|
||||
named("javax.ws.rs.Path")
|
||||
.or(named("javax.ws.rs.DELETE"))
|
||||
.or(named("javax.ws.rs.GET"))
|
||||
.or(named("javax.ws.rs.HEAD"))
|
||||
.or(named("javax.ws.rs.OPTIONS"))
|
||||
.or(named("javax.ws.rs.POST"))
|
||||
.or(named("javax.ws.rs.PUT"))),
|
||||
JaxRsAnnotationsAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class JaxRsAnnotationsAdvice {
|
||||
|
|
|
@ -6,37 +6,41 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.agent.tooling.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.ws.rs.client.ClientBuilder;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class JaxRsClientInstrumentation extends Instrumenter.Configurable {
|
||||
public final class JaxRsClientInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public JaxRsClientInstrumentation() {
|
||||
super("jax-rs", "jaxrs", "jax-rs-client");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(failSafe(hasSuperType(named("javax.ws.rs.client.ClientBuilder"))))
|
||||
.transform(
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.jaxrs.ClientTracingFeature",
|
||||
"datadog.trace.instrumentation.jaxrs.ClientTracingFilter",
|
||||
"datadog.trace.instrumentation.jaxrs.InjectAdapter"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("build").and(returns(hasSuperType(named("javax.ws.rs.client.Client")))),
|
||||
ClientBuilderAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return failSafe(hasSuperType(named("javax.ws.rs.client.ClientBuilder")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"datadog.trace.instrumentation.jaxrs.ClientTracingFeature",
|
||||
"datadog.trace.instrumentation.jaxrs.ClientTracingFilter",
|
||||
"datadog.trace.instrumentation.jaxrs.InjectAdapter"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("build").and(returns(hasSuperType(named("javax.ws.rs.client.Client")))),
|
||||
ClientBuilderAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class ClientBuilderAdvice {
|
||||
|
|
|
@ -1,56 +1,52 @@
|
|||
package datadog.trace.instrumentation.jboss;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.agent.tooling.Utils;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.dynamic.DynamicType;
|
||||
import net.bytebuddy.utility.JavaModule;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import net.bytebuddy.matcher.NameMatcher;
|
||||
import net.bytebuddy.matcher.StringMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class JBossClassloadingInstrumentation extends Instrumenter.Configurable {
|
||||
public final class JBossClassloadingInstrumentation extends Instrumenter.Default {
|
||||
public JBossClassloadingInstrumentation() {
|
||||
super("jboss-classloading");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
// Jboss Module class loads the sys prop which defines bootstrap classes
|
||||
.type(named("org.jboss.modules.Module"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
new AgentBuilder.Transformer() {
|
||||
@Override
|
||||
public DynamicType.Builder<?> transform(
|
||||
DynamicType.Builder<?> builder,
|
||||
TypeDescription typeDescription,
|
||||
ClassLoader classLoader,
|
||||
JavaModule javaModule) {
|
||||
// This instrumentation modifies no bytes.
|
||||
// Instead it sets a system prop to tell jboss to delegate
|
||||
// classloads for datadog bootstrap classes
|
||||
StringBuilder ddPrefixes = new StringBuilder("");
|
||||
for (int i = 0; i < Utils.BOOTSTRAP_PACKAGE_PREFIXES.length; ++i) {
|
||||
if (i > 0) {
|
||||
ddPrefixes.append(",");
|
||||
}
|
||||
ddPrefixes.append(Utils.BOOTSTRAP_PACKAGE_PREFIXES[i]);
|
||||
public ElementMatcher typeMatcher() {
|
||||
return new NameMatcher(
|
||||
new StringMatcher("org.jboss.modules.Module", StringMatcher.Mode.EQUALS_FULLY) {
|
||||
@Override
|
||||
public boolean matches(String target) {
|
||||
if (super.matches(target)) {
|
||||
// This instrumentation modifies no bytes.
|
||||
// Instead it sets a system prop to tell jboss to delegate
|
||||
// classloads for datadog bootstrap classes
|
||||
StringBuilder ddPrefixes = new StringBuilder("");
|
||||
for (int i = 0; i < Utils.BOOTSTRAP_PACKAGE_PREFIXES.length; ++i) {
|
||||
if (i > 0) {
|
||||
ddPrefixes.append(",");
|
||||
}
|
||||
final String existing = System.getProperty("jboss.modules.system.pkgs");
|
||||
if (null == existing) {
|
||||
System.setProperty("jboss.modules.system.pkgs", ddPrefixes.toString());
|
||||
} else if (!existing.contains(ddPrefixes)) {
|
||||
System.setProperty(
|
||||
"jboss.modules.system.pkgs", existing + "," + ddPrefixes.toString());
|
||||
}
|
||||
return builder;
|
||||
ddPrefixes.append(Utils.BOOTSTRAP_PACKAGE_PREFIXES[i]);
|
||||
}
|
||||
})
|
||||
.asDecorator();
|
||||
final String existing = System.getProperty("jboss.modules.system.pkgs");
|
||||
if (null == existing) {
|
||||
System.setProperty("jboss.modules.system.pkgs", ddPrefixes.toString());
|
||||
} else if (!existing.contains(ddPrefixes)) {
|
||||
System.setProperty(
|
||||
"jboss.modules.system.pkgs", existing + "," + ddPrefixes.toString());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,35 +9,36 @@ import static net.bytebuddy.matcher.ElementMatchers.returns;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.bootstrap.JDBCMaps;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class ConnectionInstrumentation extends Instrumenter.Configurable {
|
||||
public final class ConnectionInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public ConnectionInstrumentation() {
|
||||
super("jdbc");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(not(isInterface()).and(failSafe(isSubTypeOf(Connection.class))))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
nameStartsWith("prepare")
|
||||
.and(takesArgument(0, String.class))
|
||||
.and(returns(PreparedStatement.class)),
|
||||
ConnectionPrepareAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(isSubTypeOf(Connection.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
nameStartsWith("prepare")
|
||||
.and(takesArgument(0, String.class))
|
||||
.and(returns(PreparedStatement.class)),
|
||||
ConnectionPrepareAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class ConnectionPrepareAdvice {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package datadog.trace.instrumentation.jdbc;
|
||||
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.failSafe;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf;
|
||||
|
@ -10,8 +9,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDTags;
|
||||
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
|
||||
|
@ -25,26 +22,29 @@ import java.sql.Connection;
|
|||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class PreparedStatementInstrumentation extends Instrumenter.Configurable {
|
||||
public final class PreparedStatementInstrumentation extends Instrumenter.Default {
|
||||
public PreparedStatementInstrumentation() {
|
||||
super("jdbc");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(not(isInterface()).and(failSafe(isSubTypeOf(PreparedStatement.class))))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
nameStartsWith("execute").and(takesArguments(0)).and(isPublic()),
|
||||
PreparedStatementAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(isSubTypeOf(PreparedStatement.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
nameStartsWith("execute").and(takesArguments(0)).and(isPublic()),
|
||||
PreparedStatementAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class PreparedStatementAdvice {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package datadog.trace.instrumentation.jdbc;
|
||||
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.failSafe;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf;
|
||||
|
@ -10,8 +9,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDTags;
|
||||
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
|
||||
|
@ -25,27 +22,30 @@ import java.sql.Connection;
|
|||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class StatementInstrumentation extends Instrumenter.Configurable {
|
||||
public final class StatementInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public StatementInstrumentation() {
|
||||
super("jdbc");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(not(isInterface()).and(failSafe(isSubTypeOf(Statement.class))))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
nameStartsWith("execute").and(takesArgument(0, String.class)).and(isPublic()),
|
||||
StatementAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(isSubTypeOf(Statement.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
nameStartsWith("execute").and(takesArgument(0, String.class)).and(isPublic()),
|
||||
StatementAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class StatementAdvice {
|
||||
|
|
|
@ -7,8 +7,6 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDTags;
|
||||
import io.opentracing.Scope;
|
||||
|
@ -16,12 +14,14 @@ import io.opentracing.Span;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import redis.clients.jedis.Protocol.Command;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class JedisInstrumentation extends Instrumenter.Configurable {
|
||||
public final class JedisInstrumentation extends Instrumenter.Default {
|
||||
|
||||
private static final String SERVICE_NAME = "redis";
|
||||
private static final String COMPONENT_NAME = SERVICE_NAME + "-command";
|
||||
|
@ -31,21 +31,30 @@ public final class JedisInstrumentation extends Instrumenter.Configurable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("redis.clients.jedis.Protocol"),
|
||||
classLoaderHasClasses("redis.clients.jedis.Protocol$Command"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(named("sendCommand"))
|
||||
.and(takesArgument(1, named("redis.clients.jedis.Protocol$Command"))),
|
||||
JedisAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("redis.clients.jedis.Protocol");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("redis.clients.jedis.Protocol$Command");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(named("sendCommand"))
|
||||
.and(takesArgument(1, named("redis.clients.jedis.Protocol$Command"))),
|
||||
JedisAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class JedisAdvice {
|
||||
|
|
|
@ -10,8 +10,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -24,16 +22,18 @@ import io.opentracing.tag.Tags;
|
|||
import io.opentracing.util.GlobalTracer;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import javax.servlet.AsyncEvent;
|
||||
import javax.servlet.AsyncListener;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class HandlerInstrumentation extends Instrumenter.Configurable {
|
||||
public final class HandlerInstrumentation extends Instrumenter.Default {
|
||||
public static final String SERVLET_OPERATION_NAME = "jetty.request";
|
||||
|
||||
public HandlerInstrumentation() {
|
||||
|
@ -46,29 +46,38 @@ public final class HandlerInstrumentation extends Instrumenter.Configurable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface())
|
||||
.and(hasSuperType(named("org.eclipse.jetty.server.Handler")))
|
||||
.and(not(named("org.eclipse.jetty.server.handler.HandlerWrapper"))),
|
||||
not(classLoaderHasClasses("org.eclipse.jetty.server.AsyncContext")))
|
||||
.transform(
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.jetty8.HttpServletRequestExtractAdapter",
|
||||
"datadog.trace.instrumentation.jetty8.HttpServletRequestExtractAdapter$MultivaluedMapFlatIterator",
|
||||
HandlerInstrumentationAdvice.class.getName() + "$TagSettingAsyncListener"))
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("handle")
|
||||
.and(takesArgument(0, named("java.lang.String")))
|
||||
.and(takesArgument(1, named("org.eclipse.jetty.server.Request")))
|
||||
.and(takesArgument(2, named("javax.servlet.http.HttpServletRequest")))
|
||||
.and(takesArgument(3, named("javax.servlet.http.HttpServletResponse")))
|
||||
.and(isPublic()),
|
||||
HandlerInstrumentationAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface())
|
||||
.and(hasSuperType(named("org.eclipse.jetty.server.Handler")))
|
||||
.and(not(named("org.eclipse.jetty.server.handler.HandlerWrapper")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return not(classLoaderHasClasses("org.eclipse.jetty.server.AsyncContext"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"datadog.trace.instrumentation.jetty8.HttpServletRequestExtractAdapter",
|
||||
"datadog.trace.instrumentation.jetty8.HttpServletRequestExtractAdapter$MultivaluedMapFlatIterator",
|
||||
HandlerInstrumentationAdvice.class.getName() + "$TagSettingAsyncListener"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("handle")
|
||||
.and(takesArgument(0, named("java.lang.String")))
|
||||
.and(takesArgument(1, named("org.eclipse.jetty.server.Request")))
|
||||
.and(takesArgument(2, named("javax.servlet.http.HttpServletRequest")))
|
||||
.and(takesArgument(3, named("javax.servlet.http.HttpServletResponse")))
|
||||
.and(isPublic()),
|
||||
HandlerInstrumentationAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class HandlerInstrumentationAdvice {
|
||||
|
|
|
@ -3,7 +3,6 @@ package datadog.trace.instrumentation.jms1;
|
|||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
import static datadog.trace.instrumentation.jms.util.JmsUtil.toResourceName;
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.failSafe;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||
|
@ -12,10 +11,7 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.agent.tooling.*;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
import datadog.trace.instrumentation.jms.util.MessagePropertyTextMap;
|
||||
|
@ -27,41 +23,51 @@ import io.opentracing.propagation.Format;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageConsumer;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class JMS1MessageConsumerInstrumentation extends Instrumenter.Configurable {
|
||||
public static final HelperInjector JMS1_HELPER_INJECTOR =
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.jms.util.JmsUtil",
|
||||
"datadog.trace.instrumentation.jms.util.MessagePropertyTextMap");
|
||||
public final class JMS1MessageConsumerInstrumentation extends Instrumenter.Default {
|
||||
public static final String[] JMS1_HELPER_CLASS_NAMES =
|
||||
new String[] {
|
||||
"datadog.trace.instrumentation.jms.util.JmsUtil",
|
||||
"datadog.trace.instrumentation.jms.util.MessagePropertyTextMap"
|
||||
};
|
||||
|
||||
public JMS1MessageConsumerInstrumentation() {
|
||||
super("jms", "jms-1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface()).and(failSafe(hasSuperType(named("javax.jms.MessageConsumer")))),
|
||||
not(classLoaderHasClasses("javax.jms.JMSContext", "javax.jms.CompletionListener")))
|
||||
.transform(JMS1_HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("receive").and(takesArguments(0).or(takesArguments(1))).and(isPublic()),
|
||||
ConsumerAdvice.class.getName())
|
||||
.advice(
|
||||
named("receiveNoWait").and(takesArguments(0)).and(isPublic()),
|
||||
ConsumerAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
||||
return not(isInterface()).and(hasSuperType(named("javax.jms.MessageConsumer")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return not(classLoaderHasClasses("javax.jms.JMSContext", "javax.jms.CompletionListener"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return JMS1_HELPER_CLASS_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("receive").and(takesArguments(0).or(takesArguments(1))).and(isPublic()),
|
||||
ConsumerAdvice.class.getName());
|
||||
transformers.put(
|
||||
named("receiveNoWait").and(takesArguments(0)).and(isPublic()),
|
||||
ConsumerAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class ConsumerAdvice {
|
||||
|
|
|
@ -12,8 +12,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -26,34 +24,42 @@ import io.opentracing.propagation.Format;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageListener;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class JMS1MessageListenerInstrumentation extends Instrumenter.Configurable {
|
||||
public final class JMS1MessageListenerInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public JMS1MessageListenerInstrumentation() {
|
||||
super("jms", "jms-1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface()).and(failSafe(hasSuperType(named("javax.jms.MessageListener")))),
|
||||
not(classLoaderHasClasses("javax.jms.JMSContext", "javax.jms.CompletionListener")))
|
||||
.transform(JMS1MessageConsumerInstrumentation.JMS1_HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("onMessage")
|
||||
.and(takesArgument(0, named("javax.jms.Message")))
|
||||
.and(isPublic()),
|
||||
MessageListenerAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.jms.MessageListener"))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return not(classLoaderHasClasses("javax.jms.JMSContext", "javax.jms.CompletionListener"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return JMS1MessageConsumerInstrumentation.JMS1_HELPER_CLASS_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("onMessage").and(takesArgument(0, named("javax.jms.Message"))).and(isPublic()),
|
||||
MessageListenerAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class MessageListenerAdvice {
|
||||
|
|
|
@ -12,8 +12,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -24,40 +22,50 @@ import io.opentracing.propagation.Format;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageProducer;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class JMS1MessageProducerInstrumentation extends Instrumenter.Configurable {
|
||||
public final class JMS1MessageProducerInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public JMS1MessageProducerInstrumentation() {
|
||||
super("jms", "jms-1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface()).and(failSafe(hasSuperType(named("javax.jms.MessageProducer")))),
|
||||
not(classLoaderHasClasses("javax.jms.JMSContext", "javax.jms.CompletionListener")))
|
||||
.transform(JMS1MessageConsumerInstrumentation.JMS1_HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("send").and(takesArgument(0, named("javax.jms.Message"))).and(isPublic()),
|
||||
ProducerAdvice.class.getName())
|
||||
.advice(
|
||||
named("send")
|
||||
.and(takesArgument(0, named("javax.jms.Destination")))
|
||||
.and(takesArgument(1, named("javax.jms.Message")))
|
||||
.and(isPublic()),
|
||||
ProducerWithDestinationAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.jms.MessageProducer"))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return not(classLoaderHasClasses("javax.jms.JMSContext", "javax.jms.CompletionListener"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return JMS1MessageConsumerInstrumentation.JMS1_HELPER_CLASS_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("send").and(takesArgument(0, named("javax.jms.Message"))).and(isPublic()),
|
||||
ProducerAdvice.class.getName());
|
||||
transformers.put(
|
||||
named("send")
|
||||
.and(takesArgument(0, named("javax.jms.Destination")))
|
||||
.and(takesArgument(1, named("javax.jms.Message")))
|
||||
.and(isPublic()),
|
||||
ProducerWithDestinationAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class ProducerAdvice {
|
||||
|
|
|
@ -12,9 +12,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -28,40 +25,51 @@ import io.opentracing.tag.Tags;
|
|||
import io.opentracing.util.GlobalTracer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageConsumer;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class JMS2MessageConsumerInstrumentation extends Instrumenter.Configurable {
|
||||
public static final HelperInjector JMS2_HELPER_INJECTOR =
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.jms.util.JmsUtil",
|
||||
"datadog.trace.instrumentation.jms.util.MessagePropertyTextMap");
|
||||
public final class JMS2MessageConsumerInstrumentation extends Instrumenter.Default {
|
||||
public static final String[] JMS2_HELPER_CLASS_NAMES =
|
||||
new String[] {
|
||||
"datadog.trace.instrumentation.jms.util.JmsUtil",
|
||||
"datadog.trace.instrumentation.jms.util.MessagePropertyTextMap"
|
||||
};
|
||||
|
||||
public JMS2MessageConsumerInstrumentation() {
|
||||
super("jms", "jms-2");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface()).and(failSafe(hasSuperType(named("javax.jms.MessageConsumer")))),
|
||||
classLoaderHasClasses("javax.jms.JMSContext", "javax.jms.CompletionListener"))
|
||||
.transform(JMS2_HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("receive").and(takesArguments(0).or(takesArguments(1))).and(isPublic()),
|
||||
ConsumerAdvice.class.getName())
|
||||
.advice(
|
||||
named("receiveNoWait").and(takesArguments(0)).and(isPublic()),
|
||||
ConsumerAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.jms.MessageConsumer"))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("javax.jms.JMSContext", "javax.jms.CompletionListener");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return JMS2_HELPER_CLASS_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("receive").and(takesArguments(0).or(takesArguments(1))).and(isPublic()),
|
||||
ConsumerAdvice.class.getName());
|
||||
transformers.put(
|
||||
named("receiveNoWait").and(takesArguments(0)).and(isPublic()),
|
||||
ConsumerAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class ConsumerAdvice {
|
||||
|
|
|
@ -12,8 +12,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -26,34 +24,42 @@ import io.opentracing.propagation.Format;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageListener;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class JMS2MessageListenerInstrumentation extends Instrumenter.Configurable {
|
||||
public final class JMS2MessageListenerInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public JMS2MessageListenerInstrumentation() {
|
||||
super("jms", "jms-2");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface()).and(failSafe(hasSuperType(named("javax.jms.MessageListener")))),
|
||||
classLoaderHasClasses("javax.jms.JMSContext", "javax.jms.CompletionListener"))
|
||||
.transform(JMS2MessageConsumerInstrumentation.JMS2_HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("onMessage")
|
||||
.and(takesArgument(0, named("javax.jms.Message")))
|
||||
.and(isPublic()),
|
||||
MessageListenerAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.jms.MessageListener"))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("javax.jms.JMSContext", "javax.jms.CompletionListener");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return JMS2MessageConsumerInstrumentation.JMS2_HELPER_CLASS_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("onMessage").and(takesArgument(0, named("javax.jms.Message"))).and(isPublic()),
|
||||
MessageListenerAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class MessageListenerAdvice {
|
||||
|
|
|
@ -12,8 +12,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -24,40 +22,50 @@ import io.opentracing.propagation.Format;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageProducer;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class JMS2MessageProducerInstrumentation extends Instrumenter.Configurable {
|
||||
public final class JMS2MessageProducerInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public JMS2MessageProducerInstrumentation() {
|
||||
super("jms", "jms-2");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface()).and(failSafe(hasSuperType(named("javax.jms.MessageProducer")))),
|
||||
classLoaderHasClasses("javax.jms.JMSContext", "javax.jms.CompletionListener"))
|
||||
.transform(JMS2MessageConsumerInstrumentation.JMS2_HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("send").and(takesArgument(0, named("javax.jms.Message"))).and(isPublic()),
|
||||
ProducerAdvice.class.getName())
|
||||
.advice(
|
||||
named("send")
|
||||
.and(takesArgument(0, named("javax.jms.Destination")))
|
||||
.and(takesArgument(1, named("javax.jms.Message")))
|
||||
.and(isPublic()),
|
||||
ProducerWithDestinationAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.jms.MessageProducer"))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("javax.jms.JMSContext", "javax.jms.CompletionListener");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return JMS2MessageConsumerInstrumentation.JMS2_HELPER_CLASS_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("send").and(takesArgument(0, named("javax.jms.Message"))).and(isPublic()),
|
||||
ProducerAdvice.class.getName());
|
||||
transformers.put(
|
||||
named("send")
|
||||
.and(takesArgument(0, named("javax.jms.Destination")))
|
||||
.and(takesArgument(1, named("javax.jms.Message")))
|
||||
.and(isPublic()),
|
||||
ProducerWithDestinationAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class ProducerAdvice {
|
||||
|
|
|
@ -4,8 +4,6 @@ import static io.opentracing.log.Fields.ERROR_OBJECT;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -14,14 +12,16 @@ import io.opentracing.Span;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class JSPInstrumentation extends Instrumenter.Configurable {
|
||||
public final class JSPInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public JSPInstrumentation() {
|
||||
super("jsp", "jsp-render");
|
||||
|
@ -33,19 +33,20 @@ public final class JSPInstrumentation extends Instrumenter.Configurable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(not(isInterface()).and(hasSuperType(named("javax.servlet.jsp.HttpJspPage"))))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("_jspService")
|
||||
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest")))
|
||||
.and(takesArgument(1, named("javax.servlet.http.HttpServletResponse")))
|
||||
.and(isPublic()),
|
||||
HttpJspPageAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(hasSuperType(named("javax.servlet.jsp.HttpJspPage")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("_jspService")
|
||||
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest")))
|
||||
.and(takesArgument(1, named("javax.servlet.http.HttpServletResponse")))
|
||||
.and(isPublic()),
|
||||
HttpJspPageAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class HttpJspPageAdvice {
|
||||
|
|
|
@ -5,8 +5,6 @@ import static io.opentracing.log.Fields.ERROR_OBJECT;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -15,12 +13,14 @@ import io.opentracing.Span;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.apache.jasper.JspCompilationContext;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class JasperJSPCompilationContextInstrumentation extends Instrumenter.Configurable {
|
||||
public final class JasperJSPCompilationContextInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public JasperJSPCompilationContextInstrumentation() {
|
||||
super("jsp", "jsp-compile");
|
||||
|
@ -32,18 +32,22 @@ public final class JasperJSPCompilationContextInstrumentation extends Instrument
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("org.apache.jasper.JspCompilationContext"),
|
||||
classLoaderHasClasses("org.apache.jasper.servlet.JspServletWrapper"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("compile").and(takesArguments(0)).and(isPublic()),
|
||||
JasperJspCompilationContext.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("org.apache.jasper.JspCompilationContext");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("org.apache.jasper.servlet.JspServletWrapper");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("compile").and(takesArguments(0)).and(isPublic()),
|
||||
JasperJspCompilationContext.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class JasperJspCompilationContext {
|
||||
|
|
|
@ -9,9 +9,6 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -20,51 +17,62 @@ import io.opentracing.Tracer;
|
|||
import io.opentracing.propagation.Format;
|
||||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class KafkaConsumerInstrumentation extends Instrumenter.Configurable {
|
||||
public static final HelperInjector HELPER_INJECTOR =
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.kafka_clients.TextMapExtractAdapter",
|
||||
"datadog.trace.instrumentation.kafka_clients.TracingIterable",
|
||||
"datadog.trace.instrumentation.kafka_clients.TracingIterable$TracingIterator",
|
||||
"datadog.trace.instrumentation.kafka_clients.TracingIterable$SpanBuilderDecorator",
|
||||
"datadog.trace.instrumentation.kafka_clients.KafkaConsumerInstrumentation$ConsumeScopeAction");
|
||||
public final class KafkaConsumerInstrumentation extends Instrumenter.Default {
|
||||
private static final String[] HELPER_CLASS_NAMES =
|
||||
new String[] {
|
||||
"datadog.trace.instrumentation.kafka_clients.TextMapExtractAdapter",
|
||||
"datadog.trace.instrumentation.kafka_clients.TracingIterable",
|
||||
"datadog.trace.instrumentation.kafka_clients.TracingIterable$TracingIterator",
|
||||
"datadog.trace.instrumentation.kafka_clients.TracingIterable$SpanBuilderDecorator",
|
||||
"datadog.trace.instrumentation.kafka_clients.KafkaConsumerInstrumentation$ConsumeScopeAction"
|
||||
};
|
||||
|
||||
public KafkaConsumerInstrumentation() {
|
||||
super("kafka");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("org.apache.kafka.clients.consumer.ConsumerRecords"),
|
||||
classLoaderHasClasses(
|
||||
"org.apache.kafka.common.header.Header", "org.apache.kafka.common.header.Headers"))
|
||||
.transform(HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(named("records"))
|
||||
.and(takesArgument(0, String.class))
|
||||
.and(returns(Iterable.class)),
|
||||
IterableAdvice.class.getName())
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(named("iterator"))
|
||||
.and(takesArguments(0))
|
||||
.and(returns(Iterator.class)),
|
||||
IteratorAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("org.apache.kafka.clients.consumer.ConsumerRecords");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses(
|
||||
"org.apache.kafka.common.header.Header", "org.apache.kafka.common.header.Headers");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return HELPER_CLASS_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(named("records"))
|
||||
.and(takesArgument(0, String.class))
|
||||
.and(returns(Iterable.class)),
|
||||
IterableAdvice.class.getName());
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(named("iterator"))
|
||||
.and(takesArguments(0))
|
||||
.and(returns(Iterator.class)),
|
||||
IteratorAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class IterableAdvice {
|
||||
|
|
|
@ -8,9 +8,6 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -20,18 +17,21 @@ import io.opentracing.propagation.Format;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.apache.kafka.clients.producer.Callback;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import org.apache.kafka.clients.producer.RecordMetadata;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class KafkaProducerInstrumentation extends Instrumenter.Configurable {
|
||||
public static final HelperInjector HELPER_INJECTOR =
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.kafka_clients.TextMapInjectAdapter",
|
||||
KafkaProducerInstrumentation.class.getName() + "$ProducerCallback");
|
||||
public final class KafkaProducerInstrumentation extends Instrumenter.Default {
|
||||
private static final String[] HELPER_CLASS_NAMES =
|
||||
new String[] {
|
||||
"datadog.trace.instrumentation.kafka_clients.TextMapInjectAdapter",
|
||||
KafkaProducerInstrumentation.class.getName() + "$ProducerCallback"
|
||||
};
|
||||
|
||||
private static final String OPERATION = "kafka.produce";
|
||||
private static final String COMPONENT_NAME = "java-kafka";
|
||||
|
@ -41,26 +41,32 @@ public final class KafkaProducerInstrumentation extends Instrumenter.Configurabl
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("org.apache.kafka.clients.producer.KafkaProducer"),
|
||||
classLoaderHasClasses(
|
||||
"org.apache.kafka.common.header.Header", "org.apache.kafka.common.header.Headers"))
|
||||
.transform(HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(named("send"))
|
||||
.and(
|
||||
takesArgument(
|
||||
0, named("org.apache.kafka.clients.producer.ProducerRecord")))
|
||||
.and(takesArgument(1, named("org.apache.kafka.clients.producer.Callback"))),
|
||||
ProducerAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("org.apache.kafka.clients.producer.KafkaProducer");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses(
|
||||
"org.apache.kafka.common.header.Header", "org.apache.kafka.common.header.Headers");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return HELPER_CLASS_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(named("send"))
|
||||
.and(takesArgument(0, named("org.apache.kafka.clients.producer.ProducerRecord")))
|
||||
.and(takesArgument(1, named("org.apache.kafka.clients.producer.Callback"))),
|
||||
ProducerAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class ProducerAdvice {
|
||||
|
|
|
@ -5,8 +5,7 @@ versionScan {
|
|||
module = "kafka-streams"
|
||||
versions = "[0.11.0.0,)"
|
||||
verifyPresent = [
|
||||
'org.apache.kafka.streams.state.internals.CacheFunction' : null,
|
||||
'org.apache.kafka.streams.state.internals.InMemoryKeyValueStore': null,
|
||||
'org.apache.kafka.streams.state.internals.OrderedBytes' : null
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -10,9 +10,6 @@ import static net.bytebuddy.matcher.ElementMatchers.returns;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -23,44 +20,51 @@ import io.opentracing.propagation.Format;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.apache.kafka.streams.processor.internals.StampedRecord;
|
||||
|
||||
public class KafkaStreamsProcessorInstrumentation {
|
||||
// These two instrumentations work together to apply StreamTask.process.
|
||||
// The combination of these are needed because there's not a good instrumentation point.
|
||||
|
||||
public static final HelperInjector HELPER_INJECTOR =
|
||||
new HelperInjector("datadog.trace.instrumentation.kafka_streams.TextMapExtractAdapter");
|
||||
public static final String[] HELPER_CLASS_NAMES =
|
||||
new String[] {"datadog.trace.instrumentation.kafka_streams.TextMapExtractAdapter"};
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public static class StartInstrumentation extends Instrumenter.Configurable {
|
||||
public static class StartInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public StartInstrumentation() {
|
||||
super("kafka", "kafka-streams");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("org.apache.kafka.streams.processor.internals.PartitionGroup"),
|
||||
classLoaderHasClasses("org.apache.kafka.streams.state.internals.KeyValueIterators"))
|
||||
.transform(HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(isPackagePrivate())
|
||||
.and(named("nextRecord"))
|
||||
.and(
|
||||
returns(
|
||||
named(
|
||||
"org.apache.kafka.streams.processor.internals.StampedRecord"))),
|
||||
StartSpanAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("org.apache.kafka.streams.processor.internals.PartitionGroup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("org.apache.kafka.streams.state.internals.OrderedBytes");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return HELPER_CLASS_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isPackagePrivate())
|
||||
.and(named("nextRecord"))
|
||||
.and(returns(named("org.apache.kafka.streams.processor.internals.StampedRecord"))),
|
||||
StartSpanAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class StartSpanAdvice {
|
||||
|
@ -92,28 +96,35 @@ public class KafkaStreamsProcessorInstrumentation {
|
|||
}
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public static class StopInstrumentation extends Instrumenter.Configurable {
|
||||
public static class StopInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public StopInstrumentation() {
|
||||
super("kafka", "kafka-streams");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("org.apache.kafka.streams.processor.internals.StreamTask"),
|
||||
classLoaderHasClasses(
|
||||
"org.apache.kafka.common.header.Header",
|
||||
"org.apache.kafka.common.header.Headers"))
|
||||
.transform(HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod().and(isPublic()).and(named("process")).and(takesArguments(0)),
|
||||
StopSpanAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("org.apache.kafka.streams.processor.internals.StreamTask");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses(
|
||||
"org.apache.kafka.common.header.Header", "org.apache.kafka.common.header.Headers");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return HELPER_CLASS_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod().and(isPublic()).and(named("process")).and(takesArguments(0)),
|
||||
StopSpanAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class StopSpanAdvice {
|
||||
|
|
|
@ -8,42 +8,43 @@ import static net.bytebuddy.matcher.ElementMatchers.returns;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.apache.kafka.common.record.TimestampType;
|
||||
|
||||
// This is necessary because SourceNodeRecordDeserializer drops the headers. :-(
|
||||
@AutoService(Instrumenter.class)
|
||||
public class KafkaStreamsSourceNodeRecordDeserializerInstrumentation
|
||||
extends Instrumenter.Configurable {
|
||||
public class KafkaStreamsSourceNodeRecordDeserializerInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public KafkaStreamsSourceNodeRecordDeserializerInstrumentation() {
|
||||
super("kafka", "kafka-streams");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("org.apache.kafka.streams.processor.internals.SourceNodeRecordDeserializer"),
|
||||
classLoaderHasClasses("org.apache.kafka.streams.state.internals.KeyValueIterators"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(named("deserialize"))
|
||||
.and(
|
||||
takesArgument(
|
||||
0, named("org.apache.kafka.clients.consumer.ConsumerRecord")))
|
||||
.and(returns(named("org.apache.kafka.clients.consumer.ConsumerRecord"))),
|
||||
SaveHeadersAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("org.apache.kafka.streams.processor.internals.SourceNodeRecordDeserializer");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("org.apache.kafka.streams.state.internals.OrderedBytes");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(named("deserialize"))
|
||||
.and(takesArgument(0, named("org.apache.kafka.clients.consumer.ConsumerRecord")))
|
||||
.and(returns(named("org.apache.kafka.clients.consumer.ConsumerRecord"))),
|
||||
SaveHeadersAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class SaveHeadersAdvice {
|
||||
|
|
|
@ -4,21 +4,13 @@ import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClass
|
|||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class LettuceAsyncCommandsInstrumentation extends Instrumenter.Configurable {
|
||||
|
||||
private static final HelperInjector REDIS_ASYNC_HELPERS =
|
||||
new HelperInjector(
|
||||
LettuceAsyncCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".LettuceAsyncBiFunction",
|
||||
LettuceAsyncCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".LettuceInstrumentationUtil");
|
||||
public class LettuceAsyncCommandsInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public LettuceAsyncCommandsInstrumentation() {
|
||||
super("lettuce", "lettuce-5-async");
|
||||
|
@ -30,20 +22,32 @@ public class LettuceAsyncCommandsInstrumentation extends Instrumenter.Configurab
|
|||
}
|
||||
|
||||
@Override
|
||||
protected AgentBuilder apply(AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("io.lettuce.core.AbstractRedisAsyncCommands"),
|
||||
classLoaderHasClasses("io.lettuce.core.RedisClient"))
|
||||
.transform(REDIS_ASYNC_HELPERS)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(named("dispatch"))
|
||||
.and(takesArgument(0, named("io.lettuce.core.protocol.RedisCommand"))),
|
||||
LettuceAsyncCommandsAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("io.lettuce.core.AbstractRedisAsyncCommands");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("io.lettuce.core.RedisClient");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
LettuceAsyncCommandsInstrumentation.class.getPackage().getName() + ".LettuceAsyncBiFunction",
|
||||
LettuceAsyncCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".LettuceInstrumentationUtil"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(named("dispatch"))
|
||||
.and(takesArgument(0, named("io.lettuce.core.protocol.RedisCommand"))),
|
||||
LettuceAsyncCommandsAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,20 +4,20 @@ import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClass
|
|||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class LettuceClientInstrumentation extends Instrumenter.Configurable {
|
||||
public final class LettuceClientInstrumentation extends Instrumenter.Default {
|
||||
|
||||
private static final HelperInjector REDIS_ASYNC_HELPERS =
|
||||
new HelperInjector(
|
||||
LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".LettuceInstrumentationUtil",
|
||||
LettuceClientInstrumentation.class.getPackage().getName() + ".LettuceAsyncBiFunction");
|
||||
private static final String[] HELPER_CLASS_NAMES =
|
||||
new String[] {
|
||||
LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".LettuceInstrumentationUtil",
|
||||
LettuceClientInstrumentation.class.getPackage().getName() + ".LettuceAsyncBiFunction"
|
||||
};
|
||||
|
||||
public LettuceClientInstrumentation() {
|
||||
super("lettuce");
|
||||
|
@ -29,23 +29,31 @@ public final class LettuceClientInstrumentation extends Instrumenter.Configurabl
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("io.lettuce.core.RedisClient"),
|
||||
classLoaderHasClasses("io.lettuce.core.RedisClient"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(REDIS_ASYNC_HELPERS)
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(isPrivate())
|
||||
.and(returns(named("io.lettuce.core.ConnectionFuture")))
|
||||
.and(nameStartsWith("connect"))
|
||||
.and(nameEndsWith("Async"))
|
||||
.and(takesArgument(1, named("io.lettuce.core.RedisURI"))),
|
||||
ConnectionFutureAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("io.lettuce.core.RedisClient");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("io.lettuce.core.RedisClient");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return HELPER_CLASS_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isPrivate())
|
||||
.and(returns(named("io.lettuce.core.ConnectionFuture")))
|
||||
.and(nameStartsWith("connect"))
|
||||
.and(nameEndsWith("Async"))
|
||||
.and(takesArgument(1, named("io.lettuce.core.RedisURI"))),
|
||||
ConnectionFutureAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,31 +4,15 @@ import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClass
|
|||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.instrumentation.lettuce.rx.LettuceFluxCreationAdvice;
|
||||
import datadog.trace.instrumentation.lettuce.rx.LettuceMonoCreationAdvice;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class LettuceReactiveCommandsInstrumentation extends Instrumenter.Configurable {
|
||||
|
||||
private static final HelperInjector REDIS_RX_HELPERS =
|
||||
new HelperInjector(
|
||||
LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".LettuceInstrumentationUtil",
|
||||
LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".rx.LettuceMonoCreationAdvice",
|
||||
LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".rx.LettuceMonoDualConsumer",
|
||||
LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".rx.LettuceFluxCreationAdvice",
|
||||
LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".rx.LettuceFluxTerminationRunnable",
|
||||
LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".rx.LettuceFluxTerminationRunnable$FluxOnSubscribeConsumer");
|
||||
public class LettuceReactiveCommandsInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public LettuceReactiveCommandsInstrumentation() {
|
||||
super("lettuce", "lettuce-5-rx");
|
||||
|
@ -40,28 +24,50 @@ public class LettuceReactiveCommandsInstrumentation extends Instrumenter.Configu
|
|||
}
|
||||
|
||||
@Override
|
||||
protected AgentBuilder apply(AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("io.lettuce.core.AbstractRedisReactiveCommands"),
|
||||
classLoaderHasClasses("io.lettuce.core.RedisClient"))
|
||||
.transform(REDIS_RX_HELPERS)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(named("createMono"))
|
||||
.and(takesArgument(0, named("java.util.function.Supplier")))
|
||||
.and(returns(named("reactor.core.publisher.Mono"))),
|
||||
LettuceMonoCreationAdvice.class.getName())
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(nameStartsWith("create"))
|
||||
.and(nameEndsWith("Flux"))
|
||||
.and(takesArgument(0, named("java.util.function.Supplier")))
|
||||
.and(returns(named(("reactor.core.publisher.Flux")))),
|
||||
LettuceFluxCreationAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("io.lettuce.core.AbstractRedisReactiveCommands");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("io.lettuce.core.RedisClient");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".LettuceInstrumentationUtil",
|
||||
LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".rx.LettuceMonoCreationAdvice",
|
||||
LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".rx.LettuceMonoDualConsumer",
|
||||
LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".rx.LettuceFluxCreationAdvice",
|
||||
LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".rx.LettuceFluxTerminationRunnable",
|
||||
LettuceReactiveCommandsInstrumentation.class.getPackage().getName()
|
||||
+ ".rx.LettuceFluxTerminationRunnable$FluxOnSubscribeConsumer"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(named("createMono"))
|
||||
.and(takesArgument(0, named("java.util.function.Supplier")))
|
||||
.and(returns(named("reactor.core.publisher.Mono"))),
|
||||
LettuceMonoCreationAdvice.class.getName());
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(nameStartsWith("create"))
|
||||
.and(nameEndsWith("Flux"))
|
||||
.and(takesArgument(0, named("java.util.function.Supplier")))
|
||||
.and(returns(named(("reactor.core.publisher.Flux")))),
|
||||
LettuceFluxCreationAdvice.class.getName());
|
||||
|
||||
return transformers;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,50 +8,53 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
|||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.mongodb.MongoClientOptions;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class MongoClientInstrumentation extends Instrumenter.Configurable {
|
||||
public static final HelperInjector MONGO_HELPER_INJECTOR =
|
||||
new HelperInjector("datadog.trace.instrumentation.mongo.DDTracingCommandListener");
|
||||
public final class MongoClientInstrumentation extends Instrumenter.Default {
|
||||
public static final String[] HELPERS =
|
||||
new String[] {"datadog.trace.instrumentation.mongo.DDTracingCommandListener"};
|
||||
|
||||
public MongoClientInstrumentation() {
|
||||
super("mongo");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("com.mongodb.MongoClientOptions$Builder")
|
||||
.and(
|
||||
declaresMethod(
|
||||
named("addCommandListener")
|
||||
.and(
|
||||
takesArguments(
|
||||
new TypeDescription.Latent(
|
||||
"com.mongodb.event.CommandListener",
|
||||
Modifier.PUBLIC,
|
||||
null,
|
||||
Collections.<TypeDescription.Generic>emptyList())))
|
||||
.and(isPublic()))))
|
||||
.transform(MONGO_HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod().and(isPublic()).and(named("build")).and(takesArguments(0)),
|
||||
MongoClientAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("com.mongodb.MongoClientOptions$Builder")
|
||||
.and(
|
||||
declaresMethod(
|
||||
named("addCommandListener")
|
||||
.and(
|
||||
takesArguments(
|
||||
new TypeDescription.Latent(
|
||||
"com.mongodb.event.CommandListener",
|
||||
Modifier.PUBLIC,
|
||||
null,
|
||||
Collections.<TypeDescription.Generic>emptyList())))
|
||||
.and(isPublic())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return HELPERS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod().and(isPublic()).and(named("build")).and(takesArguments(0)),
|
||||
MongoClientAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class MongoClientAdvice {
|
||||
|
|
|
@ -8,47 +8,51 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
|||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.mongodb.async.client.MongoClientSettings;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class MongoAsyncClientInstrumentation extends Instrumenter.Configurable {
|
||||
public final class MongoAsyncClientInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public MongoAsyncClientInstrumentation() {
|
||||
super("mongo");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("com.mongodb.async.client.MongoClientSettings$Builder")
|
||||
.and(
|
||||
declaresMethod(
|
||||
named("addCommandListener")
|
||||
.and(
|
||||
takesArguments(
|
||||
new TypeDescription.Latent(
|
||||
"com.mongodb.event.CommandListener",
|
||||
Modifier.PUBLIC,
|
||||
null,
|
||||
Collections.<TypeDescription.Generic>emptyList())))
|
||||
.and(isPublic()))))
|
||||
.transform(MongoClientInstrumentation.MONGO_HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod().and(isPublic()).and(named("build")).and(takesArguments(0)),
|
||||
MongoAsyncClientAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("com.mongodb.async.client.MongoClientSettings$Builder")
|
||||
.and(
|
||||
declaresMethod(
|
||||
named("addCommandListener")
|
||||
.and(
|
||||
takesArguments(
|
||||
new TypeDescription.Latent(
|
||||
"com.mongodb.event.CommandListener",
|
||||
Modifier.PUBLIC,
|
||||
null,
|
||||
Collections.<TypeDescription.Generic>emptyList())))
|
||||
.and(isPublic())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return MongoClientInstrumentation.HELPERS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod().and(isPublic()).and(named("build")).and(takesArguments(0)),
|
||||
MongoAsyncClientAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class MongoAsyncClientAdvice {
|
||||
|
|
|
@ -10,9 +10,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
|
||||
import datadog.trace.instrumentation.netty40.client.HttpClientRequestTracingHandler;
|
||||
|
@ -29,11 +26,13 @@ import io.netty.handler.codec.http.HttpRequestEncoder;
|
|||
import io.netty.handler.codec.http.HttpResponseDecoder;
|
||||
import io.netty.handler.codec.http.HttpResponseEncoder;
|
||||
import io.netty.handler.codec.http.HttpServerCodec;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class NettyChannelPipelineInstrumentation extends Instrumenter.Configurable {
|
||||
public class NettyChannelPipelineInstrumentation extends Instrumenter.Default {
|
||||
|
||||
private static final String PACKAGE =
|
||||
NettyChannelPipelineInstrumentation.class.getPackage().getName();
|
||||
|
@ -48,32 +47,40 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Configurab
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface()).and(hasSuperType(named("io.netty.channel.ChannelPipeline"))),
|
||||
classLoaderHasClasses("io.netty.channel.local.LocalEventLoop"))
|
||||
.transform(
|
||||
new HelperInjector(
|
||||
// client helpers
|
||||
PACKAGE + ".client.NettyResponseInjectAdapter",
|
||||
PACKAGE + ".client.HttpClientRequestTracingHandler",
|
||||
PACKAGE + ".client.HttpClientResponseTracingHandler",
|
||||
PACKAGE + ".client.HttpClientTracingHandler",
|
||||
// server helpers
|
||||
PACKAGE + ".server.NettyRequestExtractAdapter",
|
||||
PACKAGE + ".server.HttpServerRequestTracingHandler",
|
||||
PACKAGE + ".server.HttpServerResponseTracingHandler",
|
||||
PACKAGE + ".server.HttpServerTracingHandler"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(nameStartsWith("add"))
|
||||
.and(takesArgument(2, named("io.netty.channel.ChannelHandler"))),
|
||||
ChannelPipelineAddAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(hasSuperType(named("io.netty.channel.ChannelPipeline")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("io.netty.channel.local.LocalEventLoop");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
// client helpers
|
||||
PACKAGE + ".client.NettyResponseInjectAdapter",
|
||||
PACKAGE + ".client.HttpClientRequestTracingHandler",
|
||||
PACKAGE + ".client.HttpClientResponseTracingHandler",
|
||||
PACKAGE + ".client.HttpClientTracingHandler",
|
||||
// server helpers
|
||||
PACKAGE + ".server.NettyRequestExtractAdapter",
|
||||
PACKAGE + ".server.HttpServerRequestTracingHandler",
|
||||
PACKAGE + ".server.HttpServerResponseTracingHandler",
|
||||
PACKAGE + ".server.HttpServerTracingHandler"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(nameStartsWith("add"))
|
||||
.and(takesArgument(2, named("io.netty.channel.ChannelHandler"))),
|
||||
ChannelPipelineAddAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,9 +10,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
|
||||
import datadog.trace.instrumentation.netty41.client.HttpClientRequestTracingHandler;
|
||||
|
@ -29,11 +26,13 @@ import io.netty.handler.codec.http.HttpRequestEncoder;
|
|||
import io.netty.handler.codec.http.HttpResponseDecoder;
|
||||
import io.netty.handler.codec.http.HttpResponseEncoder;
|
||||
import io.netty.handler.codec.http.HttpServerCodec;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class NettyChannelPipelineInstrumentation extends Instrumenter.Configurable {
|
||||
public class NettyChannelPipelineInstrumentation extends Instrumenter.Default {
|
||||
|
||||
private static final String PACKAGE =
|
||||
NettyChannelPipelineInstrumentation.class.getPackage().getName();
|
||||
|
@ -48,32 +47,40 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Configurab
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface()).and(hasSuperType(named("io.netty.channel.ChannelPipeline"))),
|
||||
classLoaderHasClasses("io.netty.handler.codec.http2.DefaultHttp2ConnectionDecoder"))
|
||||
.transform(
|
||||
new HelperInjector(
|
||||
// client helpers
|
||||
PACKAGE + ".client.NettyResponseInjectAdapter",
|
||||
PACKAGE + ".client.HttpClientRequestTracingHandler",
|
||||
PACKAGE + ".client.HttpClientResponseTracingHandler",
|
||||
PACKAGE + ".client.HttpClientTracingHandler",
|
||||
// server helpers
|
||||
PACKAGE + ".server.NettyRequestExtractAdapter",
|
||||
PACKAGE + ".server.HttpServerRequestTracingHandler",
|
||||
PACKAGE + ".server.HttpServerResponseTracingHandler",
|
||||
PACKAGE + ".server.HttpServerTracingHandler"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(nameStartsWith("add"))
|
||||
.and(takesArgument(2, named("io.netty.channel.ChannelHandler"))),
|
||||
ChannelPipelineAddAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(hasSuperType(named("io.netty.channel.ChannelPipeline")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("io.netty.handler.codec.http2.DefaultHttp2ConnectionDecoder");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
// client helpers
|
||||
PACKAGE + ".client.NettyResponseInjectAdapter",
|
||||
PACKAGE + ".client.HttpClientRequestTracingHandler",
|
||||
PACKAGE + ".client.HttpClientResponseTracingHandler",
|
||||
PACKAGE + ".client.HttpClientTracingHandler",
|
||||
// server helpers
|
||||
PACKAGE + ".server.NettyRequestExtractAdapter",
|
||||
PACKAGE + ".server.HttpServerRequestTracingHandler",
|
||||
PACKAGE + ".server.HttpServerResponseTracingHandler",
|
||||
PACKAGE + ".server.HttpServerTracingHandler"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(nameStartsWith("add"))
|
||||
.and(takesArgument(2, named("io.netty.channel.ChannelHandler"))),
|
||||
ChannelPipelineAddAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,57 +7,64 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class OkHttp3Instrumentation extends Instrumenter.Configurable {
|
||||
public class OkHttp3Instrumentation extends Instrumenter.Default {
|
||||
|
||||
public OkHttp3Instrumentation() {
|
||||
super("okhttp", "okhttp-3");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("okhttp3.OkHttpClient"),
|
||||
classLoaderHasClasses(
|
||||
"okhttp3.Request",
|
||||
"okhttp3.Response",
|
||||
"okhttp3.Connection",
|
||||
"okhttp3.Cookie",
|
||||
"okhttp3.ConnectionPool",
|
||||
"okhttp3.Headers"))
|
||||
.transform(
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.okhttp3.OkHttpClientSpanDecorator",
|
||||
"datadog.trace.instrumentation.okhttp3.OkHttpClientSpanDecorator$1",
|
||||
"datadog.trace.instrumentation.okhttp3.RequestBuilderInjectAdapter",
|
||||
"datadog.trace.instrumentation.okhttp3.TagWrapper",
|
||||
"datadog.trace.instrumentation.okhttp3.TracedCallable",
|
||||
"datadog.trace.instrumentation.okhttp3.TracedExecutor",
|
||||
"datadog.trace.instrumentation.okhttp3.TracedExecutorService",
|
||||
"datadog.trace.instrumentation.okhttp3.TracedRunnable",
|
||||
"datadog.trace.instrumentation.okhttp3.TracingInterceptor",
|
||||
"datadog.trace.instrumentation.okhttp3.TracingCallFactory",
|
||||
"datadog.trace.instrumentation.okhttp3.TracingCallFactory$NetworkInterceptor",
|
||||
"datadog.trace.instrumentation.okhttp3.TracingCallFactory$1"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isConstructor().and(takesArgument(0, named("okhttp3.OkHttpClient$Builder"))),
|
||||
OkHttp3Advice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("okhttp3.OkHttpClient");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses(
|
||||
"okhttp3.Request",
|
||||
"okhttp3.Response",
|
||||
"okhttp3.Connection",
|
||||
"okhttp3.Cookie",
|
||||
"okhttp3.ConnectionPool",
|
||||
"okhttp3.Headers");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"datadog.trace.instrumentation.okhttp3.OkHttpClientSpanDecorator",
|
||||
"datadog.trace.instrumentation.okhttp3.OkHttpClientSpanDecorator$1",
|
||||
"datadog.trace.instrumentation.okhttp3.RequestBuilderInjectAdapter",
|
||||
"datadog.trace.instrumentation.okhttp3.TagWrapper",
|
||||
"datadog.trace.instrumentation.okhttp3.TracedCallable",
|
||||
"datadog.trace.instrumentation.okhttp3.TracedExecutor",
|
||||
"datadog.trace.instrumentation.okhttp3.TracedExecutorService",
|
||||
"datadog.trace.instrumentation.okhttp3.TracedRunnable",
|
||||
"datadog.trace.instrumentation.okhttp3.TracingInterceptor",
|
||||
"datadog.trace.instrumentation.okhttp3.TracingCallFactory",
|
||||
"datadog.trace.instrumentation.okhttp3.TracingCallFactory$NetworkInterceptor",
|
||||
"datadog.trace.instrumentation.okhttp3.TracingCallFactory$1"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isConstructor().and(takesArgument(0, named("okhttp3.OkHttpClient$Builder"))),
|
||||
OkHttp3Advice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class OkHttp3Advice {
|
||||
|
|
|
@ -1,58 +1,55 @@
|
|||
package datadog.trace.instrumentation.osgi;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.agent.tooling.Utils;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.dynamic.DynamicType;
|
||||
import net.bytebuddy.utility.JavaModule;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import net.bytebuddy.matcher.NameMatcher;
|
||||
import net.bytebuddy.matcher.StringMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class OSGIClassloadingInstrumentation extends Instrumenter.Configurable {
|
||||
public final class OSGIClassloadingInstrumentation extends Instrumenter.Default {
|
||||
public OSGIClassloadingInstrumentation() {
|
||||
super("osgi-classloading");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
// OSGI Bundle class loads the sys prop which defines bootstrap classes
|
||||
.type(named("org.osgi.framework.Bundle"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
new AgentBuilder.Transformer() {
|
||||
@Override
|
||||
public DynamicType.Builder<?> transform(
|
||||
DynamicType.Builder<?> builder,
|
||||
TypeDescription typeDescription,
|
||||
ClassLoader classLoader,
|
||||
JavaModule javaModule) {
|
||||
// This instrumentation modifies no bytes.
|
||||
// Instead it sets a system prop to tell osgi to delegate
|
||||
// classloads for datadog bootstrap classes
|
||||
StringBuilder ddPrefixes = new StringBuilder("");
|
||||
for (int i = 0; i < Utils.BOOTSTRAP_PACKAGE_PREFIXES.length; ++i) {
|
||||
if (i > 0) {
|
||||
// must append twice. Once for exact package and wildcard for child packages
|
||||
ddPrefixes.append(",");
|
||||
}
|
||||
ddPrefixes.append(Utils.BOOTSTRAP_PACKAGE_PREFIXES[i]).append(".*,");
|
||||
ddPrefixes.append(Utils.BOOTSTRAP_PACKAGE_PREFIXES[i]);
|
||||
public ElementMatcher typeMatcher() {
|
||||
// OSGI Bundle class loads the sys prop which defines bootstrap classes
|
||||
return new NameMatcher(
|
||||
new StringMatcher("org.osgi.framework.Bundle", StringMatcher.Mode.EQUALS_FULLY) {
|
||||
@Override
|
||||
public boolean matches(String target) {
|
||||
if (super.matches(target)) {
|
||||
// This instrumentation modifies no bytes.
|
||||
// Instead it sets a system prop to tell osgi to delegate
|
||||
// classloads for datadog bootstrap classes
|
||||
StringBuilder ddPrefixes = new StringBuilder("");
|
||||
for (int i = 0; i < Utils.BOOTSTRAP_PACKAGE_PREFIXES.length; ++i) {
|
||||
if (i > 0) {
|
||||
// must append twice. Once for exact package and wildcard for child packages
|
||||
ddPrefixes.append(",");
|
||||
}
|
||||
final String existing = System.getProperty("org.osgi.framework.bootdelegation");
|
||||
if (null == existing) {
|
||||
System.setProperty("org.osgi.framework.bootdelegation", ddPrefixes.toString());
|
||||
} else if (!existing.contains(ddPrefixes)) {
|
||||
System.setProperty(
|
||||
"org.osgi.framework.bootdelegation", existing + "," + ddPrefixes.toString());
|
||||
}
|
||||
return builder;
|
||||
ddPrefixes.append(Utils.BOOTSTRAP_PACKAGE_PREFIXES[i]).append(".*,");
|
||||
ddPrefixes.append(Utils.BOOTSTRAP_PACKAGE_PREFIXES[i]);
|
||||
}
|
||||
})
|
||||
.asDecorator();
|
||||
final String existing = System.getProperty("org.osgi.framework.bootdelegation");
|
||||
if (null == existing) {
|
||||
System.setProperty("org.osgi.framework.bootdelegation", ddPrefixes.toString());
|
||||
} else if (!existing.contains(ddPrefixes)) {
|
||||
System.setProperty(
|
||||
"org.osgi.framework.bootdelegation", existing + "," + ddPrefixes.toString());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,8 @@ import io.opentracing.tag.Tags;
|
|||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import play.api.mvc.Action;
|
||||
import play.api.mvc.Request;
|
||||
|
@ -31,43 +31,47 @@ import scala.concurrent.Future;
|
|||
|
||||
@Slf4j
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class PlayInstrumentation extends Instrumenter.Configurable {
|
||||
private static final HelperInjector PLAY_HELPERS =
|
||||
new HelperInjector(
|
||||
PlayInstrumentation.class.getName() + "$RequestCallback",
|
||||
PlayInstrumentation.class.getName() + "$RequestError",
|
||||
PlayInstrumentation.class.getName() + "$PlayHeaders");
|
||||
public final class PlayInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public PlayInstrumentation() {
|
||||
super("play");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
hasSuperType(named("play.api.mvc.Action")),
|
||||
classLoaderHasClasses(
|
||||
"akka.japi.JavaPartialFunction",
|
||||
"play.api.mvc.Action",
|
||||
"play.api.mvc.Result",
|
||||
"scala.Option",
|
||||
"scala.Tuple2",
|
||||
"scala.concurrent.Future")
|
||||
.and(classLoaderHasClassWithMethod("play.api.mvc.Request", "tags")))
|
||||
.and(
|
||||
declaresMethod(
|
||||
named("executionContext").and(returns(named("scala.concurrent.ExecutionContext")))))
|
||||
.transform(PLAY_HELPERS)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("apply")
|
||||
.and(takesArgument(0, named("play.api.mvc.Request")))
|
||||
.and(returns(named("scala.concurrent.Future"))),
|
||||
PlayAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return hasSuperType(named("play.api.mvc.Action"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses(
|
||||
"akka.japi.JavaPartialFunction",
|
||||
"play.api.mvc.Action",
|
||||
"play.api.mvc.Result",
|
||||
"scala.Option",
|
||||
"scala.Tuple2",
|
||||
"scala.concurrent.Future")
|
||||
.and(classLoaderHasClassWithMethod("play.api.mvc.Request", "tags"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
PlayInstrumentation.class.getName() + "$RequestCallback",
|
||||
PlayInstrumentation.class.getName() + "$RequestError",
|
||||
PlayInstrumentation.class.getName() + "$PlayHeaders"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("apply")
|
||||
.and(takesArgument(0, named("play.api.mvc.Request")))
|
||||
.and(returns(named("scala.concurrent.Future"))),
|
||||
PlayAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class PlayAdvice {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package datadog.trace.instrumentation.ratpack;
|
||||
|
||||
import static datadog.trace.instrumentation.ratpack.RatpackInstrumentation.ROOT_RATPACK_HELPER_INJECTOR;
|
||||
import static datadog.trace.instrumentation.ratpack.RatpackInstrumentation.CLASSLOADER_CONTAINS_RATPACK_1_4_OR_ABOVE;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -8,27 +8,17 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.instrumentation.ratpack.impl.RatpackHttpClientAdvice;
|
||||
import java.net.URI;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class RatpackHttpClientInstrumentation extends Instrumenter.Configurable {
|
||||
public final class RatpackHttpClientInstrumentation extends Instrumenter.Default {
|
||||
|
||||
private static final HelperInjector HTTP_CLIENT_HELPER_INJECTOR =
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackHttpClientAdvice$RatpackHttpClientRequestAdvice",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackHttpClientAdvice$RatpackHttpClientRequestStreamAdvice",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackHttpClientAdvice$RatpackHttpGetAdvice",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackHttpClientAdvice$RequestAction",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackHttpClientAdvice$ResponseAction",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackHttpClientAdvice$StreamedResponseAction",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RequestSpecInjectAdapter",
|
||||
"datadog.trace.instrumentation.ratpack.impl.WrappedRequestSpec");
|
||||
public static final TypeDescription.ForLoadedType URI_TYPE_DESCRIPTION =
|
||||
new TypeDescription.ForLoadedType(URI.class);
|
||||
|
||||
|
@ -38,45 +28,59 @@ public final class RatpackHttpClientInstrumentation extends Instrumenter.Configu
|
|||
|
||||
@Override
|
||||
protected boolean defaultEnabled() {
|
||||
// FIXME: Injecting ContextualScopeManager is probably a bug. Verify and check all ratpack helpers before enabling.
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(hasSuperType(named("ratpack.http.client.HttpClient")));
|
||||
}
|
||||
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface()).and(hasSuperType(named("ratpack.http.client.HttpClient"))),
|
||||
RatpackInstrumentation.CLASSLOADER_CONTAINS_RATPACK_1_4_OR_ABOVE)
|
||||
.transform(ROOT_RATPACK_HELPER_INJECTOR)
|
||||
.transform(HTTP_CLIENT_HELPER_INJECTOR)
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("request")
|
||||
.and(
|
||||
takesArguments(
|
||||
URI_TYPE_DESCRIPTION,
|
||||
RatpackInstrumentation.ACTION_TYPE_DESCRIPTION)),
|
||||
RatpackHttpClientAdvice.RatpackHttpClientRequestAdvice.class.getName()))
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("requestStream")
|
||||
.and(
|
||||
takesArguments(
|
||||
URI_TYPE_DESCRIPTION,
|
||||
RatpackInstrumentation.ACTION_TYPE_DESCRIPTION)),
|
||||
RatpackHttpClientAdvice.RatpackHttpClientRequestStreamAdvice.class.getName()))
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("get")
|
||||
.and(
|
||||
takesArguments(
|
||||
URI_TYPE_DESCRIPTION,
|
||||
RatpackInstrumentation.ACTION_TYPE_DESCRIPTION)),
|
||||
RatpackHttpClientAdvice.RatpackHttpGetAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return CLASSLOADER_CONTAINS_RATPACK_1_4_OR_ABOVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
// http helpers
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackHttpClientAdvice$RatpackHttpClientRequestAdvice",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackHttpClientAdvice$RatpackHttpClientRequestStreamAdvice",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackHttpClientAdvice$RatpackHttpGetAdvice",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackHttpClientAdvice$RequestAction",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackHttpClientAdvice$ResponseAction",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackHttpClientAdvice$StreamedResponseAction",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RequestSpecInjectAdapter",
|
||||
"datadog.trace.instrumentation.ratpack.impl.WrappedRequestSpec",
|
||||
// core helpers
|
||||
"datadog.opentracing.scopemanager.ContextualScopeManager",
|
||||
"datadog.opentracing.scopemanager.ScopeContext"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("request")
|
||||
.and(
|
||||
takesArguments(
|
||||
URI_TYPE_DESCRIPTION, RatpackInstrumentation.ACTION_TYPE_DESCRIPTION)),
|
||||
RatpackHttpClientAdvice.RatpackHttpClientRequestAdvice.class.getName());
|
||||
transformers.put(
|
||||
named("requestStream")
|
||||
.and(
|
||||
takesArguments(
|
||||
URI_TYPE_DESCRIPTION, RatpackInstrumentation.ACTION_TYPE_DESCRIPTION)),
|
||||
RatpackHttpClientAdvice.RatpackHttpClientRequestStreamAdvice.class.getName());
|
||||
transformers.put(
|
||||
named("get")
|
||||
.and(
|
||||
takesArguments(
|
||||
URI_TYPE_DESCRIPTION, RatpackInstrumentation.ACTION_TYPE_DESCRIPTION)),
|
||||
RatpackHttpClientAdvice.RatpackHttpGetAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,38 +4,21 @@ import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClass
|
|||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.instrumentation.ratpack.impl.RatpackServerAdvice;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
@Slf4j
|
||||
public final class RatpackInstrumentation extends Instrumenter.Configurable {
|
||||
public final class RatpackInstrumentation extends Instrumenter.Default {
|
||||
|
||||
static final String EXEC_NAME = "ratpack";
|
||||
|
||||
static final HelperInjector ROOT_RATPACK_HELPER_INJECTOR =
|
||||
new HelperInjector(
|
||||
"datadog.opentracing.scopemanager.ContextualScopeManager",
|
||||
"datadog.opentracing.scopemanager.ScopeContext");
|
||||
|
||||
private static final HelperInjector SERVER_REGISTRY_HELPER_INJECTOR =
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackRequestExtractAdapter",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackScopeManager",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackServerAdvice$RatpackServerRegistryAdvice",
|
||||
"datadog.trace.instrumentation.ratpack.impl.TracingHandler");
|
||||
private static final HelperInjector EXEC_STARTER_HELPER_INJECTOR =
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackServerAdvice$ExecStarterAdvice",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackServerAdvice$ExecStarterAction");
|
||||
|
||||
static final TypeDescription.Latent ACTION_TYPE_DESCRIPTION =
|
||||
new TypeDescription.Latent("ratpack.func.Action", Modifier.PUBLIC, null);
|
||||
|
||||
|
@ -53,41 +36,121 @@ public final class RatpackInstrumentation extends Instrumenter.Configurable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("ratpack.server.internal.ServerRegistry");
|
||||
}
|
||||
|
||||
return agentBuilder
|
||||
.type(
|
||||
named("ratpack.server.internal.ServerRegistry"),
|
||||
CLASSLOADER_CONTAINS_RATPACK_1_4_OR_ABOVE)
|
||||
.transform(ROOT_RATPACK_HELPER_INJECTOR)
|
||||
.transform(SERVER_REGISTRY_HELPER_INJECTOR)
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod().and(isStatic()).and(named("buildBaseRegistry")),
|
||||
RatpackServerAdvice.RatpackServerRegistryAdvice.class.getName()))
|
||||
.asDecorator()
|
||||
.type(
|
||||
not(isInterface()).and(hasSuperType(named("ratpack.exec.ExecStarter"))),
|
||||
CLASSLOADER_CONTAINS_RATPACK_1_4_OR_ABOVE)
|
||||
.transform(ROOT_RATPACK_HELPER_INJECTOR)
|
||||
.transform(EXEC_STARTER_HELPER_INJECTOR)
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("register").and(takesArguments(ACTION_TYPE_DESCRIPTION)),
|
||||
RatpackServerAdvice.ExecStarterAdvice.class.getName()))
|
||||
.asDecorator()
|
||||
.type(
|
||||
named("ratpack.exec.Execution")
|
||||
.or(not(isInterface()).and(hasSuperType(named("ratpack.exec.Execution")))),
|
||||
CLASSLOADER_CONTAINS_RATPACK_1_4_OR_ABOVE)
|
||||
.transform(EXEC_STARTER_HELPER_INJECTOR)
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("fork").and(returns(named("ratpack.exec.ExecStarter"))),
|
||||
RatpackServerAdvice.ExecutionAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return CLASSLOADER_CONTAINS_RATPACK_1_4_OR_ABOVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
// core helpers
|
||||
"datadog.opentracing.scopemanager.ContextualScopeManager",
|
||||
"datadog.opentracing.scopemanager.ScopeContext",
|
||||
// service registry helpers
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackRequestExtractAdapter",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackScopeManager",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackServerAdvice$RatpackServerRegistryAdvice",
|
||||
"datadog.trace.instrumentation.ratpack.impl.TracingHandler"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod().and(isStatic()).and(named("buildBaseRegistry")),
|
||||
RatpackServerAdvice.RatpackServerRegistryAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public static class ExecStarterInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public ExecStarterInstrumentation() {
|
||||
super(EXEC_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean defaultEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(hasSuperType(named("ratpack.exec.ExecStarter")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return CLASSLOADER_CONTAINS_RATPACK_1_4_OR_ABOVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
// core helpers
|
||||
"datadog.opentracing.scopemanager.ContextualScopeManager",
|
||||
"datadog.opentracing.scopemanager.ScopeContext",
|
||||
// exec helpers
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackServerAdvice$ExecStarterAdvice",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackServerAdvice$ExecStarterAction"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("register").and(takesArguments(ACTION_TYPE_DESCRIPTION)),
|
||||
RatpackServerAdvice.ExecStarterAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
}
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public static class ExecutionInstrumentation extends Default {
|
||||
|
||||
public ExecutionInstrumentation() {
|
||||
super(EXEC_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean defaultEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("ratpack.exec.Execution")
|
||||
.or(not(isInterface()).and(hasSuperType(named("ratpack.exec.Execution"))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return CLASSLOADER_CONTAINS_RATPACK_1_4_OR_ABOVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
// exec helpers
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackServerAdvice$ExecStarterAdvice",
|
||||
"datadog.trace.instrumentation.ratpack.impl.RatpackServerAdvice$ExecStarterAction"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("fork").and(returns(named("ratpack.exec.ExecStarter"))),
|
||||
RatpackServerAdvice.ExecutionAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -24,15 +22,17 @@ import io.opentracing.propagation.Format;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class FilterChain2Instrumentation extends Instrumenter.Configurable {
|
||||
public final class FilterChain2Instrumentation extends Instrumenter.Default {
|
||||
public static final String FILTER_CHAIN_OPERATION_NAME = "servlet.request";
|
||||
|
||||
public FilterChain2Instrumentation() {
|
||||
|
@ -40,25 +40,33 @@ public final class FilterChain2Instrumentation extends Instrumenter.Configurable
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface()).and(failSafe(hasSuperType(named("javax.servlet.FilterChain")))),
|
||||
not(classLoaderHasClasses("javax.servlet.AsyncEvent", "javax.servlet.AsyncListener"))
|
||||
.and(
|
||||
classLoaderHasClasses(
|
||||
"javax.servlet.ServletContextEvent", "javax.servlet.ServletRequest")))
|
||||
.transform(HttpServlet2Instrumentation.SERVLET2_HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("doFilter")
|
||||
.and(takesArgument(0, named("javax.servlet.ServletRequest")))
|
||||
.and(takesArgument(1, named("javax.servlet.ServletResponse")))
|
||||
.and(isPublic()),
|
||||
FilterChain2Advice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.servlet.FilterChain"))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return not(classLoaderHasClasses("javax.servlet.AsyncEvent", "javax.servlet.AsyncListener"))
|
||||
.and(
|
||||
classLoaderHasClasses(
|
||||
"javax.servlet.ServletContextEvent", "javax.servlet.ServletRequest"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return HttpServlet2Instrumentation.HELPERS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("doFilter")
|
||||
.and(takesArgument(0, named("javax.servlet.ServletRequest")))
|
||||
.and(takesArgument(1, named("javax.servlet.ServletResponse")))
|
||||
.and(isPublic()),
|
||||
FilterChain2Advice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class FilterChain2Advice {
|
||||
|
|
|
@ -11,9 +11,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -25,45 +22,56 @@ import io.opentracing.propagation.Format;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class HttpServlet2Instrumentation extends Instrumenter.Configurable {
|
||||
public final class HttpServlet2Instrumentation extends Instrumenter.Default {
|
||||
public static final String SERVLET_OPERATION_NAME = "servlet.request";
|
||||
static final HelperInjector SERVLET2_HELPER_INJECTOR =
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.servlet2.HttpServletRequestExtractAdapter",
|
||||
"datadog.trace.instrumentation.servlet2.HttpServletRequestExtractAdapter$MultivaluedMapFlatIterator");
|
||||
static final String[] HELPERS =
|
||||
new String[] {
|
||||
"datadog.trace.instrumentation.servlet2.HttpServletRequestExtractAdapter",
|
||||
"datadog.trace.instrumentation.servlet2.HttpServletRequestExtractAdapter$MultivaluedMapFlatIterator"
|
||||
};
|
||||
|
||||
public HttpServlet2Instrumentation() {
|
||||
super("servlet", "servlet-2");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface()).and(failSafe(hasSuperType(named("javax.servlet.http.HttpServlet")))),
|
||||
not(classLoaderHasClasses("javax.servlet.AsyncEvent", "javax.servlet.AsyncListener"))
|
||||
.and(
|
||||
classLoaderHasClasses(
|
||||
"javax.servlet.ServletContextEvent", "javax.servlet.FilterChain")))
|
||||
.transform(SERVLET2_HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create(false) // Can't use the error handler for pre 1.5 classes...
|
||||
.advice(
|
||||
named("service")
|
||||
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest")))
|
||||
.and(takesArgument(1, named("javax.servlet.http.HttpServletResponse")))
|
||||
.and(isProtected()),
|
||||
HttpServlet2Advice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.servlet.http.HttpServlet"))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return not(classLoaderHasClasses("javax.servlet.AsyncEvent", "javax.servlet.AsyncListener"))
|
||||
.and(
|
||||
classLoaderHasClasses(
|
||||
"javax.servlet.ServletContextEvent", "javax.servlet.FilterChain"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return HELPERS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("service")
|
||||
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest")))
|
||||
.and(takesArgument(1, named("javax.servlet.http.HttpServletResponse")))
|
||||
.and(isProtected()),
|
||||
HttpServlet2Advice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class HttpServlet2Advice {
|
||||
|
|
|
@ -11,9 +11,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -26,6 +23,8 @@ import io.opentracing.tag.Tags;
|
|||
import io.opentracing.util.GlobalTracer;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import javax.servlet.AsyncEvent;
|
||||
import javax.servlet.AsyncListener;
|
||||
|
@ -33,11 +32,11 @@ import javax.servlet.ServletRequest;
|
|||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class FilterChain3Instrumentation extends Instrumenter.Configurable {
|
||||
public final class FilterChain3Instrumentation extends Instrumenter.Default {
|
||||
public static final String SERVLET_OPERATION_NAME = "servlet.request";
|
||||
|
||||
public FilterChain3Instrumentation() {
|
||||
|
@ -45,26 +44,34 @@ public final class FilterChain3Instrumentation extends Instrumenter.Configurable
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface()).and(failSafe(hasSuperType(named("javax.servlet.FilterChain")))),
|
||||
classLoaderHasClasses("javax.servlet.AsyncEvent", "javax.servlet.AsyncListener"))
|
||||
.transform(
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.servlet3.HttpServletRequestExtractAdapter",
|
||||
"datadog.trace.instrumentation.servlet3.HttpServletRequestExtractAdapter$MultivaluedMapFlatIterator",
|
||||
FilterChain3Advice.class.getName() + "$TagSettingAsyncListener"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("doFilter")
|
||||
.and(takesArgument(0, named("javax.servlet.ServletRequest")))
|
||||
.and(takesArgument(1, named("javax.servlet.ServletResponse")))
|
||||
.and(isPublic()),
|
||||
FilterChain3Advice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.servlet.FilterChain"))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClasses("javax.servlet.AsyncEvent", "javax.servlet.AsyncListener");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"datadog.trace.instrumentation.servlet3.HttpServletRequestExtractAdapter",
|
||||
"datadog.trace.instrumentation.servlet3.HttpServletRequestExtractAdapter$MultivaluedMapFlatIterator",
|
||||
FilterChain3Advice.class.getName() + "$TagSettingAsyncListener"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("doFilter")
|
||||
.and(takesArgument(0, named("javax.servlet.ServletRequest")))
|
||||
.and(takesArgument(1, named("javax.servlet.ServletResponse")))
|
||||
.and(isPublic()),
|
||||
FilterChain3Advice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class FilterChain3Advice {
|
||||
|
|
|
@ -10,9 +10,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -25,43 +22,50 @@ import io.opentracing.tag.Tags;
|
|||
import io.opentracing.util.GlobalTracer;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import javax.servlet.AsyncEvent;
|
||||
import javax.servlet.AsyncListener;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class HttpServlet3Instrumentation extends Instrumenter.Configurable {
|
||||
public final class HttpServlet3Instrumentation extends Instrumenter.Default {
|
||||
public static final String SERVLET_OPERATION_NAME = "servlet.request";
|
||||
|
||||
public HttpServlet3Instrumentation() {
|
||||
super("servlet", "servlet-3");
|
||||
}
|
||||
//,
|
||||
// classLoaderHasClasses("javax.servlet.AsyncEvent", "javax.servlet.AsyncListener")
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface()).and(failSafe(hasSuperType(named("javax.servlet.http.HttpServlet")))))
|
||||
.transform(
|
||||
new HelperInjector(
|
||||
"datadog.trace.instrumentation.servlet3.HttpServletRequestExtractAdapter",
|
||||
"datadog.trace.instrumentation.servlet3.HttpServletRequestExtractAdapter$MultivaluedMapFlatIterator",
|
||||
HttpServlet3Advice.class.getName() + "$TagSettingAsyncListener"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("service")
|
||||
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest")))
|
||||
.and(takesArgument(1, named("javax.servlet.http.HttpServletResponse")))
|
||||
.and(isProtected()),
|
||||
HttpServlet3Advice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
//
|
||||
// classLoaderHasClasses("javax.servlet.AsyncEvent", "javax.servlet.AsyncListener")
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.servlet.http.HttpServlet"))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"datadog.trace.instrumentation.servlet3.HttpServletRequestExtractAdapter",
|
||||
"datadog.trace.instrumentation.servlet3.HttpServletRequestExtractAdapter$MultivaluedMapFlatIterator",
|
||||
HttpServlet3Advice.class.getName() + "$TagSettingAsyncListener"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("service")
|
||||
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest")))
|
||||
.and(takesArgument(1, named("javax.servlet.http.HttpServletResponse")))
|
||||
.and(isProtected()),
|
||||
HttpServlet3Advice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class HttpServlet3Advice {
|
||||
|
|
|
@ -6,18 +6,19 @@ import static net.bytebuddy.matcher.ElementMatchers.returns;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDTags;
|
||||
import io.opentracing.Scope;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import spark.route.HttpMethod;
|
||||
import spark.routematch.RouteMatch;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class RoutesInstrumentation extends Instrumenter.Configurable {
|
||||
public class RoutesInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public RoutesInstrumentation() {
|
||||
super("sparkjava", "sparkjava-2.4");
|
||||
|
@ -29,18 +30,20 @@ public class RoutesInstrumentation extends Instrumenter.Configurable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(named("spark.route.Routes"))
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
named("find")
|
||||
.and(takesArgument(0, named("spark.route.HttpMethod")))
|
||||
.and(returns(named("spark.routematch.RouteMatch")))
|
||||
.and(isPublic()),
|
||||
RoutesAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("spark.route.Routes");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("find")
|
||||
.and(takesArgument(0, named("spark.route.HttpMethod")))
|
||||
.and(returns(named("spark.routematch.RouteMatch")))
|
||||
.and(isPublic()),
|
||||
RoutesAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class RoutesAdvice {
|
||||
|
|
|
@ -14,8 +14,6 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.DDSpanTypes;
|
||||
import datadog.trace.api.DDTags;
|
||||
|
@ -24,48 +22,67 @@ import io.opentracing.Span;
|
|||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class SpringWebInstrumentation extends Instrumenter.Configurable {
|
||||
public final class SpringWebInstrumentation extends Instrumenter.Default {
|
||||
|
||||
public SpringWebInstrumentation() {
|
||||
super("spring-web");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
not(isInterface())
|
||||
.and(
|
||||
failSafe(
|
||||
hasSuperType(named("org.springframework.web.servlet.HandlerAdapter")))),
|
||||
classLoaderHasClassWithField(
|
||||
"org.springframework.web.servlet.HandlerMapping",
|
||||
"BEST_MATCHING_PATTERN_ATTRIBUTE"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(nameStartsWith("handle"))
|
||||
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest"))),
|
||||
SpringWebNamingAdvice.class.getName()))
|
||||
.type(not(isInterface()).and(named("org.springframework.web.servlet.DispatcherServlet")))
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(isProtected())
|
||||
.and(nameStartsWith("processHandlerException"))
|
||||
.and(takesArgument(3, Exception.class)),
|
||||
SpringWebErrorHandlerAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface())
|
||||
.and(failSafe(hasSuperType(named("org.springframework.web.servlet.HandlerAdapter"))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
return classLoaderHasClassWithField(
|
||||
"org.springframework.web.servlet.HandlerMapping", "BEST_MATCHING_PATTERN_ATTRIBUTE");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(nameStartsWith("handle"))
|
||||
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest"))),
|
||||
SpringWebNamingAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public static class DispatcherServletInstrumentation extends Default {
|
||||
|
||||
public DispatcherServletInstrumentation() {
|
||||
super("spring-web");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(named("org.springframework.web.servlet.DispatcherServlet"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isProtected())
|
||||
.and(nameStartsWith("processHandlerException"))
|
||||
.and(takesArgument(3, Exception.class)),
|
||||
SpringWebErrorHandlerAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpringWebNamingAdvice {
|
||||
|
|
|
@ -4,82 +4,80 @@ import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClass
|
|||
import static net.bytebuddy.matcher.ElementMatchers.*;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.HelperInjector;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.lang.reflect.Method;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import net.spy.memcached.MemcachedClient;
|
||||
import net.spy.memcached.internal.BulkFuture;
|
||||
import net.spy.memcached.internal.GetFuture;
|
||||
import net.spy.memcached.internal.OperationFuture;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class MemcachedClientInstrumentation extends Instrumenter.Configurable {
|
||||
public final class MemcachedClientInstrumentation extends Instrumenter.Default {
|
||||
|
||||
private static final String MEMCACHED_PACKAGE = "net.spy.memcached";
|
||||
private static final String HELPERS_PACKAGE =
|
||||
MemcachedClientInstrumentation.class.getPackage().getName();
|
||||
|
||||
public static final HelperInjector HELPER_INJECTOR =
|
||||
new HelperInjector(
|
||||
HELPERS_PACKAGE + ".CompletionListener",
|
||||
HELPERS_PACKAGE + ".GetCompletionListener",
|
||||
HELPERS_PACKAGE + ".OperationCompletionListener",
|
||||
HELPERS_PACKAGE + ".BulkGetCompletionListener");
|
||||
public static final HelperInjector HELPER_INJECTOR = new HelperInjector();
|
||||
|
||||
public MemcachedClientInstrumentation() {
|
||||
super("spymemcached");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(
|
||||
named(MEMCACHED_PACKAGE + ".MemcachedClient"),
|
||||
// Target 2.12 that has this method
|
||||
classLoaderHasClassWithMethod(
|
||||
MEMCACHED_PACKAGE + ".ConnectionFactoryBuilder",
|
||||
"setListenerExecutorService",
|
||||
"java.util.concurrent.ExecutorService"))
|
||||
.transform(HELPER_INJECTOR)
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(returns(named(MEMCACHED_PACKAGE + ".internal.OperationFuture")))
|
||||
/*
|
||||
Flush seems to have a bug when listeners may not be always called.
|
||||
Also tracing flush is probably of a very limited value.
|
||||
*/
|
||||
.and(not(named("flush"))),
|
||||
AsyncOperationAdvice.class.getName()))
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(returns(named(MEMCACHED_PACKAGE + ".internal.GetFuture"))),
|
||||
AsyncGetAdvice.class.getName()))
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(returns(named(MEMCACHED_PACKAGE + ".internal.BulkFuture"))),
|
||||
AsyncBulkAdvice.class.getName()))
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(
|
||||
isMethod().and(isPublic()).and(named("incr").or(named("decr"))),
|
||||
SyncOperationAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named(MEMCACHED_PACKAGE + ".MemcachedClient");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super ClassLoader> classLoaderMatcher() {
|
||||
// Target 2.12 that has this method
|
||||
return classLoaderHasClassWithMethod(
|
||||
MEMCACHED_PACKAGE + ".ConnectionFactoryBuilder",
|
||||
"setListenerExecutorService",
|
||||
"java.util.concurrent.ExecutorService");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
HELPERS_PACKAGE + ".CompletionListener",
|
||||
HELPERS_PACKAGE + ".GetCompletionListener",
|
||||
HELPERS_PACKAGE + ".OperationCompletionListener",
|
||||
HELPERS_PACKAGE + ".BulkGetCompletionListener"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
.and(returns(named(MEMCACHED_PACKAGE + ".internal.OperationFuture")))
|
||||
/*
|
||||
Flush seems to have a bug when listeners may not be always called.
|
||||
Also tracing flush is probably of a very limited value.
|
||||
*/
|
||||
.and(not(named("flush"))),
|
||||
AsyncOperationAdvice.class.getName());
|
||||
transformers.put(
|
||||
isMethod().and(isPublic()).and(returns(named(MEMCACHED_PACKAGE + ".internal.GetFuture"))),
|
||||
AsyncGetAdvice.class.getName());
|
||||
transformers.put(
|
||||
isMethod().and(isPublic()).and(returns(named(MEMCACHED_PACKAGE + ".internal.BulkFuture"))),
|
||||
AsyncBulkAdvice.class.getName());
|
||||
transformers.put(
|
||||
isMethod().and(isPublic()).and(named("incr").or(named("decr"))),
|
||||
SyncOperationAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,7 +2,6 @@ package datadog.trace.instrumentation.trace_annotation;
|
|||
|
||||
import static datadog.trace.instrumentation.trace_annotation.TraceConfigInstrumentation.PACKAGE_CLASS_NAME_REGEX;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.declaresMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.failSafe;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.is;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith;
|
||||
|
@ -10,21 +9,20 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.Sets;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.api.Trace;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.description.NamedElement;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@Slf4j
|
||||
@AutoService(Instrumenter.class)
|
||||
public final class TraceAnnotationsInstrumentation extends Instrumenter.Configurable {
|
||||
public final class TraceAnnotationsInstrumentation extends Instrumenter.Default {
|
||||
private static final String CONFIG_NAME = "dd.trace.annotations";
|
||||
|
||||
static final String CONFIG_FORMAT =
|
||||
|
@ -44,6 +42,7 @@ public final class TraceAnnotationsInstrumentation extends Instrumenter.Configur
|
|||
};
|
||||
|
||||
private final Set<String> additionalTraceAnnotations;
|
||||
private final ElementMatcher.Junction<NamedElement> methodTraceMatcher;
|
||||
|
||||
public TraceAnnotationsInstrumentation() {
|
||||
super("trace", "trace-annotation");
|
||||
|
@ -69,21 +68,24 @@ public final class TraceAnnotationsInstrumentation extends Instrumenter.Configur
|
|||
}
|
||||
additionalTraceAnnotations = Collections.unmodifiableSet(annotations);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
ElementMatcher.Junction<NamedElement> methodTraceMatcher =
|
||||
is(new TypeDescription.ForLoadedType(Trace.class));
|
||||
for (final String annotationName : additionalTraceAnnotations) {
|
||||
methodTraceMatcher = methodTraceMatcher.or(named(annotationName));
|
||||
}
|
||||
return agentBuilder
|
||||
.type(failSafe(hasSuperType(declaresMethod(isAnnotatedWith(methodTraceMatcher)))))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(
|
||||
DDAdvice.create()
|
||||
.advice(isAnnotatedWith(methodTraceMatcher), TraceAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
this.methodTraceMatcher = methodTraceMatcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return hasSuperType(declaresMethod(isAnnotatedWith(methodTraceMatcher)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(isAnnotatedWith(methodTraceMatcher), TraceAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,19 +6,20 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||
import com.google.auto.service.AutoService;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@Slf4j
|
||||
@AutoService(Instrumenter.class)
|
||||
public class TraceConfigInstrumentation extends Instrumenter.Configurable {
|
||||
public class TraceConfigInstrumentation extends Instrumenter.Default {
|
||||
private static final String CONFIG_NAME = "dd.trace.methods";
|
||||
|
||||
static final String PACKAGE_CLASS_NAME_REGEX = "[\\w.\\$]+";
|
||||
|
@ -78,28 +79,59 @@ public class TraceConfigInstrumentation extends Instrumenter.Configurable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
public AgentBuilder instrument(AgentBuilder agentBuilder) {
|
||||
if (classMethodsToTrace.isEmpty()) {
|
||||
return agentBuilder;
|
||||
}
|
||||
AgentBuilder builder = agentBuilder;
|
||||
|
||||
for (final Map.Entry<String, Set<String>> entry : classMethodsToTrace.entrySet()) {
|
||||
TracerClassInstrumentation tracerConfigClass =
|
||||
new TracerClassInstrumentation(entry.getKey(), entry.getValue());
|
||||
agentBuilder = tracerConfigClass.instrument(agentBuilder);
|
||||
}
|
||||
return agentBuilder;
|
||||
}
|
||||
|
||||
// Not Using AutoService to hook up this instrumentation
|
||||
public static class TracerClassInstrumentation extends Default {
|
||||
private final String className;
|
||||
private final Set<String> methodNames;
|
||||
|
||||
public TracerClassInstrumentation(String className, Set<String> methodNames) {
|
||||
super("trace", "trace-config");
|
||||
this.className = className;
|
||||
this.methodNames = methodNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
||||
return hasSuperType(named(className));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
ElementMatcher.Junction<MethodDescription> methodMatchers = null;
|
||||
for (final String methodName : entry.getValue()) {
|
||||
for (final String methodName : methodNames) {
|
||||
if (methodMatchers == null) {
|
||||
methodMatchers = named(methodName);
|
||||
} else {
|
||||
methodMatchers = methodMatchers.or(named(methodName));
|
||||
}
|
||||
}
|
||||
builder =
|
||||
builder
|
||||
.type(hasSuperType(named(entry.getKey())))
|
||||
.transform(DDAdvice.create().advice(methodMatchers, TraceAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(methodMatchers, TraceAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
||||
throw new RuntimeException("TracerConfigInstrumentation must not use TypeMatcher");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
throw new RuntimeException("TracerConfigInstrumentation must not use transformers.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,28 @@
|
|||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.DDAdvice;
|
||||
import datadog.trace.agent.tooling.DDTransformers;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
@AutoService(Instrumenter.class)
|
||||
public class IBMResourceLevelInstrumentation extends Instrumenter.Configurable {
|
||||
public class IBMResourceLevelInstrumentation extends Instrumenter.Default {
|
||||
public IBMResourceLevelInstrumentation() {
|
||||
super(IBMResourceLevelInstrumentation.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AgentBuilder apply(final AgentBuilder agentBuilder) {
|
||||
return agentBuilder
|
||||
.type(named("com.ibm.as400.resource.ResourceLevel"))
|
||||
.transform(DDTransformers.defaultTransformers())
|
||||
.transform(DDAdvice.create().advice(named("toString"), ToStringAdvice.class.getName()))
|
||||
.asDecorator();
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("com.ibm.as400.resource.ResourceLevel");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(named("toString"), ToStringAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class ToStringAdvice {
|
||||
|
|
Loading…
Reference in New Issue