Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@Slf4j
public final class ClassLoaderMatcher {
public static final ClassLoader BOOTSTRAP_CLASSLOADER = null;
public static final int CACHE_MAX_SIZE = 25; // limit number of cached responses for each matcher.
public static final int CACHE_CONCURRENCY =
Math.max(8, Runtime.getRuntime().availableProcessors());

Expand All @@ -20,9 +21,16 @@ public static ElementMatcher.Junction.AbstractBase<ClassLoader> skipClassLoader(
return SkipClassLoaderMatcher.INSTANCE;
}

public static ElementMatcher.Junction.AbstractBase<ClassLoader> classLoaderHasNoResources(
final String... resources) {
return new ClassLoaderHasNoResourceMatcher(resources);
/**
* NOTICE: Does not match the bootstrap classpath. Don't use with classes expected to be on the
* bootstrap.
*
* @param classNames list of names to match. returns true if empty.
* @return true if class is available as a resource and not the bootstrap classloader.
*/
public static ElementMatcher.Junction.AbstractBase<ClassLoader> hasClassesNamed(
final String... classNames) {
return new ClassLoaderHasClassesNamedMatcher(classNames);
}

private static final class SkipClassLoaderMatcher
Expand Down Expand Up @@ -57,38 +65,47 @@ private static boolean shouldSkipClass(final ClassLoader loader) {
}
}

private static class ClassLoaderHasNoResourceMatcher
private static class ClassLoaderHasClassesNamedMatcher
extends ElementMatcher.Junction.AbstractBase<ClassLoader> {

private final Cache<ClassLoader, Boolean> cache =
CacheBuilder.newBuilder().weakKeys().concurrencyLevel(CACHE_CONCURRENCY).build();
CacheBuilder.newBuilder()
.weakKeys()
.maximumSize(CACHE_MAX_SIZE)
.concurrencyLevel(CACHE_CONCURRENCY)
.build();

private final String[] resources;

private ClassLoaderHasNoResourceMatcher(final String... resources) {
this.resources = resources;
private ClassLoaderHasClassesNamedMatcher(final String... classNames) {
resources = classNames;
for (int i = 0; i < resources.length; i++) {
resources[i] = resources[i].replace(".", "/") + ".class";
}
}

private boolean hasNoResources(final ClassLoader cl) {
private boolean hasResources(final ClassLoader cl) {
for (final String resource : resources) {
if (cl.getResource(resource) == null) {
return true;
return false;
}
}
return false;
return true;
}

@Override
public boolean matches(final ClassLoader cl) {
if (cl == null) {
if (cl == BOOTSTRAP_CLASSLOADER) {
// Can't match the bootstrap classloader.
return false;
}
Boolean v = cache.getIfPresent(cl);
if (v != null) {
return v;
final Boolean cached;
if ((cached = cache.getIfPresent(cl)) != null) {
return cached;
}
v = hasNoResources(cl);
cache.put(cl, v);
return v;
final boolean value = hasResources(cl);
cache.put(cl, value);
return value;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package datadog.trace.instrumentation.apachehttpasyncclient;

import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.implementsInterface;
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeScope;
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.propagate;
Expand All @@ -10,7 +10,6 @@
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;

Expand Down Expand Up @@ -43,7 +42,7 @@ public ApacheHttpAsyncClientInstrumentation() {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("org/apache/http/nio/client/HttpAsyncClient.class"));
return hasClassesNamed("org.apache.http.nio.client.HttpAsyncClient");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package datadog.trace.instrumentation.apachehttpasyncclient;

import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.implementsInterface;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;

import com.google.auto.service.AutoService;
Expand Down Expand Up @@ -34,7 +33,7 @@ public ApacheHttpClientRedirectInstrumentation() {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("org/apache/http/client/RedirectStrategy.class"));
return hasClassesNamed("org.apache.http.client.RedirectStrategy");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package datadog.trace.instrumentation.apachehttpclient;

import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.implementsInterface;
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan;
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.propagate;
Expand Down Expand Up @@ -45,7 +45,7 @@ public ApacheHttpClientInstrumentation() {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("org/apache/http/client/HttpClient.class"));
return hasClassesNamed("org.apache.http.client.HttpClient");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package datadog.trace.instrumentation.aws.v0;

import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.extendsClass;
import static java.util.Collections.singletonMap;
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;

import com.amazonaws.AmazonWebServiceRequest;
Expand All @@ -30,7 +29,7 @@ public RequestInstrumentation() {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("com/amazonaws/AmazonWebServiceRequest.class"));
return hasClassesNamed("com.amazonaws.AmazonWebServiceRequest");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package datadog.trace.instrumentation.aws.v2;

import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.implementsInterface;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
Expand All @@ -20,6 +21,12 @@
@AutoService(Instrumenter.class)
public final class AwsClientInstrumentation extends AbstractAwsClientInstrumentation {

@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return hasClassesNamed("software.amazon.awssdk.core.client.builder.SdkClientBuilder");
}

@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return nameStartsWith("software.amazon.awssdk.")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package datadog.trace.instrumentation.aws.v2;

import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.extendsClass;
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeScope;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
Expand All @@ -25,6 +26,13 @@
@AutoService(Instrumenter.class)
public final class AwsHttpClientInstrumentation extends AbstractAwsClientInstrumentation {

@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return hasClassesNamed(
"software.amazon.awssdk.core.internal.http.pipeline.stages.MakeHttpRequestStage");
}

@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return nameStartsWith("software.amazon.awssdk.")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package datadog.trace.instrumentation.couchbase.client;

import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.extendsClass;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
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;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;

Expand Down Expand Up @@ -34,9 +33,7 @@ public CouchbaseNetworkInstrumentation() {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(
classLoaderHasNoResources(
"com/couchbase/client/core/endpoint/AbstractGenericHandler.class"));
return hasClassesNamed("com.couchbase.client.core.endpoint.AbstractGenericHandler");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package datadog.trace.instrumentation.dropwizard.view;

import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.implementsInterface;
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan;
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan;
Expand All @@ -9,7 +9,6 @@
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;

import com.google.auto.service.AutoService;
Expand All @@ -35,7 +34,7 @@ public DropwizardViewInstrumentation() {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("io/dropwizard/views/ViewRenderer.class"));
return hasClassesNamed("io.dropwizard.views.ViewRenderer");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package datadog.trace.instrumentation.finatra;

import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.extendsClass;
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan;
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan;
Expand All @@ -10,7 +10,6 @@
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
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;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;

Expand Down Expand Up @@ -53,7 +52,7 @@ public String[] helperClassNames() {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("com/twitter/finatra/http/internal/routing/Route.class"));
return hasClassesNamed("com.twitter.finatra.http.internal.routing.Route");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package datadog.trace.instrumentation.hibernate.core.v3_3;

import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed;

import datadog.trace.agent.tooling.Instrumenter;
import net.bytebuddy.matcher.ElementMatcher;
Expand All @@ -17,7 +16,7 @@ public AbstractHibernateInstrumentation() {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("org/hibernate/Session.class"));
return hasClassesNamed("org.hibernate.Session");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package datadog.trace.instrumentation.hibernate.core.v4_0;

import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed;

import datadog.trace.agent.tooling.Instrumenter;
import net.bytebuddy.matcher.ElementMatcher;
Expand All @@ -16,7 +15,7 @@ public AbstractHibernateInstrumentation() {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("org/hibernate/Session.class"));
return hasClassesNamed("org.hibernate.Session");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package datadog.trace.instrumentation.hibernate.core.v4_3;

import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.implementsInterface;
import static java.util.Collections.singletonMap;
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;
Expand Down Expand Up @@ -48,7 +47,7 @@ public String[] helperClassNames() {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("org/hibernate/Session.class"));
return hasClassesNamed("org.hibernate.Session");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package datadog.trace.instrumentation.hibernate.core.v4_3;

import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.hasInterface;
import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.implementsInterface;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.returns;

import com.google.auto.service.AutoService;
Expand Down Expand Up @@ -55,7 +54,7 @@ public String[] helperClassNames() {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("org/hibernate/Session.class"));
return hasClassesNamed("org.hibernate.Session");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package datadog.trace.instrumentation.hystrix;

import static datadog.trace.agent.tooling.ClassLoaderMatcher.classLoaderHasNoResources;
import static datadog.trace.agent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.extendsClass;
import static datadog.trace.instrumentation.hystrix.HystrixDecorator.DECORATE;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.returns;

import com.google.auto.service.AutoService;
Expand Down Expand Up @@ -32,7 +31,7 @@ public HystrixInstrumentation() {
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("com/netflix/hystrix/HystrixCommand.class"));
return hasClassesNamed("com.netflix.hystrix.HystrixCommand");
}

@Override
Expand Down
Loading