Cache element matchers
The effect is mostly notable on class loader matchers.
Previously, a new matcher was created for every loaded class.
Class loader matchers have an internal cache which is now actually used.
@@ -36,6 +36,7 @@ import net.bytebuddy.ByteBuddy;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.agent.builder.ResettableClassFileTransformer;
import net.bytebuddy.asm.Advice;
+import net.bytebuddy.description.NamedElement;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
@@ -164,28 +165,32 @@ public class ElasticApmAgent {
logger.debug("Applying advice {}", advice.getClass().getName());
advice.init(tracer);
final boolean typeMatchingWithNamePreFilter = tracer.getConfig(CoreConfiguration.class).isTypeMatchingWithNamePreFilter();
+ final ElementMatcher.Junction<ClassLoader> classLoaderMatcher = advice.getClassLoaderMatcher();
+ final ElementMatcher<? super NamedElement> typeMatcherPreFilter = advice.getTypeMatcherPreFilter();
+ final ElementMatcher<? super TypeDescription> typeMatcher = advice.getTypeMatcher();
+ final ElementMatcher<? super MethodDescription> methodMatcher = advice.getMethodMatcher();
return agentBuilder
.type(new AgentBuilder.RawMatcher() {
@Override
public boolean matches(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, Class<?> classBeingRedefined, ProtectionDomain protectionDomain) {
long start = System.nanoTime();
try {
- if (!advice.getClassLoaderMatcher().matches(classLoader)) {
+ if (!classLoaderMatcher.matches(classLoader)) {
return false;
}
- if (typeMatchingWithNamePreFilter && !advice.getTypeMatcherPreFilter().matches(typeDescription)) {
+ if (typeMatchingWithNamePreFilter && !typeMatcherPreFilter.matches(typeDescription)) {
return false;
}
boolean typeMatches;
try {
- typeMatches = advice.getTypeMatcher().matches(typeDescription);
+ typeMatches = typeMatcher.matches(typeDescription);
} catch (Exception ignored) {
// could be because of a missing type
typeMatches = false;
}
if (typeMatches) {
logger.debug("Type match for advice {}: {} matches {}",
- advice.getClass().getSimpleName(), advice.getTypeMatcher(), typeDescription);
+ advice.getClass().getSimpleName(), typeMatcher, typeDescription);
if (logger.isTraceEnabled()) {
logClassLoaderHierarchy(classLoader, logger, advice);
}
@@ -207,14 +212,14 @@ public class ElasticApmAgent {
try {
boolean matches;
try {
- matches = advice.getMethodMatcher().matches(target);
+ matches = methodMatcher.matches(target);
} catch (Exception ignored) {
// could be because of a missing type
matches = false;
}
if (matches) {
logger.debug("Method match for advice {}: {} matches {}",
- advice.getClass().getSimpleName(), advice.getMethodMatcher(), target);
+ advice.getClass().getSimpleName(), methodMatcher, target);
}
return matches;
} finally {
@@ -321,6 +326,7 @@ public class ElasticApmAgent {
not(nameEndsWith("URLConnection"))
)
)
+ .or(nameStartsWith("co.elastic.apm.agent.shaded"))
.or(nameStartsWith("org.aspectj."))
.or(nameStartsWith("org.groovy."))
.or(nameStartsWith("com.p6spy."))
