diff --git a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/Instrumenter.java b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/Instrumenter.java
index 7010d067cb..6003586367 100644
--- a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/Instrumenter.java
+++ b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/Instrumenter.java
@@ -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.
+ *
+ *
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 transformers();
+
@Slf4j
- abstract class Configurable implements Instrumenter {
+ abstract class Default implements Instrumenter {
private final Set 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 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 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)));
diff --git a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/NewInstrumenter.java b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/NewInstrumenter.java
deleted file mode 100644
index c1c1f9048c..0000000000
--- a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/NewInstrumenter.java
+++ /dev/null
@@ -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 getHelperClassNames();
-
- Map 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(), )
- .and(safeToInject()) // implementation generated by muzzle
- .transform(DDTransformers.defaultTransformers())
- .transform(new HelperInjector(getHelperClassNames()));
- Map advice = getTransformers();
- for (Entry entry : advice.getEntrySet()) {
- transformer = transformer.transform(DDAdvice.create().advice(entry.getKey(), entry.getValue()));
- }
- return transformer.asDecorator()
- */
- // FIXME
- return null;
- }
-
- @Override
- public Set getHelperClassNames() {
- // FIXME
- return null;
- }
-
- public abstract ElementMatcher super TypeDescription> getTypeMatcher();
-
- public abstract ElementMatcher super ClassLoaderMatcher> getClassLoaderMatcher();
-
- public abstract Map getTransformers();
-
-
- // TODO merge in config logic from previous instrumenter
-
- private final Set 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(".", "_");
- }
- }
-}
diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ConfigurableInstrumenterTest.groovy b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/DefaultInstrumenterTest.groovy
similarity index 74%
rename from dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ConfigurableInstrumenterTest.groovy
rename to dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/DefaultInstrumenterTest.groovy
index bce1ac83e6..962f6ec2b1 100644
--- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ConfigurableInstrumenterTest.groovy
+++ b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/DefaultInstrumenterTest.groovy
@@ -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 transformers() {
+ return Collections.emptyMap()
+ }
}
}
diff --git a/dd-java-agent/instrumentation/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/AkkaHttpServerInstrumentation.java b/dd-java-agent/instrumentation/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/AkkaHttpServerInstrumentation.java
index e9a7e655c9..4509644f5d 100644
--- a/dd-java-agent/instrumentation/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/AkkaHttpServerInstrumentation.java
+++ b/dd-java-agent/instrumentation/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/AkkaHttpServerInstrumentation.java
@@ -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 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 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 {
diff --git a/dd-java-agent/instrumentation/apache-httpclient-4.3/src/main/java/datadog/trace/instrumentation/apachehttpclient/ApacheHttpClientInstrumentation.java b/dd-java-agent/instrumentation/apache-httpclient-4.3/src/main/java/datadog/trace/instrumentation/apachehttpclient/ApacheHttpClientInstrumentation.java
index 6c3ff42d50..1efe58cd48 100644
--- a/dd-java-agent/instrumentation/apache-httpclient-4.3/src/main/java/datadog/trace/instrumentation/apachehttpclient/ApacheHttpClientInstrumentation.java
+++ b/dd-java-agent/instrumentation/apache-httpclient-4.3/src/main/java/datadog/trace/instrumentation/apachehttpclient/ApacheHttpClientInstrumentation.java
@@ -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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ isMethod().and(named("decorateProtocolExec")), ApacheHttpClientAdvice.class.getName());
+ return transformers;
}
public static class ApacheHttpClientAdvice {
diff --git a/dd-java-agent/instrumentation/aws-java-sdk-1.11.0/src/main/java/datadog/trace/instrumentation/aws/v0/AWSClientInstrumentation.java b/dd-java-agent/instrumentation/aws-java-sdk-1.11.0/src/main/java/datadog/trace/instrumentation/aws/v0/AWSClientInstrumentation.java
index 226e9ff246..edb5e433c7 100644
--- a/dd-java-agent/instrumentation/aws-java-sdk-1.11.0/src/main/java/datadog/trace/instrumentation/aws/v0/AWSClientInstrumentation.java
+++ b/dd-java-agent/instrumentation/aws-java-sdk-1.11.0/src/main/java/datadog/trace/instrumentation/aws/v0/AWSClientInstrumentation.java
@@ -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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(isConstructor(), AWSClientAdvice.class.getName());
+ return transformers;
}
public static class AWSClientAdvice {
diff --git a/dd-java-agent/instrumentation/aws-java-sdk-1.11.106/src/main/java/datadog/trace/instrumentation/aws/v106/AWSClientInstrumentation.java b/dd-java-agent/instrumentation/aws-java-sdk-1.11.106/src/main/java/datadog/trace/instrumentation/aws/v106/AWSClientInstrumentation.java
index b5effae293..753e7d591d 100644
--- a/dd-java-agent/instrumentation/aws-java-sdk-1.11.106/src/main/java/datadog/trace/instrumentation/aws/v106/AWSClientInstrumentation.java
+++ b/dd-java-agent/instrumentation/aws-java-sdk-1.11.106/src/main/java/datadog/trace/instrumentation/aws/v106/AWSClientInstrumentation.java
@@ -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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(isConstructor(), AWSClientAdvice.class.getName());
+ return transformers;
}
public static class AWSClientAdvice {
diff --git a/dd-java-agent/instrumentation/classloaders/src/main/java/datadog/trace/instrumentation/classloaders/ClassLoaderInstrumentation.java b/dd-java-agent/instrumentation/classloaders/src/main/java/datadog/trace/instrumentation/classloaders/ClassLoaderInstrumentation.java
index 0e526c2ef4..845bf8e5ae 100644
--- a/dd-java-agent/instrumentation/classloaders/src/main/java/datadog/trace/instrumentation/classloaders/ClassLoaderInstrumentation.java
+++ b/dd-java-agent/instrumentation/classloaders/src/main/java/datadog/trace/instrumentation/classloaders/ClassLoaderInstrumentation.java
@@ -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 transformers() {
+ Map 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);
diff --git a/dd-java-agent/instrumentation/datastax-cassandra-3.2/src/main/java/datadog/trace/instrumentation/datastax/cassandra/CassandraClientInstrumentation.java b/dd-java-agent/instrumentation/datastax-cassandra-3.2/src/main/java/datadog/trace/instrumentation/datastax/cassandra/CassandraClientInstrumentation.java
index 446811b61d..ac24cc4472 100644
--- a/dd-java-agent/instrumentation/datastax-cassandra-3.2/src/main/java/datadog/trace/instrumentation/datastax/cassandra/CassandraClientInstrumentation.java
+++ b/dd-java-agent/instrumentation/datastax-cassandra-3.2/src/main/java/datadog/trace/instrumentation/datastax/cassandra/CassandraClientInstrumentation.java
@@ -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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ isMethod().and(isPrivate()).and(named("newSession")).and(takesArguments(0)),
+ CassandraClientAdvice.class.getName());
+ return transformers;
}
public static class CassandraClientAdvice {
diff --git a/dd-java-agent/instrumentation/elasticsearch-rest-5/src/main/java/datadog/trace/instrumentation/elasticsearch5/Elasticsearch5RestClientInstrumentation.java b/dd-java-agent/instrumentation/elasticsearch-rest-5/src/main/java/datadog/trace/instrumentation/elasticsearch5/Elasticsearch5RestClientInstrumentation.java
index 3c2af1fdde..49e485b338 100644
--- a/dd-java-agent/instrumentation/elasticsearch-rest-5/src/main/java/datadog/trace/instrumentation/elasticsearch5/Elasticsearch5RestClientInstrumentation.java
+++ b/dd-java-agent/instrumentation/elasticsearch-rest-5/src/main/java/datadog/trace/instrumentation/elasticsearch5/Elasticsearch5RestClientInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/elasticsearch-transport-2/src/main/java/datadog/trace/instrumentation/elasticsearch2/Elasticsearch2TransportClientInstrumentation.java b/dd-java-agent/instrumentation/elasticsearch-transport-2/src/main/java/datadog/trace/instrumentation/elasticsearch2/Elasticsearch2TransportClientInstrumentation.java
index 3b8eb12605..080774664a 100644
--- a/dd-java-agent/instrumentation/elasticsearch-transport-2/src/main/java/datadog/trace/instrumentation/elasticsearch2/Elasticsearch2TransportClientInstrumentation.java
+++ b/dd-java-agent/instrumentation/elasticsearch-transport-2/src/main/java/datadog/trace/instrumentation/elasticsearch2/Elasticsearch2TransportClientInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/elasticsearch-transport-5/src/main/java/datadog/trace/instrumentation/elasticsearch5/Elasticsearch5TransportClientInstrumentation.java b/dd-java-agent/instrumentation/elasticsearch-transport-5/src/main/java/datadog/trace/instrumentation/elasticsearch5/Elasticsearch5TransportClientInstrumentation.java
index 5554787e0b..495223eba8 100644
--- a/dd-java-agent/instrumentation/elasticsearch-transport-5/src/main/java/datadog/trace/instrumentation/elasticsearch5/Elasticsearch5TransportClientInstrumentation.java
+++ b/dd-java-agent/instrumentation/elasticsearch-transport-5/src/main/java/datadog/trace/instrumentation/elasticsearch5/Elasticsearch5TransportClientInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/elasticsearch-transport-6/src/main/java/datadog/trace/instrumentation/elasticsearch6/Elasticsearch6TransportClientInstrumentation.java b/dd-java-agent/instrumentation/elasticsearch-transport-6/src/main/java/datadog/trace/instrumentation/elasticsearch6/Elasticsearch6TransportClientInstrumentation.java
index d82515f0b3..b223b7080d 100644
--- a/dd-java-agent/instrumentation/elasticsearch-transport-6/src/main/java/datadog/trace/instrumentation/elasticsearch6/Elasticsearch6TransportClientInstrumentation.java
+++ b/dd-java-agent/instrumentation/elasticsearch-transport-6/src/main/java/datadog/trace/instrumentation/elasticsearch6/Elasticsearch6TransportClientInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/http-url-connection/src/main/java/datadog/trace/instrumentation/http_url_connection/HttpUrlConnectionInstrumentation.java b/dd-java-agent/instrumentation/http-url-connection/src/main/java/datadog/trace/instrumentation/http_url_connection/HttpUrlConnectionInstrumentation.java
index b743b018f6..875b8c09eb 100644
--- a/dd-java-agent/instrumentation/http-url-connection/src/main/java/datadog/trace/instrumentation/http_url_connection/HttpUrlConnectionInstrumentation.java
+++ b/dd-java-agent/instrumentation/http-url-connection/src/main/java/datadog/trace/instrumentation/http_url_connection/HttpUrlConnectionInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/http-url-connection/src/main/java/datadog/trace/instrumentation/http_url_connection/UrlInstrumentation.java b/dd-java-agent/instrumentation/http-url-connection/src/main/java/datadog/trace/instrumentation/http_url_connection/UrlInstrumentation.java
index 8ddada8d54..f71e3d5e87 100644
--- a/dd-java-agent/instrumentation/http-url-connection/src/main/java/datadog/trace/instrumentation/http_url_connection/UrlInstrumentation.java
+++ b/dd-java-agent/instrumentation/http-url-connection/src/main/java/datadog/trace/instrumentation/http_url_connection/UrlInstrumentation.java
@@ -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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ isMethod().and(isPublic()).and(named("openConnection")),
+ ConnectionErrorAdvice.class.getName());
+ return transformers;
}
public static class ConnectionErrorAdvice {
diff --git a/dd-java-agent/instrumentation/hystrix-1.4/src/main/java/datadog/trace/instrumentation/hystrix/HystrixCommandInstrumentation.java b/dd-java-agent/instrumentation/hystrix-1.4/src/main/java/datadog/trace/instrumentation/hystrix/HystrixCommandInstrumentation.java
index 690d025965..fa56b6261b 100644
--- a/dd-java-agent/instrumentation/hystrix-1.4/src/main/java/datadog/trace/instrumentation/hystrix/HystrixCommandInstrumentation.java
+++ b/dd-java-agent/instrumentation/hystrix-1.4/src/main/java/datadog/trace/instrumentation/hystrix/HystrixCommandInstrumentation.java
@@ -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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ isMethod().and(named("run").or(named("getFallback"))), TraceAdvice.class.getName());
+ return transformers;
}
public static class TraceAdvice {
diff --git a/dd-java-agent/instrumentation/hystrix-1.4/src/main/java/datadog/trace/instrumentation/hystrix/HystrixThreadPoolInstrumentation.java b/dd-java-agent/instrumentation/hystrix-1.4/src/main/java/datadog/trace/instrumentation/hystrix/HystrixThreadPoolInstrumentation.java
index b2d6c3ea94..f4fd053cb6 100644
--- a/dd-java-agent/instrumentation/hystrix-1.4/src/main/java/datadog/trace/instrumentation/hystrix/HystrixThreadPoolInstrumentation.java
+++ b/dd-java-agent/instrumentation/hystrix-1.4/src/main/java/datadog/trace/instrumentation/hystrix/HystrixThreadPoolInstrumentation.java
@@ -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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ isMethod().and(named("schedule")).and(takesArguments(1)),
+ EnableAsyncAdvice.class.getName());
+ return transformers;
}
public static class EnableAsyncAdvice {
diff --git a/dd-java-agent/instrumentation/java-concurrent/src/main/java/datadog/trace/instrumentation/java/concurrent/ExecutorInstrumentation.java b/dd-java-agent/instrumentation/java-concurrent/src/main/java/datadog/trace/instrumentation/java/concurrent/ExecutorInstrumentation.java
index 40ecf1a329..8aa2535dd6 100644
--- a/dd-java-agent/instrumentation/java-concurrent/src/main/java/datadog/trace/instrumentation/java/concurrent/ExecutorInstrumentation.java
+++ b/dd-java-agent/instrumentation/java-concurrent/src/main/java/datadog/trace/instrumentation/java/concurrent/ExecutorInstrumentation.java
@@ -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() {
@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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/java-concurrent/src/main/java/datadog/trace/instrumentation/java/concurrent/FutureInstrumentation.java b/dd-java-agent/instrumentation/java-concurrent/src/main/java/datadog/trace/instrumentation/java/concurrent/FutureInstrumentation.java
index eb21c2af36..0471b38d3c 100644
--- a/dd-java-agent/instrumentation/java-concurrent/src/main/java/datadog/trace/instrumentation/java/concurrent/FutureInstrumentation.java
+++ b/dd-java-agent/instrumentation/java-concurrent/src/main/java/datadog/trace/instrumentation/java/concurrent/FutureInstrumentation.java
@@ -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() {
@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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ named("cancel").and(returns(boolean.class)), CanceledFutureAdvice.class.getName());
+ return transformers;
}
public static class CanceledFutureAdvice {
diff --git a/dd-java-agent/instrumentation/jax-rs-annotations/src/main/java/datadog/trace/instrumentation/jaxrs/JaxRsAnnotationsInstrumentation.java b/dd-java-agent/instrumentation/jax-rs-annotations/src/main/java/datadog/trace/instrumentation/jaxrs/JaxRsAnnotationsInstrumentation.java
index 3b9f241c2d..9598fb539b 100644
--- a/dd-java-agent/instrumentation/jax-rs-annotations/src/main/java/datadog/trace/instrumentation/jaxrs/JaxRsAnnotationsInstrumentation.java
+++ b/dd-java-agent/instrumentation/jax-rs-annotations/src/main/java/datadog/trace/instrumentation/jaxrs/JaxRsAnnotationsInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/jax-rs-client/src/main/java/datadog/trace/instrumentation/jaxrs/JaxRsClientInstrumentation.java b/dd-java-agent/instrumentation/jax-rs-client/src/main/java/datadog/trace/instrumentation/jaxrs/JaxRsClientInstrumentation.java
index 4e48c7fef0..9dc0193a32 100644
--- a/dd-java-agent/instrumentation/jax-rs-client/src/main/java/datadog/trace/instrumentation/jaxrs/JaxRsClientInstrumentation.java
+++ b/dd-java-agent/instrumentation/jax-rs-client/src/main/java/datadog/trace/instrumentation/jaxrs/JaxRsClientInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/jboss-classloading/src/main/java/datadog/trace/instrumentation/jboss/JBossClassloadingInstrumentation.java b/dd-java-agent/instrumentation/jboss-classloading/src/main/java/datadog/trace/instrumentation/jboss/JBossClassloadingInstrumentation.java
index 01a23f3ccb..6190dfa646 100644
--- a/dd-java-agent/instrumentation/jboss-classloading/src/main/java/datadog/trace/instrumentation/jboss/JBossClassloadingInstrumentation.java
+++ b/dd-java-agent/instrumentation/jboss-classloading/src/main/java/datadog/trace/instrumentation/jboss/JBossClassloadingInstrumentation.java
@@ -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 transformers() {
+ return Collections.emptyMap();
}
}
diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/ConnectionInstrumentation.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/ConnectionInstrumentation.java
index f530387627..e5c21a4c70 100644
--- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/ConnectionInstrumentation.java
+++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/ConnectionInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/PreparedStatementInstrumentation.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/PreparedStatementInstrumentation.java
index 32fd3501ad..33f0a3c456 100644
--- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/PreparedStatementInstrumentation.java
+++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/PreparedStatementInstrumentation.java
@@ -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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ nameStartsWith("execute").and(takesArguments(0)).and(isPublic()),
+ PreparedStatementAdvice.class.getName());
+ return transformers;
}
public static class PreparedStatementAdvice {
diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java
index 61790f4d83..bf40bfdd11 100644
--- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java
+++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java
@@ -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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ nameStartsWith("execute").and(takesArgument(0, String.class)).and(isPublic()),
+ StatementAdvice.class.getName());
+ return transformers;
}
public static class StatementAdvice {
diff --git a/dd-java-agent/instrumentation/jedis-1.4/src/main/java/datadog/trace/instrumentation/jedis/JedisInstrumentation.java b/dd-java-agent/instrumentation/jedis-1.4/src/main/java/datadog/trace/instrumentation/jedis/JedisInstrumentation.java
index ebf704479c..7dca92ec21 100644
--- a/dd-java-agent/instrumentation/jedis-1.4/src/main/java/datadog/trace/instrumentation/jedis/JedisInstrumentation.java
+++ b/dd-java-agent/instrumentation/jedis-1.4/src/main/java/datadog/trace/instrumentation/jedis/JedisInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/jetty-8/src/main/java/datadog/trace/instrumentation/jetty8/HandlerInstrumentation.java b/dd-java-agent/instrumentation/jetty-8/src/main/java/datadog/trace/instrumentation/jetty8/HandlerInstrumentation.java
index 611d106e2e..471bf6dd7e 100644
--- a/dd-java-agent/instrumentation/jetty-8/src/main/java/datadog/trace/instrumentation/jetty8/HandlerInstrumentation.java
+++ b/dd-java-agent/instrumentation/jetty-8/src/main/java/datadog/trace/instrumentation/jetty8/HandlerInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/jms-1/src/main/java/datadog/trace/instrumentation/jms1/JMS1MessageConsumerInstrumentation.java b/dd-java-agent/instrumentation/jms-1/src/main/java/datadog/trace/instrumentation/jms1/JMS1MessageConsumerInstrumentation.java
index bcac11693d..1b6d6ce48c 100644
--- a/dd-java-agent/instrumentation/jms-1/src/main/java/datadog/trace/instrumentation/jms1/JMS1MessageConsumerInstrumentation.java
+++ b/dd-java-agent/instrumentation/jms-1/src/main/java/datadog/trace/instrumentation/jms1/JMS1MessageConsumerInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/jms-1/src/main/java/datadog/trace/instrumentation/jms1/JMS1MessageListenerInstrumentation.java b/dd-java-agent/instrumentation/jms-1/src/main/java/datadog/trace/instrumentation/jms1/JMS1MessageListenerInstrumentation.java
index 207b043ba5..c8837ed721 100644
--- a/dd-java-agent/instrumentation/jms-1/src/main/java/datadog/trace/instrumentation/jms1/JMS1MessageListenerInstrumentation.java
+++ b/dd-java-agent/instrumentation/jms-1/src/main/java/datadog/trace/instrumentation/jms1/JMS1MessageListenerInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/jms-1/src/main/java/datadog/trace/instrumentation/jms1/JMS1MessageProducerInstrumentation.java b/dd-java-agent/instrumentation/jms-1/src/main/java/datadog/trace/instrumentation/jms1/JMS1MessageProducerInstrumentation.java
index 062e61cdda..9cb37ff2b5 100644
--- a/dd-java-agent/instrumentation/jms-1/src/main/java/datadog/trace/instrumentation/jms1/JMS1MessageProducerInstrumentation.java
+++ b/dd-java-agent/instrumentation/jms-1/src/main/java/datadog/trace/instrumentation/jms1/JMS1MessageProducerInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/jms-2/src/main/java/datadog/trace/instrumentation/jms2/JMS2MessageConsumerInstrumentation.java b/dd-java-agent/instrumentation/jms-2/src/main/java/datadog/trace/instrumentation/jms2/JMS2MessageConsumerInstrumentation.java
index d962c65adf..73e9d86571 100644
--- a/dd-java-agent/instrumentation/jms-2/src/main/java/datadog/trace/instrumentation/jms2/JMS2MessageConsumerInstrumentation.java
+++ b/dd-java-agent/instrumentation/jms-2/src/main/java/datadog/trace/instrumentation/jms2/JMS2MessageConsumerInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/jms-2/src/main/java/datadog/trace/instrumentation/jms2/JMS2MessageListenerInstrumentation.java b/dd-java-agent/instrumentation/jms-2/src/main/java/datadog/trace/instrumentation/jms2/JMS2MessageListenerInstrumentation.java
index d77721e18b..5d457f25a4 100644
--- a/dd-java-agent/instrumentation/jms-2/src/main/java/datadog/trace/instrumentation/jms2/JMS2MessageListenerInstrumentation.java
+++ b/dd-java-agent/instrumentation/jms-2/src/main/java/datadog/trace/instrumentation/jms2/JMS2MessageListenerInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/jms-2/src/main/java/datadog/trace/instrumentation/jms2/JMS2MessageProducerInstrumentation.java b/dd-java-agent/instrumentation/jms-2/src/main/java/datadog/trace/instrumentation/jms2/JMS2MessageProducerInstrumentation.java
index e607e43c6b..f8d41483e4 100644
--- a/dd-java-agent/instrumentation/jms-2/src/main/java/datadog/trace/instrumentation/jms2/JMS2MessageProducerInstrumentation.java
+++ b/dd-java-agent/instrumentation/jms-2/src/main/java/datadog/trace/instrumentation/jms2/JMS2MessageProducerInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/jsp-2.3/src/main/java/datadog/trace/instrumentation/jsp/JSPInstrumentation.java b/dd-java-agent/instrumentation/jsp-2.3/src/main/java/datadog/trace/instrumentation/jsp/JSPInstrumentation.java
index 6094bcc21e..4405b4f721 100644
--- a/dd-java-agent/instrumentation/jsp-2.3/src/main/java/datadog/trace/instrumentation/jsp/JSPInstrumentation.java
+++ b/dd-java-agent/instrumentation/jsp-2.3/src/main/java/datadog/trace/instrumentation/jsp/JSPInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/jsp-2.3/src/main/java/datadog/trace/instrumentation/jsp/JasperJSPCompilationContextInstrumentation.java b/dd-java-agent/instrumentation/jsp-2.3/src/main/java/datadog/trace/instrumentation/jsp/JasperJSPCompilationContextInstrumentation.java
index 6c94c61ca2..e84af1ced5 100644
--- a/dd-java-agent/instrumentation/jsp-2.3/src/main/java/datadog/trace/instrumentation/jsp/JasperJSPCompilationContextInstrumentation.java
+++ b/dd-java-agent/instrumentation/jsp-2.3/src/main/java/datadog/trace/instrumentation/jsp/JasperJSPCompilationContextInstrumentation.java
@@ -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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ named("compile").and(takesArguments(0)).and(isPublic()),
+ JasperJspCompilationContext.class.getName());
+ return transformers;
}
public static class JasperJspCompilationContext {
diff --git a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaConsumerInstrumentation.java b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaConsumerInstrumentation.java
index d1967c8ba9..0186ec8fb8 100644
--- a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaConsumerInstrumentation.java
+++ b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaConsumerInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaProducerInstrumentation.java b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaProducerInstrumentation.java
index 3d7bc68c1e..b31668ac69 100644
--- a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaProducerInstrumentation.java
+++ b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaProducerInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/kafka-streams-0.11/kafka-streams-0.11.gradle b/dd-java-agent/instrumentation/kafka-streams-0.11/kafka-streams-0.11.gradle
index 103ce39df2..7f6ce7ac44 100644
--- a/dd-java-agent/instrumentation/kafka-streams-0.11/kafka-streams-0.11.gradle
+++ b/dd-java-agent/instrumentation/kafka-streams-0.11/kafka-streams-0.11.gradle
@@ -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
]
}
diff --git a/dd-java-agent/instrumentation/kafka-streams-0.11/src/main/java/datadog/trace/instrumentation/kafka_streams/KafkaStreamsProcessorInstrumentation.java b/dd-java-agent/instrumentation/kafka-streams-0.11/src/main/java/datadog/trace/instrumentation/kafka_streams/KafkaStreamsProcessorInstrumentation.java
index e9f8293bc8..85c42b548d 100644
--- a/dd-java-agent/instrumentation/kafka-streams-0.11/src/main/java/datadog/trace/instrumentation/kafka_streams/KafkaStreamsProcessorInstrumentation.java
+++ b/dd-java-agent/instrumentation/kafka-streams-0.11/src/main/java/datadog/trace/instrumentation/kafka_streams/KafkaStreamsProcessorInstrumentation.java
@@ -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 transformers() {
+ Map 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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ isMethod().and(isPublic()).and(named("process")).and(takesArguments(0)),
+ StopSpanAdvice.class.getName());
+ return transformers;
}
public static class StopSpanAdvice {
diff --git a/dd-java-agent/instrumentation/kafka-streams-0.11/src/main/java/datadog/trace/instrumentation/kafka_streams/KafkaStreamsSourceNodeRecordDeserializerInstrumentation.java b/dd-java-agent/instrumentation/kafka-streams-0.11/src/main/java/datadog/trace/instrumentation/kafka_streams/KafkaStreamsSourceNodeRecordDeserializerInstrumentation.java
index 20449ceb7c..62cf2f1b5b 100644
--- a/dd-java-agent/instrumentation/kafka-streams-0.11/src/main/java/datadog/trace/instrumentation/kafka_streams/KafkaStreamsSourceNodeRecordDeserializerInstrumentation.java
+++ b/dd-java-agent/instrumentation/kafka-streams-0.11/src/main/java/datadog/trace/instrumentation/kafka_streams/KafkaStreamsSourceNodeRecordDeserializerInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/LettuceAsyncCommandsInstrumentation.java b/dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/LettuceAsyncCommandsInstrumentation.java
index beda0d95fd..32fbce4a1d 100644
--- a/dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/LettuceAsyncCommandsInstrumentation.java
+++ b/dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/LettuceAsyncCommandsInstrumentation.java
@@ -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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ isMethod()
+ .and(named("dispatch"))
+ .and(takesArgument(0, named("io.lettuce.core.protocol.RedisCommand"))),
+ LettuceAsyncCommandsAdvice.class.getName());
+ return transformers;
}
}
diff --git a/dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/LettuceClientInstrumentation.java b/dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/LettuceClientInstrumentation.java
index a21e773e07..31229ec255 100644
--- a/dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/LettuceClientInstrumentation.java
+++ b/dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/LettuceClientInstrumentation.java
@@ -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 transformers() {
+ Map 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;
}
}
diff --git a/dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/LettuceReactiveCommandsInstrumentation.java b/dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/LettuceReactiveCommandsInstrumentation.java
index 7a42f4ec81..700b031450 100644
--- a/dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/LettuceReactiveCommandsInstrumentation.java
+++ b/dd-java-agent/instrumentation/lettuce-5/src/main/java/datadog/trace/instrumentation/lettuce/LettuceReactiveCommandsInstrumentation.java
@@ -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 transformers() {
+ Map 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;
}
}
diff --git a/dd-java-agent/instrumentation/mongo-3.1/src/main/java/datadog/trace/instrumentation/mongo/MongoClientInstrumentation.java b/dd-java-agent/instrumentation/mongo-3.1/src/main/java/datadog/trace/instrumentation/mongo/MongoClientInstrumentation.java
index 9568b7aaa7..ab8777edd1 100644
--- a/dd-java-agent/instrumentation/mongo-3.1/src/main/java/datadog/trace/instrumentation/mongo/MongoClientInstrumentation.java
+++ b/dd-java-agent/instrumentation/mongo-3.1/src/main/java/datadog/trace/instrumentation/mongo/MongoClientInstrumentation.java
@@ -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.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.emptyList())))
+ .and(isPublic())));
+ }
+
+ @Override
+ public String[] helperClassNames() {
+ return HELPERS;
+ }
+
+ @Override
+ public Map transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ isMethod().and(isPublic()).and(named("build")).and(takesArguments(0)),
+ MongoClientAdvice.class.getName());
+ return transformers;
}
public static class MongoClientAdvice {
diff --git a/dd-java-agent/instrumentation/mongo-async-3.3/src/main/java/datadog/trace/instrumentation/mongo/MongoAsyncClientInstrumentation.java b/dd-java-agent/instrumentation/mongo-async-3.3/src/main/java/datadog/trace/instrumentation/mongo/MongoAsyncClientInstrumentation.java
index e9b6b247e0..0d75bea8c2 100644
--- a/dd-java-agent/instrumentation/mongo-async-3.3/src/main/java/datadog/trace/instrumentation/mongo/MongoAsyncClientInstrumentation.java
+++ b/dd-java-agent/instrumentation/mongo-async-3.3/src/main/java/datadog/trace/instrumentation/mongo/MongoAsyncClientInstrumentation.java
@@ -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.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.emptyList())))
+ .and(isPublic())));
+ }
+
+ @Override
+ public String[] helperClassNames() {
+ return MongoClientInstrumentation.HELPERS;
+ }
+
+ @Override
+ public Map transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ isMethod().and(isPublic()).and(named("build")).and(takesArguments(0)),
+ MongoAsyncClientAdvice.class.getName());
+ return transformers;
}
public static class MongoAsyncClientAdvice {
diff --git a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/NettyChannelPipelineInstrumentation.java b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/NettyChannelPipelineInstrumentation.java
index 07886b6212..0023a432d5 100644
--- a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/NettyChannelPipelineInstrumentation.java
+++ b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/NettyChannelPipelineInstrumentation.java
@@ -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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ isMethod()
+ .and(nameStartsWith("add"))
+ .and(takesArgument(2, named("io.netty.channel.ChannelHandler"))),
+ ChannelPipelineAddAdvice.class.getName());
+ return transformers;
}
/**
diff --git a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyChannelPipelineInstrumentation.java b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyChannelPipelineInstrumentation.java
index bb3dfdacb6..311f10b60a 100644
--- a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyChannelPipelineInstrumentation.java
+++ b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyChannelPipelineInstrumentation.java
@@ -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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ isMethod()
+ .and(nameStartsWith("add"))
+ .and(takesArgument(2, named("io.netty.channel.ChannelHandler"))),
+ ChannelPipelineAddAdvice.class.getName());
+ return transformers;
}
/**
diff --git a/dd-java-agent/instrumentation/okhttp-3/src/main/java/datadog/trace/instrumentation/okhttp3/OkHttp3Instrumentation.java b/dd-java-agent/instrumentation/okhttp-3/src/main/java/datadog/trace/instrumentation/okhttp3/OkHttp3Instrumentation.java
index 70f70990ff..229203f44e 100644
--- a/dd-java-agent/instrumentation/okhttp-3/src/main/java/datadog/trace/instrumentation/okhttp3/OkHttp3Instrumentation.java
+++ b/dd-java-agent/instrumentation/okhttp-3/src/main/java/datadog/trace/instrumentation/okhttp3/OkHttp3Instrumentation.java
@@ -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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ isConstructor().and(takesArgument(0, named("okhttp3.OkHttpClient$Builder"))),
+ OkHttp3Advice.class.getName());
+ return transformers;
}
public static class OkHttp3Advice {
diff --git a/dd-java-agent/instrumentation/osgi-classloading/src/main/java/datadog/trace/instrumentation/osgi/OSGIClassloadingInstrumentation.java b/dd-java-agent/instrumentation/osgi-classloading/src/main/java/datadog/trace/instrumentation/osgi/OSGIClassloadingInstrumentation.java
index 702a4dc304..af2339cd19 100644
--- a/dd-java-agent/instrumentation/osgi-classloading/src/main/java/datadog/trace/instrumentation/osgi/OSGIClassloadingInstrumentation.java
+++ b/dd-java-agent/instrumentation/osgi-classloading/src/main/java/datadog/trace/instrumentation/osgi/OSGIClassloadingInstrumentation.java
@@ -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 transformers() {
+ return Collections.emptyMap();
}
}
diff --git a/dd-java-agent/instrumentation/play-2.4/src/main/java/datadog/trace/instrumentation/play/PlayInstrumentation.java b/dd-java-agent/instrumentation/play-2.4/src/main/java/datadog/trace/instrumentation/play/PlayInstrumentation.java
index 04b858bfe3..e63a89063f 100644
--- a/dd-java-agent/instrumentation/play-2.4/src/main/java/datadog/trace/instrumentation/play/PlayInstrumentation.java
+++ b/dd-java-agent/instrumentation/play-2.4/src/main/java/datadog/trace/instrumentation/play/PlayInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/ratpack-1.4/src/main/java/datadog/trace/instrumentation/ratpack/RatpackHttpClientInstrumentation.java b/dd-java-agent/instrumentation/ratpack-1.4/src/main/java/datadog/trace/instrumentation/ratpack/RatpackHttpClientInstrumentation.java
index 10a1b943ac..5a022dde4c 100644
--- a/dd-java-agent/instrumentation/ratpack-1.4/src/main/java/datadog/trace/instrumentation/ratpack/RatpackHttpClientInstrumentation.java
+++ b/dd-java-agent/instrumentation/ratpack-1.4/src/main/java/datadog/trace/instrumentation/ratpack/RatpackHttpClientInstrumentation.java
@@ -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 transformers() {
+ Map 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;
}
}
diff --git a/dd-java-agent/instrumentation/ratpack-1.4/src/main/java/datadog/trace/instrumentation/ratpack/RatpackInstrumentation.java b/dd-java-agent/instrumentation/ratpack-1.4/src/main/java/datadog/trace/instrumentation/ratpack/RatpackInstrumentation.java
index 164258e12d..1502300456 100644
--- a/dd-java-agent/instrumentation/ratpack-1.4/src/main/java/datadog/trace/instrumentation/ratpack/RatpackInstrumentation.java
+++ b/dd-java-agent/instrumentation/ratpack-1.4/src/main/java/datadog/trace/instrumentation/ratpack/RatpackInstrumentation.java
@@ -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 transformers() {
+ Map 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 transformers() {
+ Map 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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(
+ named("fork").and(returns(named("ratpack.exec.ExecStarter"))),
+ RatpackServerAdvice.ExecutionAdvice.class.getName());
+ return transformers;
+ }
}
}
diff --git a/dd-java-agent/instrumentation/servlet-2/src/main/java/datadog/trace/instrumentation/servlet2/FilterChain2Instrumentation.java b/dd-java-agent/instrumentation/servlet-2/src/main/java/datadog/trace/instrumentation/servlet2/FilterChain2Instrumentation.java
index b28d895faa..bd4f760536 100644
--- a/dd-java-agent/instrumentation/servlet-2/src/main/java/datadog/trace/instrumentation/servlet2/FilterChain2Instrumentation.java
+++ b/dd-java-agent/instrumentation/servlet-2/src/main/java/datadog/trace/instrumentation/servlet2/FilterChain2Instrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/servlet-2/src/main/java/datadog/trace/instrumentation/servlet2/HttpServlet2Instrumentation.java b/dd-java-agent/instrumentation/servlet-2/src/main/java/datadog/trace/instrumentation/servlet2/HttpServlet2Instrumentation.java
index fc65a7bdf5..1bffbd412a 100644
--- a/dd-java-agent/instrumentation/servlet-2/src/main/java/datadog/trace/instrumentation/servlet2/HttpServlet2Instrumentation.java
+++ b/dd-java-agent/instrumentation/servlet-2/src/main/java/datadog/trace/instrumentation/servlet2/HttpServlet2Instrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/servlet-3/src/main/java/datadog/trace/instrumentation/servlet3/FilterChain3Instrumentation.java b/dd-java-agent/instrumentation/servlet-3/src/main/java/datadog/trace/instrumentation/servlet3/FilterChain3Instrumentation.java
index 3b52294ff0..60974a3b1f 100644
--- a/dd-java-agent/instrumentation/servlet-3/src/main/java/datadog/trace/instrumentation/servlet3/FilterChain3Instrumentation.java
+++ b/dd-java-agent/instrumentation/servlet-3/src/main/java/datadog/trace/instrumentation/servlet3/FilterChain3Instrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/servlet-3/src/main/java/datadog/trace/instrumentation/servlet3/HttpServlet3Instrumentation.java b/dd-java-agent/instrumentation/servlet-3/src/main/java/datadog/trace/instrumentation/servlet3/HttpServlet3Instrumentation.java
index 841931afb1..b64f7d34e9 100644
--- a/dd-java-agent/instrumentation/servlet-3/src/main/java/datadog/trace/instrumentation/servlet3/HttpServlet3Instrumentation.java
+++ b/dd-java-agent/instrumentation/servlet-3/src/main/java/datadog/trace/instrumentation/servlet3/HttpServlet3Instrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/sparkjava-2.4/src/main/java/datadog/trace/instrumentation/sparkjava/RoutesInstrumentation.java b/dd-java-agent/instrumentation/sparkjava-2.4/src/main/java/datadog/trace/instrumentation/sparkjava/RoutesInstrumentation.java
index 6856ea3d56..6b292b5111 100644
--- a/dd-java-agent/instrumentation/sparkjava-2.4/src/main/java/datadog/trace/instrumentation/sparkjava/RoutesInstrumentation.java
+++ b/dd-java-agent/instrumentation/sparkjava-2.4/src/main/java/datadog/trace/instrumentation/sparkjava/RoutesInstrumentation.java
@@ -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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/spring-web/src/main/java/datadog/trace/instrumentation/springweb/SpringWebInstrumentation.java b/dd-java-agent/instrumentation/spring-web/src/main/java/datadog/trace/instrumentation/springweb/SpringWebInstrumentation.java
index 5e82cb2998..be53bc2091 100644
--- a/dd-java-agent/instrumentation/spring-web/src/main/java/datadog/trace/instrumentation/springweb/SpringWebInstrumentation.java
+++ b/dd-java-agent/instrumentation/spring-web/src/main/java/datadog/trace/instrumentation/springweb/SpringWebInstrumentation.java
@@ -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 transformers() {
+ Map 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 transformers() {
+ Map 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 {
diff --git a/dd-java-agent/instrumentation/spymemcached-2.12/src/main/java/datadog/trace/instrumentation/spymemcached/MemcachedClientInstrumentation.java b/dd-java-agent/instrumentation/spymemcached-2.12/src/main/java/datadog/trace/instrumentation/spymemcached/MemcachedClientInstrumentation.java
index 3df5b09a8c..c3cc01de82 100644
--- a/dd-java-agent/instrumentation/spymemcached-2.12/src/main/java/datadog/trace/instrumentation/spymemcached/MemcachedClientInstrumentation.java
+++ b/dd-java-agent/instrumentation/spymemcached-2.12/src/main/java/datadog/trace/instrumentation/spymemcached/MemcachedClientInstrumentation.java
@@ -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 transformers() {
+ Map 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
diff --git a/dd-java-agent/instrumentation/trace-annotation/src/main/java/datadog/trace/instrumentation/trace_annotation/TraceAnnotationsInstrumentation.java b/dd-java-agent/instrumentation/trace-annotation/src/main/java/datadog/trace/instrumentation/trace_annotation/TraceAnnotationsInstrumentation.java
index dbabdefe14..3d77dfe3c4 100644
--- a/dd-java-agent/instrumentation/trace-annotation/src/main/java/datadog/trace/instrumentation/trace_annotation/TraceAnnotationsInstrumentation.java
+++ b/dd-java-agent/instrumentation/trace-annotation/src/main/java/datadog/trace/instrumentation/trace_annotation/TraceAnnotationsInstrumentation.java
@@ -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 additionalTraceAnnotations;
+ private final ElementMatcher.Junction 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 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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(isAnnotatedWith(methodTraceMatcher), TraceAdvice.class.getName());
+ return transformers;
}
}
diff --git a/dd-java-agent/instrumentation/trace-annotation/src/main/java/datadog/trace/instrumentation/trace_annotation/TraceConfigInstrumentation.java b/dd-java-agent/instrumentation/trace-annotation/src/main/java/datadog/trace/instrumentation/trace_annotation/TraceConfigInstrumentation.java
index 410ca244e2..502eef6bdd 100644
--- a/dd-java-agent/instrumentation/trace-annotation/src/main/java/datadog/trace/instrumentation/trace_annotation/TraceConfigInstrumentation.java
+++ b/dd-java-agent/instrumentation/trace-annotation/src/main/java/datadog/trace/instrumentation/trace_annotation/TraceConfigInstrumentation.java
@@ -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> 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 methodNames;
+
+ public TracerClassInstrumentation(String className, Set methodNames) {
+ super("trace", "trace-config");
+ this.className = className;
+ this.methodNames = methodNames;
+ }
+
+ @Override
+ public ElementMatcher super TypeDescription> typeMatcher() {
+ return hasSuperType(named(className));
+ }
+
+ @Override
+ public Map transformers() {
ElementMatcher.Junction 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 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 transformers() {
+ throw new RuntimeException("TracerConfigInstrumentation must not use transformers.");
}
}
diff --git a/dd-java-agent/testing/src/test/java/IBMResourceLevelInstrumentation.java b/dd-java-agent/testing/src/test/java/IBMResourceLevelInstrumentation.java
index 19761de49d..f08c57d064 100644
--- a/dd-java-agent/testing/src/test/java/IBMResourceLevelInstrumentation.java
+++ b/dd-java-agent/testing/src/test/java/IBMResourceLevelInstrumentation.java
@@ -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 transformers() {
+ Map transformers = new HashMap<>();
+ transformers.put(named("toString"), ToStringAdvice.class.getName());
+ return transformers;
}
public static class ToStringAdvice {