Merge pull request #417 from DataDog/mar-kolya/apache-http-client-fix-exception-handling
Apache http client fix exception handling
This commit is contained in:
commit
911ad5f231
|
@ -1,17 +1,22 @@
|
|||
package datadog.trace.agent.integration.classloading
|
||||
|
||||
import datadog.test.ClassToInstrument
|
||||
import datadog.test.ClassToInstrumentChild
|
||||
import datadog.trace.agent.test.IntegrationTestUtils
|
||||
import datadog.trace.api.Trace
|
||||
import spock.lang.Specification
|
||||
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
import static datadog.trace.agent.test.IntegrationTestUtils.createJarWithClasses
|
||||
|
||||
class ClassLoadingTest extends Specification {
|
||||
|
||||
final URL[] classpath = [createJarWithClasses(ClassToInstrument, ClassToInstrumentChild, Trace)]
|
||||
|
||||
/** Assert that we can instrument classloaders which cannot resolve agent advice classes. */
|
||||
def "instrument classloader without agent classes"() {
|
||||
setup:
|
||||
final URL[] classpath = [createJarWithClasses(ClassToInstrument, Trace)]
|
||||
final URLClassLoader loader = new URLClassLoader(classpath, (ClassLoader) null)
|
||||
|
||||
when:
|
||||
|
@ -25,6 +30,61 @@ class ClassLoadingTest extends Specification {
|
|||
instrumentedClass.getClassLoader() == loader
|
||||
}
|
||||
|
||||
def "make sure ByteBuddy does not hold strong references to ClassLoader"() {
|
||||
setup:
|
||||
final URLClassLoader loader = new URLClassLoader(classpath, (ClassLoader) null)
|
||||
final WeakReference<URLClassLoader> ref = new WeakReference<>(loader)
|
||||
|
||||
when:
|
||||
loader.loadClass(ClassToInstrument.getName())
|
||||
loader = null
|
||||
|
||||
IntegrationTestUtils.awaitGC()
|
||||
|
||||
then:
|
||||
null == ref.get()
|
||||
}
|
||||
|
||||
// We are doing this because Grovy cannot properly resolve constructor argument types in anonymous classes
|
||||
static class CountingClassLoader extends URLClassLoader {
|
||||
public int count = 0
|
||||
|
||||
CountingClassLoader(URL[] urls) {
|
||||
super(urls, (ClassLoader) null)
|
||||
}
|
||||
|
||||
@Override
|
||||
URL getResource(String name) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
def "make sure that ByteBuddy reads classes's bytes only once"() {
|
||||
setup:
|
||||
final CountingClassLoader loader = new CountingClassLoader(classpath)
|
||||
|
||||
when:
|
||||
loader.loadClass(ClassToInstrument.getName())
|
||||
loader.loadClass(ClassToInstrumentChild.getName())
|
||||
|
||||
then:
|
||||
loader.count == 2
|
||||
}
|
||||
|
||||
def "make sure that ByteBuddy doesn't resue cached type descriptions between different classloaders"() {
|
||||
setup:
|
||||
final CountingClassLoader loader1 = new CountingClassLoader(classpath)
|
||||
final CountingClassLoader loader2 = new CountingClassLoader(classpath)
|
||||
|
||||
when:
|
||||
loader1.loadClass(ClassToInstrument.getName())
|
||||
loader2.loadClass(ClassToInstrument.getName())
|
||||
|
||||
then:
|
||||
loader1.count == 1
|
||||
loader2.count == 1
|
||||
}
|
||||
|
||||
def "can find bootstrap resources"() {
|
||||
expect:
|
||||
IntegrationTestUtils.getAgentClassLoader().getResources('datadog/trace/api/Trace.class') != null
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
package datadog.trace.agent.integration.classloading;
|
||||
|
||||
import datadog.trace.api.Trace;
|
||||
|
||||
class ClassToInstrument {
|
||||
@Trace
|
||||
public static void someMethod() {}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package datadog.test;
|
||||
|
||||
import datadog.trace.api.Trace;
|
||||
|
||||
/** Note: this has to stay in 'datadog.test' package to be considered for instrumentation */
|
||||
public class ClassToInstrument {
|
||||
@Trace
|
||||
public static void someMethod() {}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package datadog.test;
|
||||
|
||||
/** Note: this has to stay in 'datadog.test' package to be considered for instrumentation */
|
||||
public class ClassToInstrumentChild extends ClassToInstrument {}
|
|
@ -7,6 +7,7 @@ import java.io.File;
|
|||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
import java.util.UUID;
|
||||
|
@ -156,4 +157,14 @@ public class IntegrationTestUtils {
|
|||
.getField("AGENT_PACKAGE_PREFIXES");
|
||||
return (String[]) f.get(null);
|
||||
}
|
||||
|
||||
public static void awaitGC() {
|
||||
System.gc(); // For good measure.
|
||||
Object obj = new Object();
|
||||
final WeakReference ref = new WeakReference<>(obj);
|
||||
obj = null;
|
||||
while (ref.get() != null) {
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ public class AgentInstaller {
|
|||
new AgentBuilder.Default()
|
||||
.disableClassFormatChanges()
|
||||
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
|
||||
.with(AgentBuilder.DescriptionStrategy.Default.POOL_ONLY)
|
||||
.with(new LoggingListener())
|
||||
.with(new DDLocationStrategy())
|
||||
.ignore(any(), skipClassLoader())
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
package datadog.trace.agent.tooling;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.erasure;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.bytebuddy.build.HashCodeAndEqualsPlugin;
|
||||
import net.bytebuddy.description.type.TypeDefinition;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.description.type.TypeList;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
|
||||
/**
|
||||
* This class provides some custom ByteBuddy element matchers to use when applying instrumentation
|
||||
*/
|
||||
@Slf4j
|
||||
public class ByteBuddyElementMatchers {
|
||||
|
||||
/**
|
||||
* Matches any type description that declares a super type that matches the provided matcher.
|
||||
* Exceptions during matching process are logged and ignored.
|
||||
*
|
||||
* @param matcher The type to be checked for being a super type of the matched type.
|
||||
* @param <T> The type of the matched object.
|
||||
* @return A matcher that matches any type description that declares a super type that matches the
|
||||
* provided matcher.
|
||||
* @see ElementMatchers#hasSuperType(net.bytebuddy.matcher.ElementMatcher)
|
||||
*/
|
||||
public static <T extends TypeDescription> ElementMatcher.Junction<T> safeHasSuperType(
|
||||
final ElementMatcher<? super TypeDescription> matcher) {
|
||||
return safeHasGenericSuperType(erasure(matcher));
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches any type description that declares a super type that matches the provided matcher.
|
||||
* Exceptions during matching process are logged and ignored.
|
||||
*
|
||||
* @param matcher The type to be checked for being a super type of the matched type.
|
||||
* @param <T> The type of the matched object.
|
||||
* @return A matcher that matches any type description that declares a super type that matches the
|
||||
* provided matcher.
|
||||
* @see ElementMatchers#hasGenericSuperType(net.bytebuddy.matcher.ElementMatcher)
|
||||
*/
|
||||
public static <T extends TypeDescription> ElementMatcher.Junction<T> safeHasGenericSuperType(
|
||||
final ElementMatcher<? super TypeDescription.Generic> matcher) {
|
||||
return new SafeHasSuperTypeMatcher<>(matcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* An element matcher that matches a super type. This is different from {@link
|
||||
* net.bytebuddy.matcher.HasSuperTypeMatcher} in the following way:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Exceptions are logged
|
||||
* <li>When exception happens the rest of the inheritance subtree is discarded (since ByteBuddy
|
||||
* cannot load/parse type information for it) but search in other subtrees continues
|
||||
* </ul>
|
||||
*
|
||||
* <p>This is useful because this allows us to see when matcher's check is not complete (i.e. part
|
||||
* of it fails), at the same time it makes best effort instead of failing quickly (like {@code
|
||||
* failSafe(hasSuperType(...))} does) which means the code is more resilient to classpath
|
||||
* inconsistencies
|
||||
*
|
||||
* @param <T> The type of the matched entity.
|
||||
* @see net.bytebuddy.matcher.HasSuperTypeMatcher
|
||||
*/
|
||||
@HashCodeAndEqualsPlugin.Enhance
|
||||
public static class SafeHasSuperTypeMatcher<T extends TypeDescription>
|
||||
extends ElementMatcher.Junction.AbstractBase<T> {
|
||||
|
||||
/** The matcher to apply to any super type of the matched type. */
|
||||
private final ElementMatcher<? super TypeDescription.Generic> matcher;
|
||||
|
||||
/**
|
||||
* Creates a new matcher for a super type.
|
||||
*
|
||||
* @param matcher The matcher to apply to any super type of the matched type.
|
||||
*/
|
||||
public SafeHasSuperTypeMatcher(final ElementMatcher<? super TypeDescription.Generic> matcher) {
|
||||
this.matcher = matcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(final T target) {
|
||||
final Set<TypeDescription> checkedInterfaces = new HashSet<>();
|
||||
// We do not use foreach loop and iterator interface here because we need to catch exceptions
|
||||
// in {@code getSuperClass} calls
|
||||
TypeDefinition typeDefinition = target;
|
||||
while (typeDefinition != null) {
|
||||
if (matcher.matches(typeDefinition.asGenericType())
|
||||
|| hasInterface(typeDefinition, checkedInterfaces)) {
|
||||
return true;
|
||||
}
|
||||
typeDefinition = safeGetSuperClass(typeDefinition);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private TypeDefinition safeGetSuperClass(final TypeDefinition typeDefinition) {
|
||||
try {
|
||||
return typeDefinition.getSuperClass();
|
||||
} catch (final Exception e) {
|
||||
log.info("Exception trying to get next type definition:", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches a type's interfaces against the provided matcher.
|
||||
*
|
||||
* @param typeDefinition The type for which to check all implemented interfaces.
|
||||
* @param checkedInterfaces The interfaces that have already been checked.
|
||||
* @return {@code true} if any interface matches the supplied matcher.
|
||||
*/
|
||||
private boolean hasInterface(
|
||||
final TypeDefinition typeDefinition, final Set<TypeDescription> checkedInterfaces) {
|
||||
for (final TypeDefinition interfaceType : safeGetInterfaces(typeDefinition)) {
|
||||
if (checkedInterfaces.add(interfaceType.asErasure())
|
||||
&& (matcher.matches(interfaceType.asGenericType())
|
||||
|| hasInterface(interfaceType, checkedInterfaces))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private TypeList.Generic safeGetInterfaces(final TypeDefinition typeDefinition) {
|
||||
try {
|
||||
return typeDefinition.getInterfaces();
|
||||
} catch (final Exception e) {
|
||||
log.info("Exception trying to get interfaces:", e);
|
||||
return new TypeList.Generic.Empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "safeHasSuperType(" + matcher + ")";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package datadog.trace.agent.tooling;
|
||||
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder.LocationStrategy;
|
||||
import net.bytebuddy.dynamic.ClassFileLocator;
|
||||
|
||||
/** A bytebuddy advice builder with default DataDog settings. */
|
||||
public class DDAdvice extends AgentBuilder.Transformer.ForAdvice {
|
||||
private static final ClassFileLocator AGENT_CLASS_LOCATOR =
|
||||
ClassFileLocator.ForClassLoader.of(Utils.getAgentClassLoader());
|
||||
/** Location strategy for resolving classes in the agent's jar. */
|
||||
private static final LocationStrategy AGENT_CLASS_LOCATION_STRATEGY =
|
||||
new AgentBuilder.LocationStrategy.Simple(AGENT_CLASS_LOCATOR);
|
||||
|
||||
/**
|
||||
* Create bytebuddy advice with default datadog settings.
|
||||
*
|
||||
* @return the bytebuddy advice
|
||||
*/
|
||||
public static AgentBuilder.Transformer.ForAdvice create() {
|
||||
return create(true);
|
||||
}
|
||||
|
||||
public static AgentBuilder.Transformer.ForAdvice create(final boolean includeExceptionHandler) {
|
||||
ForAdvice advice = new DDAdvice().with(AGENT_CLASS_LOCATION_STRATEGY);
|
||||
if (includeExceptionHandler) {
|
||||
advice = advice.withExceptionHandler(ExceptionHandlers.defaultExceptionHandler());
|
||||
}
|
||||
return advice;
|
||||
}
|
||||
|
||||
private DDAdvice() {}
|
||||
}
|
|
@ -12,16 +12,14 @@ import net.bytebuddy.utility.JavaModule;
|
|||
* reached.
|
||||
*/
|
||||
public class DDLocationStrategy implements AgentBuilder.LocationStrategy {
|
||||
private static final ClassLoader BOOTSTRAP_RESOURCE_LOCATOR = new ClassLoader(null) {};
|
||||
|
||||
@Override
|
||||
public ClassFileLocator classFileLocator(ClassLoader classLoader, JavaModule javaModule) {
|
||||
List<ClassFileLocator> locators = new ArrayList<ClassFileLocator>();
|
||||
public ClassFileLocator classFileLocator(ClassLoader classLoader, final JavaModule javaModule) {
|
||||
final List<ClassFileLocator> locators = new ArrayList<>();
|
||||
while (classLoader != null) {
|
||||
locators.add(ClassFileLocator.ForClassLoader.of(classLoader));
|
||||
classLoader = classLoader.getParent();
|
||||
}
|
||||
locators.add(ClassFileLocator.ForClassLoader.of(BOOTSTRAP_RESOURCE_LOCATOR));
|
||||
locators.add(ClassFileLocator.ForClassLoader.of(Utils.getBootstrapProxy()));
|
||||
return new ClassFileLocator.Compound(locators.toArray(new ClassFileLocator[0]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,9 +30,10 @@ public class HelperInjector implements Transformer {
|
|||
* Construct HelperInjector.
|
||||
*
|
||||
* @param helperClassNames binary names of the helper classes to inject. These class names must be
|
||||
* resolvable by the classloader returned by DDAdvice#getAgentClassLoader(). Classes are
|
||||
* injected in the order provided. This is important if there is interdependency between
|
||||
* helper classes that requires them to be injected in a specific order.
|
||||
* resolvable by the classloader returned by
|
||||
* datadog.trace.agent.tooling.Utils#getAgentClassLoader(). Classes are injected in the order
|
||||
* provided. This is important if there is interdependency between helper classes that
|
||||
* requires them to be injected in a specific order.
|
||||
*/
|
||||
public HelperInjector(final String... helperClassNames) {
|
||||
this.helperClassNames = new LinkedHashSet<>(Arrays.asList(helperClassNames));
|
||||
|
|
|
@ -51,7 +51,7 @@ public interface Instrumenter {
|
|||
protected final boolean enabled;
|
||||
|
||||
public Default(final String instrumentationName, final String... additionalNames) {
|
||||
this.instrumentationNames = new HashSet<>(Arrays.asList(additionalNames));
|
||||
instrumentationNames = new HashSet<>(Arrays.asList(additionalNames));
|
||||
instrumentationNames.add(instrumentationName);
|
||||
instrumentationPrimaryName = instrumentationName;
|
||||
|
||||
|
@ -72,17 +72,46 @@ public interface Instrumenter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AgentBuilder instrument(final AgentBuilder agentBuilder) {
|
||||
public AgentBuilder instrument(final AgentBuilder parentAgentBuilder) {
|
||||
if (!enabled) {
|
||||
log.debug("Instrumentation {} is disabled", this);
|
||||
return parentAgentBuilder;
|
||||
}
|
||||
|
||||
AgentBuilder.Identified.Extendable agentBuilder =
|
||||
parentAgentBuilder
|
||||
.type(typeMatcher(), classLoaderMatcher())
|
||||
.and(new MuzzleMatcher())
|
||||
.transform(DDTransformers.defaultTransformers());
|
||||
agentBuilder = injectHelperClasses(agentBuilder);
|
||||
agentBuilder = applyInstrumentationTransformers(agentBuilder);
|
||||
return agentBuilder.asDecorator();
|
||||
}
|
||||
|
||||
private AgentBuilder.Identified.Extendable injectHelperClasses(
|
||||
AgentBuilder.Identified.Extendable agentBuilder) {
|
||||
final String[] helperClassNames = helperClassNames();
|
||||
if (helperClassNames.length > 0) {
|
||||
agentBuilder = agentBuilder.transform(new HelperInjector(helperClassNames));
|
||||
}
|
||||
return agentBuilder;
|
||||
}
|
||||
|
||||
AgentBuilder.Identified.Extendable advice =
|
||||
agentBuilder
|
||||
.type(typeMatcher(), classLoaderMatcher())
|
||||
.and(
|
||||
new AgentBuilder.RawMatcher() {
|
||||
private AgentBuilder.Identified.Extendable applyInstrumentationTransformers(
|
||||
AgentBuilder.Identified.Extendable agentBuilder) {
|
||||
for (final Map.Entry<ElementMatcher, String> entry : transformers().entrySet()) {
|
||||
agentBuilder =
|
||||
agentBuilder.transform(
|
||||
new AgentBuilder.Transformer.ForAdvice()
|
||||
.include(Utils.getAgentClassLoader())
|
||||
.withExceptionHandler(ExceptionHandlers.defaultExceptionHandler())
|
||||
.advice(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
return agentBuilder;
|
||||
}
|
||||
|
||||
/** Matches classes for which instrumentation is not muzzled. */
|
||||
private class MuzzleMatcher implements AgentBuilder.RawMatcher {
|
||||
@Override
|
||||
public boolean matches(
|
||||
final TypeDescription typeDescription,
|
||||
|
@ -102,7 +131,7 @@ public interface Instrumenter {
|
|||
log.debug(
|
||||
"Instrumentation muzzled: {} -- {} on {}",
|
||||
instrumentationPrimaryName,
|
||||
this.getClass().getName(),
|
||||
getClass().getName(),
|
||||
classLoader);
|
||||
}
|
||||
for (final Reference.Mismatch mismatch : mismatches) {
|
||||
|
@ -112,16 +141,6 @@ public interface Instrumenter {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
})
|
||||
.transform(DDTransformers.defaultTransformers());
|
||||
final String[] helperClassNames = helperClassNames();
|
||||
if (helperClassNames.length > 0) {
|
||||
advice = advice.transform(new HelperInjector(helperClassNames));
|
||||
}
|
||||
for (final Map.Entry<ElementMatcher, String> entry : transformers().entrySet()) {
|
||||
advice = advice.transform(DDAdvice.create().advice(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
return advice.asDecorator();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,11 +21,11 @@ public class ReferenceMatcher {
|
|||
private final Reference[] references;
|
||||
private final Set<String> helperClassNames;
|
||||
|
||||
public ReferenceMatcher(Reference... references) {
|
||||
public ReferenceMatcher(final Reference... references) {
|
||||
this(new String[0], references);
|
||||
}
|
||||
|
||||
public ReferenceMatcher(String[] helperClassNames, Reference[] references) {
|
||||
public ReferenceMatcher(final String[] helperClassNames, final Reference[] references) {
|
||||
this.references = references;
|
||||
this.helperClassNames = new HashSet<>(Arrays.asList(helperClassNames));
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public class ReferenceMatcher {
|
|||
* @param loader Classloader to validate against (or null for bootstrap)
|
||||
* @return true if all references match the classpath of loader
|
||||
*/
|
||||
public boolean matches(ClassLoader loader) {
|
||||
public boolean matches(final ClassLoader loader) {
|
||||
return getMismatchedReferenceSources(loader).size() == 0;
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ public class ReferenceMatcher {
|
|||
mismatches = mismatchCache.get(loader);
|
||||
if (null == mismatches) {
|
||||
mismatches = new ArrayList<>(0);
|
||||
for (Reference reference : references) {
|
||||
for (final Reference reference : references) {
|
||||
// Don't reference-check helper classes.
|
||||
// They will be injected by the instrumentation's HelperInjector.
|
||||
if (!helperClassNames.contains(reference.getClassName())) {
|
||||
|
|
|
@ -6,7 +6,6 @@ import datadog.trace.agent.test.AgentTestRunner
|
|||
import datadog.trace.api.DDSpanTypes
|
||||
import datadog.trace.api.DDTags
|
||||
import io.opentracing.tag.Tags
|
||||
import net.bytebuddy.utility.JavaModule
|
||||
import play.inject.guice.GuiceApplicationBuilder
|
||||
import spock.lang.Shared
|
||||
|
||||
|
@ -25,27 +24,13 @@ class LagomTest extends AgentTestRunner {
|
|||
@Shared
|
||||
private TestServer server
|
||||
|
||||
@Override
|
||||
protected boolean onInstrumentationError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) {
|
||||
if (throwable.getMessage().contains('Cannot resolve type description for akka.stream.impl.VirtualProcessor$WrappedSubscription$$SubscriptionState')) {
|
||||
// 'akka/stream/impl/VirtualProcessor$WrappedSubscription$PassThrough$.class' declares
|
||||
// itself an implementation of 'VirtualProcessor$WrappedSubscription$$SubscriptionState',
|
||||
// but this interface does not exist on the classpath.
|
||||
// The closest thing on the classpath is 'VirtualProcessor$WrappedSubscription$SubscriptionState' (only one $).
|
||||
|
||||
// Looks like a compiler/packaging issue on akka's end. Or maybe this interface is dynamically generated.
|
||||
return false
|
||||
}
|
||||
return super.onInstrumentationError(typeName, classLoader, module, loaded, throwable)
|
||||
}
|
||||
|
||||
def setupSpec() {
|
||||
server = startServer(defaultSetup()
|
||||
.withCluster(false)
|
||||
.withPersistence(false)
|
||||
.withCassandra(false)
|
||||
.withJdbc(false)
|
||||
.withConfigureBuilder(
|
||||
.configureBuilder(
|
||||
new Function<GuiceApplicationBuilder, GuiceApplicationBuilder>() {
|
||||
@Override
|
||||
GuiceApplicationBuilder apply(GuiceApplicationBuilder builder) {
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
lagom.circuit-breaker {
|
||||
// Disable Lagom circuit-breaker
|
||||
default {
|
||||
enabled = off
|
||||
}
|
||||
}
|
|
@ -1,18 +1,25 @@
|
|||
package datadog.trace.instrumentation.apachehttpclient;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isAbstract;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
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.Instrumenter;
|
||||
import io.opentracing.Scope;
|
||||
import io.opentracing.Span;
|
||||
import io.opentracing.Tracer;
|
||||
import io.opentracing.tag.Tags;
|
||||
import io.opentracing.util.GlobalTracer;
|
||||
import java.util.Collections;
|
||||
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)
|
||||
|
@ -23,8 +30,9 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
||||
return named("org.apache.http.impl.client.HttpClientBuilder");
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("org.apache.http.impl.client.HttpClientBuilder")
|
||||
.or(safeHasSuperType(named("org.apache.http.impl.client.CloseableHttpClient")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -38,7 +46,9 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
|
|||
"org.apache.http.client.methods.HttpRequestWrapper",
|
||||
"org.apache.http.client.protocol.HttpClientContext",
|
||||
"org.apache.http.conn.routing.HttpRoute",
|
||||
"org.apache.http.impl.execchain.ClientExecChain");
|
||||
"org.apache.http.impl.execchain.ClientExecChain",
|
||||
"org.apache.http.impl.client.CloseableHttpClient",
|
||||
"org.apache.http.impl.client.InternalHttpClient");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -51,19 +61,42 @@ public class ApacheHttpClientInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod().and(named("decorateProtocolExec")), ApacheHttpClientAdvice.class.getName());
|
||||
isMethod().and(not(isAbstract())).and(named("doExecute")), ClientAdvice.class.getName());
|
||||
transformers.put(
|
||||
isMethod().and(named("decorateProtocolExec")), ClientExecAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
public static class ApacheHttpClientAdvice {
|
||||
/** Strategy: add our tracing exec to the apache exec chain. */
|
||||
public static class ClientAdvice {
|
||||
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static Scope methodEnter() {
|
||||
final Tracer.SpanBuilder spanBuilder =
|
||||
GlobalTracer.get()
|
||||
.buildSpan(DDTracingClientExec.OPERATION_NAME)
|
||||
.withTag(Tags.COMPONENT.getKey(), DDTracingClientExec.COMPONENT_NAME);
|
||||
return spanBuilder.startActive(true);
|
||||
}
|
||||
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void methodExit(
|
||||
@Advice.Enter final Scope scope, @Advice.Thrown final Throwable throwable) {
|
||||
final Span span = scope.span();
|
||||
if (throwable != null) {
|
||||
Tags.ERROR.set(span, Boolean.TRUE);
|
||||
span.log(Collections.singletonMap(ERROR_OBJECT, throwable));
|
||||
span.finish();
|
||||
}
|
||||
scope.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ClientExecAdvice {
|
||||
@Advice.OnMethodExit(suppress = Throwable.class)
|
||||
public static void addTracingExec(@Advice.Return(readOnly = false) ClientExecChain execChain) {
|
||||
execChain =
|
||||
new DDTracingClientExec(
|
||||
execChain, DefaultRedirectStrategy.INSTANCE, false, GlobalTracer.get());
|
||||
execChain = new DDTracingClientExec(execChain, GlobalTracer.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ import java.util.Map;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.http.HttpException;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.client.RedirectStrategy;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpExecutionAware;
|
||||
import org.apache.http.client.methods.HttpRequestWrapper;
|
||||
|
@ -33,36 +32,15 @@ import org.apache.http.impl.execchain.ClientExecChain;
|
|||
*/
|
||||
@Slf4j
|
||||
public class DDTracingClientExec implements ClientExecChain {
|
||||
private static final String COMPONENT_NAME = "apache-httpclient";
|
||||
private static final String OPERATION_NAME = "http.request";
|
||||
/**
|
||||
* Id of {@link HttpClientContext#setAttribute(String, Object)} representing span associated with
|
||||
* the current client processing. Referenced span is local span not a span representing HTTP
|
||||
* communication.
|
||||
*/
|
||||
private static final String ACTIVE_SPAN = DDTracingClientExec.class.getName() + ".activeSpan";
|
||||
/**
|
||||
* Tracing {@link ClientExecChain} is executed after redirect exec, so on redirects it is called
|
||||
* multiple times. This is used as an id for {@link HttpClientContext#setAttribute(String,
|
||||
* Object)} to store number of redirects.
|
||||
*/
|
||||
private static final String REDIRECT_COUNT =
|
||||
DDTracingClientExec.class.getName() + ".redirectCount";
|
||||
static final String COMPONENT_NAME = "apache-httpclient";
|
||||
static final String OPERATION_NAME = "http.request";
|
||||
|
||||
private final RedirectStrategy redirectStrategy;
|
||||
private final ClientExecChain requestExecutor;
|
||||
private final boolean redirectHandlingDisabled;
|
||||
|
||||
private final Tracer tracer;
|
||||
|
||||
public DDTracingClientExec(
|
||||
final ClientExecChain clientExecChain,
|
||||
final RedirectStrategy redirectStrategy,
|
||||
final boolean redirectHandlingDisabled,
|
||||
final Tracer tracer) {
|
||||
this.requestExecutor = clientExecChain;
|
||||
this.redirectStrategy = redirectStrategy;
|
||||
this.redirectHandlingDisabled = redirectHandlingDisabled;
|
||||
public DDTracingClientExec(final ClientExecChain clientExecChain, final Tracer tracer) {
|
||||
requestExecutor = clientExecChain;
|
||||
this.tracer = tracer;
|
||||
}
|
||||
|
||||
|
@ -73,91 +51,37 @@ public class DDTracingClientExec implements ClientExecChain {
|
|||
final HttpClientContext clientContext,
|
||||
final HttpExecutionAware execAware)
|
||||
throws IOException, HttpException {
|
||||
|
||||
Scope localScope = clientContext.getAttribute(ACTIVE_SPAN, Scope.class);
|
||||
CloseableHttpResponse response = null;
|
||||
try {
|
||||
if (localScope == null) {
|
||||
localScope = createLocalScope(request, clientContext);
|
||||
}
|
||||
|
||||
return (response = createNetworkSpan(localScope, route, request, clientContext, execAware));
|
||||
} catch (final Exception e) {
|
||||
localScope.close();
|
||||
throw e;
|
||||
} finally {
|
||||
if (response != null) {
|
||||
/**
|
||||
* This exec runs after {@link org.apache.http.impl.execchain.RedirectExec} which loops
|
||||
* until there is no redirect or reaches max redirect count. {@link RedirectStrategy} is
|
||||
* used to decide whether localScope should be finished or not. If there is a redirect
|
||||
* localScope is not finished and redirect is logged.
|
||||
*/
|
||||
Integer redirectCount = clientContext.getAttribute(REDIRECT_COUNT, Integer.class);
|
||||
if (!redirectHandlingDisabled
|
||||
&& clientContext.getRequestConfig().isRedirectsEnabled()
|
||||
&& redirectStrategy.isRedirected(request, response, clientContext)
|
||||
&& ++redirectCount < clientContext.getRequestConfig().getMaxRedirects()) {
|
||||
clientContext.setAttribute(REDIRECT_COUNT, redirectCount);
|
||||
} else {
|
||||
localScope.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Scope createLocalScope(
|
||||
final HttpRequest httpRequest, final HttpClientContext clientContext) {
|
||||
final Tracer.SpanBuilder spanBuilder =
|
||||
tracer.buildSpan(OPERATION_NAME).withTag(Tags.COMPONENT.getKey(), COMPONENT_NAME);
|
||||
|
||||
final Scope scope = spanBuilder.startActive(true);
|
||||
clientContext.setAttribute(ACTIVE_SPAN, scope);
|
||||
clientContext.setAttribute(REDIRECT_COUNT, 0);
|
||||
return scope;
|
||||
}
|
||||
|
||||
private CloseableHttpResponse createNetworkSpan(
|
||||
final Scope parentScope,
|
||||
final HttpRoute route,
|
||||
final HttpRequestWrapper request,
|
||||
final HttpClientContext clientContext,
|
||||
final HttpExecutionAware execAware)
|
||||
throws IOException, HttpException {
|
||||
Scope networkScope = null;
|
||||
Span networkSpan = null;
|
||||
Scope scope = null;
|
||||
Span span = null;
|
||||
try {
|
||||
// This handlers runs untrapped in the client code
|
||||
// so we must ensure any unexpected agent errors are caught.
|
||||
try {
|
||||
networkScope =
|
||||
scope =
|
||||
tracer
|
||||
.buildSpan(OPERATION_NAME)
|
||||
.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)
|
||||
.withTag(DDTags.SPAN_TYPE, DDSpanTypes.HTTP_CLIENT)
|
||||
.asChildOf(parentScope.span())
|
||||
.startActive(true);
|
||||
networkSpan = networkScope.span();
|
||||
span = scope.span();
|
||||
|
||||
final boolean awsClientCall = request.getHeaders("amz-sdk-invocation-id").length > 0;
|
||||
// AWS calls are often signed, so we can't add headers without breaking the signature.
|
||||
if (!awsClientCall) {
|
||||
tracer.inject(
|
||||
networkSpan.context(),
|
||||
Format.Builtin.HTTP_HEADERS,
|
||||
new HttpHeadersInjectAdapter(request));
|
||||
span.context(), Format.Builtin.HTTP_HEADERS, new HttpHeadersInjectAdapter(request));
|
||||
}
|
||||
// request tags
|
||||
Tags.HTTP_METHOD.set(networkSpan, request.getRequestLine().getMethod());
|
||||
Tags.HTTP_URL.set(networkSpan, request.getRequestLine().getUri());
|
||||
Tags.HTTP_METHOD.set(span, request.getRequestLine().getMethod());
|
||||
Tags.HTTP_URL.set(span, request.getRequestLine().getUri());
|
||||
final URI uri = request.getURI();
|
||||
// zuul users have encountered cases where getURI returns null
|
||||
if (null != uri) {
|
||||
Tags.PEER_PORT.set(networkSpan, uri.getPort() == -1 ? 80 : uri.getPort());
|
||||
Tags.PEER_HOSTNAME.set(networkSpan, uri.getHost());
|
||||
Tags.PEER_PORT.set(span, uri.getPort() == -1 ? 80 : uri.getPort());
|
||||
Tags.PEER_HOSTNAME.set(span, uri.getHost());
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
log.debug("failed to create network span", e);
|
||||
log.debug("failed to create span", e);
|
||||
}
|
||||
|
||||
final CloseableHttpResponse response =
|
||||
|
@ -165,23 +89,23 @@ public class DDTracingClientExec implements ClientExecChain {
|
|||
|
||||
try {
|
||||
// response tags
|
||||
if (null != networkSpan) {
|
||||
Tags.HTTP_STATUS.set(networkSpan, response.getStatusLine().getStatusCode());
|
||||
if (null != span) {
|
||||
Tags.HTTP_STATUS.set(span, response.getStatusLine().getStatusCode());
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
log.debug("failed to set network span status", e);
|
||||
log.debug("failed to set span status", e);
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (IOException | HttpException | RuntimeException e) {
|
||||
} catch (final IOException | HttpException | RuntimeException e) {
|
||||
// error tags
|
||||
Tags.ERROR.set(networkSpan, Boolean.TRUE);
|
||||
networkSpan.log(Collections.singletonMap(ERROR_OBJECT, e));
|
||||
Tags.ERROR.set(span, Boolean.TRUE);
|
||||
span.log(Collections.singletonMap(ERROR_OBJECT, e));
|
||||
|
||||
throw e;
|
||||
} finally {
|
||||
if (null != networkScope) {
|
||||
networkScope.close();
|
||||
if (null != scope) {
|
||||
scope.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
import datadog.opentracing.DDSpan
|
||||
import datadog.trace.agent.test.AgentTestRunner
|
||||
import datadog.trace.agent.test.ListWriterAssert
|
||||
import datadog.trace.agent.test.RatpackUtils
|
||||
import datadog.trace.agent.test.TraceAssert
|
||||
import datadog.trace.api.DDSpanTypes
|
||||
import datadog.trace.api.DDTags
|
||||
import io.opentracing.tag.Tags
|
||||
import org.apache.http.HttpResponse
|
||||
import org.apache.http.client.ClientProtocolException
|
||||
import org.apache.http.client.HttpClient
|
||||
import org.apache.http.client.config.RequestConfig
|
||||
import org.apache.http.client.methods.HttpGet
|
||||
import org.apache.http.impl.client.HttpClientBuilder
|
||||
import org.apache.http.message.BasicHeader
|
||||
import spock.lang.Shared
|
||||
|
||||
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
|
||||
import static datadog.trace.agent.test.TestUtils.runUnderTrace
|
||||
import static ratpack.groovy.test.embed.GroovyEmbeddedApp.ratpack
|
||||
|
||||
class ApacheHttpClientTest extends AgentTestRunner {
|
||||
|
@ -19,6 +23,7 @@ class ApacheHttpClientTest extends AgentTestRunner {
|
|||
@Shared
|
||||
def server = ratpack {
|
||||
handlers {
|
||||
prefix("success") {
|
||||
get {
|
||||
RatpackUtils.handleDistributedRequest(context)
|
||||
|
||||
|
@ -26,31 +31,147 @@ class ApacheHttpClientTest extends AgentTestRunner {
|
|||
response.status(200).send(msg)
|
||||
}
|
||||
}
|
||||
prefix("redirect") {
|
||||
get {
|
||||
RatpackUtils.handleDistributedRequest(context)
|
||||
|
||||
redirect(server.address.resolve("/success").toURL().toString())
|
||||
}
|
||||
}
|
||||
prefix("another-redirect") {
|
||||
get {
|
||||
RatpackUtils.handleDistributedRequest(context)
|
||||
|
||||
redirect(server.address.resolve("/redirect").toURL().toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@Shared
|
||||
int port = server.getAddress().port
|
||||
int port = server.address.port
|
||||
@Shared
|
||||
def successUrl = server.address.resolve("/success")
|
||||
@Shared
|
||||
def redirectUrl = server.address.resolve("/redirect")
|
||||
@Shared
|
||||
def twoRedirectsUrl = server.address.resolve("/another-redirect")
|
||||
|
||||
final HttpClientBuilder builder = HttpClientBuilder.create()
|
||||
final HttpClient client = builder.build()
|
||||
|
||||
def "trace request with propagation"() {
|
||||
setup:
|
||||
final HttpClientBuilder builder = HttpClientBuilder.create()
|
||||
when:
|
||||
HttpResponse response = client.execute(new HttpGet(successUrl))
|
||||
|
||||
final HttpClient client = builder.build()
|
||||
runUnderTrace("someTrace") {
|
||||
try {
|
||||
HttpResponse response = client.execute(new HttpGet(server.getAddress()))
|
||||
assert response.getStatusLine().getStatusCode() == 200
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace()
|
||||
throw new RuntimeException(e)
|
||||
}
|
||||
}
|
||||
|
||||
expect:
|
||||
then:
|
||||
response.getStatusLine().getStatusCode() == 200
|
||||
// one trace on the server, one trace on the client
|
||||
assertTraces(TEST_WRITER, 2) {
|
||||
trace(0, 1) {
|
||||
serverTrace(it, 0, TEST_WRITER[1][1])
|
||||
trace(1, 2) {
|
||||
clientParentSpan(it, 0)
|
||||
successClientSpan(it, 1, span(0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "trace redirected request with propagation many redirects allowed"() {
|
||||
setup:
|
||||
final RequestConfig.Builder requestConfigBuilder = new RequestConfig.Builder()
|
||||
requestConfigBuilder.setMaxRedirects(10)
|
||||
|
||||
HttpGet request = new HttpGet(redirectUrl)
|
||||
request.setConfig(requestConfigBuilder.build())
|
||||
|
||||
when:
|
||||
HttpResponse response = client.execute(request)
|
||||
|
||||
then:
|
||||
response.getStatusLine().getStatusCode() == 200
|
||||
// two traces on the server, one trace on the client
|
||||
assertTraces(TEST_WRITER, 3) {
|
||||
serverTrace(it, 0, TEST_WRITER[2][2])
|
||||
serverTrace(it, 1, TEST_WRITER[2][1])
|
||||
trace(2, 3) {
|
||||
clientParentSpan(it, 0)
|
||||
successClientSpan(it, 1, span(0))
|
||||
redirectClientSpan(it, 2, span(0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "trace redirected request with propagation 1 redirect allowed"() {
|
||||
setup:
|
||||
final RequestConfig.Builder requestConfigBuilder = new RequestConfig.Builder()
|
||||
requestConfigBuilder.setMaxRedirects(1)
|
||||
HttpGet request = new HttpGet(redirectUrl)
|
||||
request.setConfig(requestConfigBuilder.build())
|
||||
|
||||
when:
|
||||
HttpResponse response = client.execute(request)
|
||||
|
||||
then:
|
||||
response.getStatusLine().getStatusCode() == 200
|
||||
// two traces on the server, one trace on the client
|
||||
assertTraces(TEST_WRITER, 3) {
|
||||
serverTrace(it, 0, TEST_WRITER[2][2])
|
||||
serverTrace(it, 1, TEST_WRITER[2][1])
|
||||
trace(2, 3) {
|
||||
clientParentSpan(it, 0)
|
||||
successClientSpan(it, 1, span(0))
|
||||
redirectClientSpan(it, 2, span(0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "trace redirected request with propagation too many redirects"() {
|
||||
setup:
|
||||
final RequestConfig.Builder requestConfigBuilder = new RequestConfig.Builder()
|
||||
requestConfigBuilder.setMaxRedirects(1)
|
||||
|
||||
HttpGet request = new HttpGet(twoRedirectsUrl)
|
||||
request.setConfig(requestConfigBuilder.build())
|
||||
|
||||
when:
|
||||
client.execute(request)
|
||||
|
||||
then:
|
||||
def exception = thrown(ClientProtocolException)
|
||||
// two traces on the server, one trace on the client
|
||||
assertTraces(TEST_WRITER, 3) {
|
||||
serverTrace(it, 0, TEST_WRITER[2][2])
|
||||
serverTrace(it, 1, TEST_WRITER[2][1])
|
||||
trace(2, 3) {
|
||||
clientParentSpan(it, 0, exception)
|
||||
redirectClientSpan(it, 1, span(0))
|
||||
redirectClientSpan(it, 2, span(0), "another-redirect")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "trace request without propagation"() {
|
||||
setup:
|
||||
HttpGet request = new HttpGet(successUrl)
|
||||
request.addHeader(new BasicHeader("is-dd-server", "false"))
|
||||
|
||||
when:
|
||||
HttpResponse response = client.execute(request)
|
||||
|
||||
then:
|
||||
response.getStatusLine().getStatusCode() == 200
|
||||
// only one trace (client).
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 2) {
|
||||
clientParentSpan(it, 0)
|
||||
successClientSpan(it, 1, span(0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def serverTrace(ListWriterAssert writer, int index, DDSpan parent) {
|
||||
writer.trace(index, 1) {
|
||||
span(0) {
|
||||
childOf TEST_WRITER[1][2]
|
||||
childOf parent
|
||||
serviceName "unnamed-java-app"
|
||||
operationName "test-http-server"
|
||||
resourceName "test-http-server"
|
||||
|
@ -60,39 +181,36 @@ class ApacheHttpClientTest extends AgentTestRunner {
|
|||
}
|
||||
}
|
||||
}
|
||||
trace(1, 3) {
|
||||
span(0) {
|
||||
}
|
||||
|
||||
def clientParentSpan(TraceAssert trace, int index, Throwable exception = null) {
|
||||
trace.span(index) {
|
||||
parent()
|
||||
serviceName "unnamed-java-app"
|
||||
operationName "someTrace"
|
||||
resourceName "someTrace"
|
||||
errored false
|
||||
tags {
|
||||
defaultTags()
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
childOf span(0)
|
||||
serviceName "unnamed-java-app"
|
||||
operationName "apache.http"
|
||||
resourceName "apache.http"
|
||||
errored false
|
||||
errored exception != null
|
||||
tags {
|
||||
defaultTags()
|
||||
"$Tags.COMPONENT.key" "apache-httpclient"
|
||||
if (exception) {
|
||||
errorTags(exception.class)
|
||||
}
|
||||
}
|
||||
span(2) {
|
||||
childOf span(1)
|
||||
}
|
||||
}
|
||||
|
||||
def successClientSpan(TraceAssert trace, int index, DDSpan parent, status = 200, route = "success") {
|
||||
trace.span(index) {
|
||||
childOf parent
|
||||
serviceName "unnamed-java-app"
|
||||
operationName "http.request"
|
||||
resourceName "GET /"
|
||||
spanType DDSpanTypes.HTTP_CLIENT
|
||||
resourceName "GET /$route"
|
||||
errored false
|
||||
tags {
|
||||
defaultTags()
|
||||
"$Tags.HTTP_STATUS.key" 200
|
||||
"$Tags.HTTP_URL.key" "http://localhost:$port/"
|
||||
"$Tags.HTTP_STATUS.key" status
|
||||
"$Tags.HTTP_URL.key" "http://localhost:$port/$route"
|
||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||
"$Tags.PEER_PORT.key" server.getAddress().port
|
||||
"$Tags.HTTP_METHOD.key" "GET"
|
||||
|
@ -101,69 +219,8 @@ class ApacheHttpClientTest extends AgentTestRunner {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "trace request without propagation"() {
|
||||
setup:
|
||||
final HttpClientBuilder builder = HttpClientBuilder.create()
|
||||
|
||||
final HttpClient client = builder.build()
|
||||
runUnderTrace("someTrace") {
|
||||
try {
|
||||
HttpGet request = new HttpGet(server.getAddress())
|
||||
request.addHeader(new BasicHeader("is-dd-server", "false"))
|
||||
HttpResponse response = client.execute(request)
|
||||
assert response.getStatusLine().getStatusCode() == 200
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace()
|
||||
throw new RuntimeException(e)
|
||||
}
|
||||
}
|
||||
expect:
|
||||
// only one trace (client).
|
||||
assertTraces(TEST_WRITER, 1) {
|
||||
trace(0, 3) {
|
||||
span(0) {
|
||||
parent()
|
||||
serviceName "unnamed-java-app"
|
||||
operationName "someTrace"
|
||||
resourceName "someTrace"
|
||||
errored false
|
||||
tags {
|
||||
defaultTags()
|
||||
}
|
||||
}
|
||||
span(1) {
|
||||
childOf span(0)
|
||||
serviceName "unnamed-java-app"
|
||||
operationName "apache.http"
|
||||
resourceName "apache.http"
|
||||
errored false
|
||||
tags {
|
||||
defaultTags()
|
||||
"$Tags.COMPONENT.key" "apache-httpclient"
|
||||
}
|
||||
}
|
||||
span(2) {
|
||||
childOf span(1)
|
||||
serviceName "unnamed-java-app"
|
||||
operationName "http.request"
|
||||
resourceName "GET /"
|
||||
spanType DDSpanTypes.HTTP_CLIENT
|
||||
errored false
|
||||
tags {
|
||||
defaultTags()
|
||||
"$Tags.HTTP_STATUS.key" 200
|
||||
"$Tags.HTTP_URL.key" "http://localhost:$port/"
|
||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||
"$Tags.PEER_PORT.key" server.getAddress().port
|
||||
"$Tags.HTTP_METHOD.key" "GET"
|
||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
|
||||
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_CLIENT
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
def redirectClientSpan(TraceAssert trace, int index, DDSpan parent, route = "redirect") {
|
||||
successClientSpan(trace, index, parent, 302, route)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package datadog.trace.instrumentation.classloaders;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import datadog.opentracing.DDTracer;
|
||||
|
@ -28,12 +27,12 @@ public final class ClassLoaderInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return isSubTypeOf(ClassLoader.class);
|
||||
return safeHasSuperType(named("java.lang.ClassLoader"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(isConstructor(), ClassloaderAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public class Elasticsearch2TransportClientInstrumentation extends Instrumenter.D
|
|||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
// If we want to be more generic, we could instrument the interface instead:
|
||||
// .and(hasSuperType(named("org.elasticsearch.client.ElasticsearchClient"))))
|
||||
// .and(safeHasSuperType(named("org.elasticsearch.client.ElasticsearchClient"))))
|
||||
return not(isInterface()).and(named("org.elasticsearch.client.support.AbstractClient"));
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ public class Elasticsearch5TransportClientInstrumentation extends Instrumenter.D
|
|||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
// If we want to be more generic, we could instrument the interface instead:
|
||||
// .and(hasSuperType(named("org.elasticsearch.client.ElasticsearchClient"))))
|
||||
// .and(safeHasSuperType(named("org.elasticsearch.client.ElasticsearchClient"))))
|
||||
return not(isInterface()).and(named("org.elasticsearch.client.support.AbstractClient"));
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ public class Elasticsearch6TransportClientInstrumentation extends Instrumenter.D
|
|||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
// If we want to be more generic, we could instrument the interface instead:
|
||||
// .and(hasSuperType(named("org.elasticsearch.client.ElasticsearchClient"))))
|
||||
// .and(safeHasSuperType(named("org.elasticsearch.client.ElasticsearchClient"))))
|
||||
return not(isInterface()).and(named("org.elasticsearch.client.support.AbstractClient"));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package datadog.trace.instrumentation.http_url_connection;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.not;
|
||||
|
@ -43,7 +43,7 @@ public class HttpUrlConnectionInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return isSubTypeOf(HttpURLConnection.class)
|
||||
return safeHasSuperType(named("java.net.HttpURLConnection"))
|
||||
// This class is a simple delegator. Skip because it does not update its `connected` field.
|
||||
.and(not(named("sun.net.www.protocol.https.HttpsURLConnectionImpl")));
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public class HttpUrlConnectionInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
|
@ -177,7 +177,7 @@ public class HttpUrlConnectionInstrumentation extends Instrumenter.Default {
|
|||
private static final Map<HttpURLConnection, HttpURLState> STATE_MAP =
|
||||
Collections.synchronizedMap(new WeakHashMap<HttpURLConnection, HttpURLState>());
|
||||
|
||||
public static HttpURLState get(HttpURLConnection connection) {
|
||||
public static HttpURLState get(final HttpURLConnection connection) {
|
||||
HttpURLState state = STATE_MAP.get(connection);
|
||||
if (state == null) {
|
||||
// not thread-safe, but neither is HttpURLConnection
|
||||
|
@ -195,8 +195,8 @@ public class HttpUrlConnectionInstrumentation extends Instrumenter.Default {
|
|||
return hasDoneIO;
|
||||
}
|
||||
|
||||
public void setHasDoneIO(boolean value) {
|
||||
this.hasDoneIO = value;
|
||||
public void setHasDoneIO(final boolean value) {
|
||||
hasDoneIO = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package datadog.trace.instrumentation.hystrix;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -31,7 +31,7 @@ public class HystrixCommandInstrumentation extends Instrumenter.Default {
|
|||
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")));
|
||||
return not(isInterface()).and(safeHasSuperType(named("com.netflix.hystrix.HystrixCommand")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package datadog.trace.instrumentation.java.concurrent;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.nameMatches;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -95,7 +95,7 @@ public final class ExecutorInstrumentation extends Instrumenter.Default {
|
|||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface())
|
||||
.and(hasSuperType(named(Executor.class.getName())))
|
||||
.and(safeHasSuperType(named(Executor.class.getName())))
|
||||
.and(
|
||||
new ElementMatcher<TypeDescription>() {
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package datadog.trace.instrumentation.java.concurrent;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.not;
|
||||
|
@ -70,7 +70,7 @@ public final class FutureInstrumentation extends Instrumenter.Default {
|
|||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface())
|
||||
.and(hasSuperType(named(Future.class.getName())))
|
||||
.and(safeHasSuperType(named(Future.class.getName())))
|
||||
.and(
|
||||
new ElementMatcher<TypeDescription>() {
|
||||
@Override
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package datadog.trace.instrumentation.jaxrs;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
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.isAnnotatedWith;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
||||
|
@ -31,16 +30,14 @@ public final class JaxRsAnnotationsInstrumentation extends Instrumenter.Default
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return hasSuperType(
|
||||
return safeHasSuperType(
|
||||
isAnnotatedWith(named("javax.ws.rs.Path"))
|
||||
.or(
|
||||
failSafe(
|
||||
hasSuperType(declaresMethod(isAnnotatedWith(named("javax.ws.rs.Path")))))));
|
||||
.or(safeHasSuperType(declaresMethod(isAnnotatedWith(named("javax.ws.rs.Path"))))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isAnnotatedWith(
|
||||
named("javax.ws.rs.Path")
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package datadog.trace.instrumentation.jaxrs;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.failSafe;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||
|
||||
|
@ -22,7 +21,7 @@ public final class JaxRsClientInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return failSafe(hasSuperType(named("javax.ws.rs.client.ClientBuilder")));
|
||||
return safeHasSuperType(named("javax.ws.rs.client.ClientBuilder"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -38,7 +37,7 @@ public final class JaxRsClientInstrumentation extends Instrumenter.Default {
|
|||
public Map<ElementMatcher, String> transformers() {
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("build").and(returns(hasSuperType(named("javax.ws.rs.client.Client")))),
|
||||
named("build").and(returns(safeHasSuperType(named("javax.ws.rs.client.Client")))),
|
||||
ClientBuilderAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package datadog.trace.instrumentation.jdbc;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.failSafe;
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.not;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
@ -11,7 +11,6 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
|||
import com.google.auto.service.AutoService;
|
||||
import datadog.trace.agent.tooling.Instrumenter;
|
||||
import datadog.trace.bootstrap.JDBCMaps;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -27,12 +26,12 @@ public final class ConnectionInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(isSubTypeOf(Connection.class)));
|
||||
return not(isInterface()).and(safeHasSuperType(named("java.sql.Connection")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
nameStartsWith("prepare")
|
||||
.and(takesArgument(0, String.class))
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package datadog.trace.instrumentation.jdbc;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.not;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
|
||||
|
@ -36,7 +37,7 @@ public final class PreparedStatementInstrumentation extends Instrumenter.Default
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(isSubTypeOf(PreparedStatement.class));
|
||||
return not(isInterface()).and(safeHasSuperType(named("java.sql.PreparedStatement")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package datadog.trace.instrumentation.jdbc;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isSubTypeOf;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.not;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
||||
|
@ -37,7 +38,7 @@ public final class StatementInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(isSubTypeOf(Statement.class));
|
||||
return not(isInterface()).and(safeHasSuperType(named("java.sql.Statement")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package datadog.trace.instrumentation.jetty8;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -30,7 +30,7 @@ public final class HandlerInstrumentation extends Instrumenter.Default {
|
|||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface())
|
||||
.and(hasSuperType(named("org.eclipse.jetty.server.Handler")))
|
||||
.and(safeHasSuperType(named("org.eclipse.jetty.server.Handler")))
|
||||
.and(not(named("org.eclipse.jetty.server.handler.HandlerWrapper")));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package datadog.trace.instrumentation.jms1;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
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.hasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -47,7 +47,7 @@ public final class JMS1MessageConsumerInstrumentation extends Instrumenter.Defau
|
|||
|
||||
@Override
|
||||
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
||||
return not(isInterface()).and(hasSuperType(named("javax.jms.MessageConsumer")));
|
||||
return not(isInterface()).and(safeHasSuperType(named("javax.jms.MessageConsumer")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -62,7 +62,7 @@ public final class JMS1MessageConsumerInstrumentation extends Instrumenter.Defau
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("receive").and(takesArguments(0).or(takesArguments(1))).and(isPublic()),
|
||||
ConsumerAdvice.class.getName());
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package datadog.trace.instrumentation.jms1;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
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;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -40,7 +39,7 @@ public final class JMS1MessageListenerInstrumentation extends Instrumenter.Defau
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.jms.MessageListener"))));
|
||||
return not(isInterface()).and(safeHasSuperType(named("javax.jms.MessageListener")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -55,7 +54,7 @@ public final class JMS1MessageListenerInstrumentation extends Instrumenter.Defau
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("onMessage").and(takesArgument(0, named("javax.jms.Message"))).and(isPublic()),
|
||||
MessageListenerAdvice.class.getName());
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package datadog.trace.instrumentation.jms1;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
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;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -40,7 +39,7 @@ public final class JMS1MessageProducerInstrumentation extends Instrumenter.Defau
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.jms.MessageProducer"))));
|
||||
return not(isInterface()).and(safeHasSuperType(named("javax.jms.MessageProducer")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -55,7 +54,7 @@ public final class JMS1MessageProducerInstrumentation extends Instrumenter.Defau
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("send").and(takesArgument(0, named("javax.jms.Message"))).and(isPublic()),
|
||||
ProducerAdvice.class.getName());
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package datadog.trace.instrumentation.jms2;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
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;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -47,7 +46,7 @@ public final class JMS2MessageConsumerInstrumentation extends Instrumenter.Defau
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.jms.MessageConsumer"))));
|
||||
return not(isInterface()).and(safeHasSuperType(named("javax.jms.MessageConsumer")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -62,7 +61,7 @@ public final class JMS2MessageConsumerInstrumentation extends Instrumenter.Defau
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("receive").and(takesArguments(0).or(takesArguments(1))).and(isPublic()),
|
||||
ConsumerAdvice.class.getName());
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package datadog.trace.instrumentation.jms2;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
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;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -40,7 +39,7 @@ public final class JMS2MessageListenerInstrumentation extends Instrumenter.Defau
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.jms.MessageListener"))));
|
||||
return not(isInterface()).and(safeHasSuperType(named("javax.jms.MessageListener")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -55,7 +54,7 @@ public final class JMS2MessageListenerInstrumentation extends Instrumenter.Defau
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("onMessage").and(takesArgument(0, named("javax.jms.Message"))).and(isPublic()),
|
||||
MessageListenerAdvice.class.getName());
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package datadog.trace.instrumentation.jms2;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
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;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -40,7 +39,7 @@ public final class JMS2MessageProducerInstrumentation extends Instrumenter.Defau
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.jms.MessageProducer"))));
|
||||
return not(isInterface()).and(safeHasSuperType(named("javax.jms.MessageProducer")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -55,7 +54,7 @@ public final class JMS2MessageProducerInstrumentation extends Instrumenter.Defau
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("send").and(takesArgument(0, named("javax.jms.Message"))).and(isPublic()),
|
||||
ProducerAdvice.class.getName());
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package datadog.trace.instrumentation.jsp;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -39,12 +39,12 @@ public final class JSPInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(hasSuperType(named("javax.servlet.jsp.HttpJspPage")));
|
||||
return not(isInterface()).and(safeHasSuperType(named("javax.servlet.jsp.HttpJspPage")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("_jspService")
|
||||
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest")))
|
||||
|
@ -68,14 +68,14 @@ public final class JSPInstrumentation extends Instrumenter.Default {
|
|||
|
||||
final Span span = scope.span();
|
||||
// get the JSP file name being rendered in an include action
|
||||
Object includeServletPath = req.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);
|
||||
final Object includeServletPath = req.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);
|
||||
String resourceName = req.getServletPath();
|
||||
if (includeServletPath != null && includeServletPath instanceof String) {
|
||||
resourceName = includeServletPath.toString();
|
||||
}
|
||||
span.setTag(DDTags.RESOURCE_NAME, resourceName);
|
||||
|
||||
Object forwardOrigin = req.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH);
|
||||
final Object forwardOrigin = req.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH);
|
||||
if (forwardOrigin != null && forwardOrigin instanceof String) {
|
||||
span.setTag("jsp.forwardOrigin", forwardOrigin.toString());
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package datadog.trace.instrumentation.netty40;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
||||
|
@ -48,7 +48,7 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(hasSuperType(named("io.netty.channel.ChannelPipeline")));
|
||||
return not(isInterface()).and(safeHasSuperType(named("io.netty.channel.ChannelPipeline")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -99,7 +99,9 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default {
|
|||
@Advice.Enter final int depth,
|
||||
@Advice.This final ChannelPipeline pipeline,
|
||||
@Advice.Argument(2) final ChannelHandler handler) {
|
||||
if (depth > 0) return;
|
||||
if (depth > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Server pipeline handlers
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package datadog.trace.instrumentation.netty41;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
||||
|
@ -48,7 +48,7 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(hasSuperType(named("io.netty.channel.ChannelPipeline")));
|
||||
return not(isInterface()).and(safeHasSuperType(named("io.netty.channel.ChannelPipeline")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -99,7 +99,9 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default {
|
|||
@Advice.Enter final int depth,
|
||||
@Advice.This final ChannelPipeline pipeline,
|
||||
@Advice.Argument(2) final ChannelHandler handler) {
|
||||
if (depth > 0) return;
|
||||
if (depth > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Server pipeline handlers
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package datadog.trace.instrumentation.play;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClassWithMethod;
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
@ -46,7 +46,7 @@ public final class PlayInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return hasSuperType(named("play.api.mvc.Action"));
|
||||
return safeHasSuperType(named("play.api.mvc.Action"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package datadog.trace.instrumentation.ratpack;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
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;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.not;
|
||||
|
@ -35,7 +35,7 @@ public final class RatpackHttpClientInstrumentation extends Instrumenter.Default
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(hasSuperType(named("ratpack.http.client.HttpClient")));
|
||||
return not(isInterface()).and(safeHasSuperType(named("ratpack.http.client.HttpClient")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -63,7 +63,7 @@ public final class RatpackHttpClientInstrumentation extends Instrumenter.Default
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
named("request")
|
||||
.and(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package datadog.trace.instrumentation.ratpack;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClassWithMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isStatic;
|
||||
|
@ -91,7 +91,7 @@ public final class RatpackInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(hasSuperType(named("ratpack.exec.ExecStarter")));
|
||||
return not(isInterface()).and(safeHasSuperType(named("ratpack.exec.ExecStarter")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -136,7 +136,7 @@ public final class RatpackInstrumentation extends Instrumenter.Default {
|
|||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return named("ratpack.exec.Execution")
|
||||
.or(not(isInterface()).and(hasSuperType(named("ratpack.exec.Execution"))));
|
||||
.or(not(isInterface()).and(safeHasSuperType(named("ratpack.exec.Execution"))));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package datadog.trace.instrumentation.servlet2;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
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;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -24,7 +23,7 @@ public final class FilterChain2Instrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.servlet.FilterChain"))));
|
||||
return not(isInterface()).and(safeHasSuperType(named("javax.servlet.FilterChain")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package datadog.trace.instrumentation.servlet2;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
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.isProtected;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -29,7 +28,7 @@ public final class HttpServlet2Instrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.servlet.http.HttpServlet"))));
|
||||
return not(isInterface()).and(safeHasSuperType(named("javax.servlet.http.HttpServlet")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package datadog.trace.instrumentation.servlet3;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClasses;
|
||||
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;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -22,7 +21,7 @@ public class AbstractServlet3Instrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.servlet.FilterChain"))));
|
||||
return not(isInterface()).and(safeHasSuperType(named("javax.servlet.FilterChain")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package datadog.trace.instrumentation.servlet3;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.failSafe;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -19,7 +18,7 @@ public final class FilterChain3Instrumentation extends AbstractServlet3Instrumen
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.servlet.FilterChain"))));
|
||||
return not(isInterface()).and(safeHasSuperType(named("javax.servlet.FilterChain")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package datadog.trace.instrumentation.servlet3;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.failSafe;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isProtected;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -19,7 +18,7 @@ public final class HttpServlet3Instrumentation extends AbstractServlet3Instrumen
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface()).and(failSafe(hasSuperType(named("javax.servlet.http.HttpServlet"))));
|
||||
return not(isInterface()).and(safeHasSuperType(named("javax.servlet.http.HttpServlet")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package datadog.trace.instrumentation.springweb;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasClassWithField;
|
||||
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.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isProtected;
|
||||
|
@ -39,7 +38,7 @@ public final class SpringWebInstrumentation extends Instrumenter.Default {
|
|||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return not(isInterface())
|
||||
.and(failSafe(hasSuperType(named("org.springframework.web.servlet.HandlerAdapter"))));
|
||||
.and(safeHasSuperType(named("org.springframework.web.servlet.HandlerAdapter")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -50,7 +49,7 @@ public final class SpringWebInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isPublic())
|
||||
|
@ -74,7 +73,7 @@ public final class SpringWebInstrumentation extends Instrumenter.Default {
|
|||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(
|
||||
isMethod()
|
||||
.and(isProtected())
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package datadog.trace.instrumentation.trace_annotation;
|
||||
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
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.hasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.is;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
@ -79,12 +79,12 @@ public final class TraceAnnotationsInstrumentation extends Instrumenter.Default
|
|||
|
||||
@Override
|
||||
public ElementMatcher typeMatcher() {
|
||||
return hasSuperType(declaresMethod(isAnnotatedWith(methodTraceMatcher)));
|
||||
return safeHasSuperType(declaresMethod(isAnnotatedWith(methodTraceMatcher)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ElementMatcher, String> transformers() {
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(isAnnotatedWith(methodTraceMatcher), TraceAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package datadog.trace.instrumentation.trace_annotation;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
|
||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
|
@ -92,7 +92,7 @@ public class TraceConfigInstrumentation implements Instrumenter {
|
|||
}
|
||||
|
||||
for (final Map.Entry<String, Set<String>> entry : classMethodsToTrace.entrySet()) {
|
||||
TracerClassInstrumentation tracerConfigClass =
|
||||
final TracerClassInstrumentation tracerConfigClass =
|
||||
new TracerClassInstrumentation(entry.getKey(), entry.getValue());
|
||||
agentBuilder = tracerConfigClass.instrument(agentBuilder);
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ public class TraceConfigInstrumentation implements Instrumenter {
|
|||
this("noop", Collections.singleton("noop"));
|
||||
}
|
||||
|
||||
public TracerClassInstrumentation(String className, Set<String> methodNames) {
|
||||
public TracerClassInstrumentation(final String className, final Set<String> methodNames) {
|
||||
super("trace", "trace-config");
|
||||
this.className = className;
|
||||
this.methodNames = methodNames;
|
||||
|
@ -117,7 +117,7 @@ public class TraceConfigInstrumentation implements Instrumenter {
|
|||
|
||||
@Override
|
||||
public ElementMatcher<? super TypeDescription> typeMatcher() {
|
||||
return hasSuperType(named(className));
|
||||
return safeHasSuperType(named(className));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -131,7 +131,7 @@ public class TraceConfigInstrumentation implements Instrumenter {
|
|||
}
|
||||
}
|
||||
|
||||
Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
final Map<ElementMatcher, String> transformers = new HashMap<>();
|
||||
transformers.put(methodMatchers, TraceAdvice.class.getName());
|
||||
return transformers;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue