Generate InstrumentationModule#contextStore() with muzzle (#2775)

This commit is contained in:
Mateusz Rzeszutek 2021-04-14 05:05:01 +02:00 committed by GitHub
parent 06832d84fc
commit 078603caf5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 283 additions and 362 deletions

View File

@ -8,14 +8,9 @@ package io.opentelemetry.javaagent.instrumentation.akkaactor;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.instrumentation.api.concurrent.State;
import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
public class AkkaActorInstrumentationModule extends InstrumentationModule { public class AkkaActorInstrumentationModule extends InstrumentationModule {
@ -32,16 +27,6 @@ public class AkkaActorInstrumentationModule extends InstrumentationModule {
new AkkaActorCellInstrumentation()); new AkkaActorCellInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
Map<String, String> map = new HashMap<>();
map.put(Runnable.class.getName(), State.class.getName());
map.put(Callable.class.getName(), State.class.getName());
map.put(AkkaForkJoinTaskInstrumentation.TASK_CLASS_NAME, State.class.getName());
map.put("akka.dispatch.Envelope", State.class.getName());
return Collections.unmodifiableMap(map);
}
@Override @Override
protected boolean defaultEnabled() { protected boolean defaultEnabled() {
return false; return false;

View File

@ -6,13 +6,10 @@
package io.opentelemetry.javaagent.instrumentation.asynchttpclient; package io.opentelemetry.javaagent.instrumentation.asynchttpclient;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.Collections.singletonMap;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.instrumentation.api.Pair;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List; import java.util.List;
import java.util.Map;
@AutoService(io.opentelemetry.javaagent.tooling.InstrumentationModule.class) @AutoService(io.opentelemetry.javaagent.tooling.InstrumentationModule.class)
public class AsyncHttpClientInstrumentationModule public class AsyncHttpClientInstrumentationModule
@ -25,9 +22,4 @@ public class AsyncHttpClientInstrumentationModule
public List<TypeInstrumentation> typeInstrumentations() { public List<TypeInstrumentation> typeInstrumentations() {
return asList(new RequestInstrumentation(), new ResponseInstrumentation()); return asList(new RequestInstrumentation(), new ResponseInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
return singletonMap("com.ning.http.client.AsyncHandler", Pair.class.getName());
}
} }

View File

@ -8,11 +8,8 @@ package io.opentelemetry.javaagent.instrumentation.asynchttpclient;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.context.Context;
import io.opentelemetry.javaagent.instrumentation.api.Pair;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List; import java.util.List;
import java.util.Map;
@AutoService(io.opentelemetry.javaagent.tooling.InstrumentationModule.class) @AutoService(io.opentelemetry.javaagent.tooling.InstrumentationModule.class)
public class AsyncHttpClientInstrumentationModule public class AsyncHttpClientInstrumentationModule
@ -28,12 +25,4 @@ public class AsyncHttpClientInstrumentationModule
new ResponseInstrumentation(), new ResponseInstrumentation(),
new RequestSenderInstrumentation()); new RequestSenderInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
Map<String, String> stores = new java.util.HashMap<>();
stores.put("org.asynchttpclient.AsyncHandler", Pair.class.getName());
stores.put("org.asynchttpclient.Request", Context.class.getName());
return stores;
}
} }

View File

@ -6,14 +6,11 @@
package io.opentelemetry.javaagent.instrumentation.couchbase.v2_6; package io.opentelemetry.javaagent.instrumentation.couchbase.v2_6;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.Collections.singletonMap;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List; import java.util.List;
import java.util.Map;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
public class CouchbaseInstrumentationModule extends InstrumentationModule { public class CouchbaseInstrumentationModule extends InstrumentationModule {
@ -25,9 +22,4 @@ public class CouchbaseInstrumentationModule extends InstrumentationModule {
public List<TypeInstrumentation> typeInstrumentations() { public List<TypeInstrumentation> typeInstrumentations() {
return asList(new CouchbaseCoreInstrumentation(), new CouchbaseNetworkInstrumentation()); return asList(new CouchbaseCoreInstrumentation(), new CouchbaseNetworkInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
return singletonMap("com.couchbase.client.core.message.CouchbaseRequest", Span.class.getName());
}
} }

View File

@ -8,16 +8,9 @@ package io.opentelemetry.javaagent.instrumentation.javaconcurrent;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.instrumentation.api.concurrent.State;
import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.Future;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
public class ExecutorInstrumentationModule extends InstrumentationModule { public class ExecutorInstrumentationModule extends InstrumentationModule {
@ -34,14 +27,4 @@ public class ExecutorInstrumentationModule extends InstrumentationModule {
new JavaForkJoinTaskInstrumentation(), new JavaForkJoinTaskInstrumentation(),
new RunnableInstrumentation()); new RunnableInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
Map<String, String> map = new HashMap<>();
map.put(Callable.class.getName(), State.class.getName());
map.put(ForkJoinTask.class.getName(), State.class.getName());
map.put(Future.class.getName(), State.class.getName());
map.put(Runnable.class.getName(), State.class.getName());
return Collections.unmodifiableMap(map);
}
} }

View File

@ -8,7 +8,6 @@ package io.opentelemetry.javaagent.instrumentation.googlehttpclient;
import static io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge.currentContext; import static io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge.currentContext;
import static io.opentelemetry.javaagent.instrumentation.googlehttpclient.GoogleHttpClientTracer.tracer; import static io.opentelemetry.javaagent.instrumentation.googlehttpclient.GoogleHttpClientTracer.tracer;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.isPublic; import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
@ -38,11 +37,6 @@ public class GoogleHttpClientInstrumentationModule extends InstrumentationModule
super("google-http-client", "google-http-client-1.19"); super("google-http-client", "google-http-client-1.19");
} }
@Override
public Map<String, String> contextStore() {
return singletonMap("com.google.api.client.http.HttpRequest", Context.class.getName());
}
@Override @Override
public List<TypeInstrumentation> typeInstrumentations() { public List<TypeInstrumentation> typeInstrumentations() {
return singletonList(new HttpRequestInstrumentation()); return singletonList(new HttpRequestInstrumentation());

View File

@ -41,11 +41,6 @@ public class GuavaInstrumentationModule extends InstrumentationModule {
return singletonList(new ListenableFutureInstrumentation()); return singletonList(new ListenableFutureInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
return singletonMap(Runnable.class.getName(), State.class.getName());
}
public static class ListenableFutureInstrumentation implements TypeInstrumentation { public static class ListenableFutureInstrumentation implements TypeInstrumentation {
@Override @Override
public ElementMatcher<TypeDescription> typeMatcher() { public ElementMatcher<TypeDescription> typeMatcher() {

View File

@ -9,13 +9,9 @@ import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMa
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.context.Context;
import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
@ -43,15 +39,4 @@ public class HibernateInstrumentationModule extends InstrumentationModule {
new SessionInstrumentation(), new SessionInstrumentation(),
new TransactionInstrumentation()); new TransactionInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
Map<String, String> map = new HashMap<>();
map.put("org.hibernate.Criteria", Context.class.getName());
map.put("org.hibernate.Query", Context.class.getName());
map.put("org.hibernate.Session", Context.class.getName());
map.put("org.hibernate.StatelessSession", Context.class.getName());
map.put("org.hibernate.Transaction", Context.class.getName());
return Collections.unmodifiableMap(map);
}
} }

View File

@ -8,13 +8,9 @@ package io.opentelemetry.javaagent.instrumentation.hibernate.v4_0;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.context.Context;
import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
public class HibernateInstrumentationModule extends InstrumentationModule { public class HibernateInstrumentationModule extends InstrumentationModule {
@ -32,14 +28,4 @@ public class HibernateInstrumentationModule extends InstrumentationModule {
new SessionInstrumentation(), new SessionInstrumentation(),
new TransactionInstrumentation()); new TransactionInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
Map<String, String> map = new HashMap<>();
map.put("org.hibernate.Criteria", Context.class.getName());
map.put("org.hibernate.Query", Context.class.getName());
map.put("org.hibernate.SharedSessionContract", Context.class.getName());
map.put("org.hibernate.Transaction", Context.class.getName());
return Collections.unmodifiableMap(map);
}
} }

View File

@ -8,13 +8,9 @@ package io.opentelemetry.javaagent.instrumentation.hibernate.v4_3;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.context.Context;
import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
public class HibernateInstrumentationModule extends InstrumentationModule { public class HibernateInstrumentationModule extends InstrumentationModule {
@ -26,12 +22,4 @@ public class HibernateInstrumentationModule extends InstrumentationModule {
public List<TypeInstrumentation> typeInstrumentations() { public List<TypeInstrumentation> typeInstrumentations() {
return asList(new ProcedureCallInstrumentation(), new SessionInstrumentation()); return asList(new ProcedureCallInstrumentation(), new SessionInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
Map<String, String> map = new HashMap<>();
map.put("org.hibernate.SharedSessionContract", Context.class.getName());
map.put("org.hibernate.procedure.ProcedureCall", Context.class.getName());
return Collections.unmodifiableMap(map);
}
} }

View File

@ -10,7 +10,6 @@ import static io.opentelemetry.javaagent.instrumentation.httpurlconnection.HttpU
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.isPublic; import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith; import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
@ -52,11 +51,6 @@ public class HttpUrlConnectionInstrumentationModule extends InstrumentationModul
return singletonList(new HttpUrlConnectionInstrumentation()); return singletonList(new HttpUrlConnectionInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
return singletonMap("java.net.HttpURLConnection", getClass().getName() + "$HttpUrlState");
}
public static class HttpUrlConnectionInstrumentation implements TypeInstrumentation { public static class HttpUrlConnectionInstrumentation implements TypeInstrumentation {
@Override @Override
public ElementMatcher<TypeDescription> typeMatcher() { public ElementMatcher<TypeDescription> typeMatcher() {

View File

@ -7,14 +7,11 @@ package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.Collections.singletonMap;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.context.Context;
import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List; import java.util.List;
import java.util.Map;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
@ -37,9 +34,4 @@ public class JaxRsInstrumentationModule extends InstrumentationModule {
new JaxRsAnnotationsInstrumentation(), new JaxRsAnnotationsInstrumentation(),
new JaxRsAsyncResponseInstrumentation()); new JaxRsAsyncResponseInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
return singletonMap("javax.ws.rs.container.AsyncResponse", Context.class.getName());
}
} }

View File

@ -5,7 +5,6 @@
package io.opentelemetry.javaagent.instrumentation.jetty.v8_0; package io.opentelemetry.javaagent.instrumentation.jetty.v8_0;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
@ -45,11 +44,6 @@ public class Jetty8InstrumentationModule extends InstrumentationModule {
new JettyQueuedThreadPoolInstrumentation()); new JettyQueuedThreadPoolInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
return singletonMap(Runnable.class.getName(), State.class.getName());
}
public static class JettyQueuedThreadPoolInstrumentation implements TypeInstrumentation { public static class JettyQueuedThreadPoolInstrumentation implements TypeInstrumentation {
@Override @Override

View File

@ -6,13 +6,11 @@
package io.opentelemetry.javaagent.instrumentation.jms; package io.opentelemetry.javaagent.instrumentation.jms;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.Collections.singletonMap;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List; import java.util.List;
import java.util.Map;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
public class JmsInstrumentationModule extends InstrumentationModule { public class JmsInstrumentationModule extends InstrumentationModule {
@ -27,9 +25,4 @@ public class JmsInstrumentationModule extends InstrumentationModule {
new JmsMessageListenerInstrumentation(), new JmsMessageListenerInstrumentation(),
new JmsMessageProducerInstrumentation()); new JmsMessageProducerInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
return singletonMap("javax.jms.MessageConsumer", MessageDestination.class.getName());
}
} }

View File

@ -6,14 +6,11 @@
package io.opentelemetry.javaagent.instrumentation.log4j.v1_2; package io.opentelemetry.javaagent.instrumentation.log4j.v1_2;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.Collections.singletonMap;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List; import java.util.List;
import java.util.Map;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
public class Log4j1InstrumentationModule extends InstrumentationModule { public class Log4j1InstrumentationModule extends InstrumentationModule {
@ -25,9 +22,4 @@ public class Log4j1InstrumentationModule extends InstrumentationModule {
public List<TypeInstrumentation> typeInstrumentations() { public List<TypeInstrumentation> typeInstrumentations() {
return asList(new CategoryInstrumentation(), new LoggingEventInstrumentation()); return asList(new CategoryInstrumentation(), new LoggingEventInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
return singletonMap("org.apache.log4j.spi.LoggingEvent", Span.class.getName());
}
} }

View File

@ -6,14 +6,11 @@
package io.opentelemetry.javaagent.instrumentation.logback.v1_0; package io.opentelemetry.javaagent.instrumentation.logback.v1_0;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.Collections.singletonMap;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List; import java.util.List;
import java.util.Map;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
public class LogbackInstrumentationModule extends InstrumentationModule { public class LogbackInstrumentationModule extends InstrumentationModule {
@ -25,9 +22,4 @@ public class LogbackInstrumentationModule extends InstrumentationModule {
public List<TypeInstrumentation> typeInstrumentations() { public List<TypeInstrumentation> typeInstrumentations() {
return asList(new LoggerInstrumentation(), new LoggingEventInstrumentation()); return asList(new LoggerInstrumentation(), new LoggingEventInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
return singletonMap("ch.qos.logback.classic.spi.ILoggingEvent", Span.class.getName());
}
} }

View File

@ -10,9 +10,7 @@ import static java.util.Arrays.asList;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
public class NettyInstrumentationModule extends InstrumentationModule { public class NettyInstrumentationModule extends InstrumentationModule {
@ -28,10 +26,4 @@ public class NettyInstrumentationModule extends InstrumentationModule {
new NettyChannelPipelineInstrumentation(), new NettyChannelPipelineInstrumentation(),
new DefaultChannelPipelineInstrumentation()); new DefaultChannelPipelineInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
return Collections.singletonMap(
"org.jboss.netty.channel.Channel", ChannelTraceContext.class.getName());
}
} }

View File

@ -6,7 +6,6 @@
package io.opentelemetry.javaagent.instrumentation.rmi.context; package io.opentelemetry.javaagent.instrumentation.rmi.context;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.Collections.singletonMap;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.instrumentation.rmi.context.client.RmiClientContextInstrumentation; import io.opentelemetry.javaagent.instrumentation.rmi.context.client.RmiClientContextInstrumentation;
@ -14,7 +13,6 @@ import io.opentelemetry.javaagent.instrumentation.rmi.context.server.RmiServerCo
import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List; import java.util.List;
import java.util.Map;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
public class RmiContextPropagationInstrumentationModule extends InstrumentationModule { public class RmiContextPropagationInstrumentationModule extends InstrumentationModule {
@ -26,10 +24,4 @@ public class RmiContextPropagationInstrumentationModule extends InstrumentationM
public List<TypeInstrumentation> typeInstrumentations() { public List<TypeInstrumentation> typeInstrumentations() {
return asList(new RmiClientContextInstrumentation(), new RmiServerContextInstrumentation()); return asList(new RmiClientContextInstrumentation(), new RmiServerContextInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
// caching if a connection can support enhanced format
return singletonMap("sun.rmi.transport.Connection", "java.lang.Boolean");
}
} }

View File

@ -78,6 +78,7 @@ public class RmiClientContextInstrumentation implements TypeInstrumentation {
return; return;
} }
// caching if a connection can support enhanced format
ContextStore<Connection, Boolean> knownConnections = ContextStore<Connection, Boolean> knownConnections =
InstrumentationContext.get(Connection.class, Boolean.class); InstrumentationContext.get(Connection.class, Boolean.class);

View File

@ -5,18 +5,12 @@
package io.opentelemetry.javaagent.instrumentation.scalaexecutors; package io.opentelemetry.javaagent.instrumentation.scalaexecutors;
import static io.opentelemetry.javaagent.instrumentation.scalaexecutors.ScalaForkJoinTaskInstrumentation.TASK_CLASS_NAME;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.instrumentation.api.concurrent.State;
import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
public class ScalaConcurrentInstrumentationModule extends InstrumentationModule { public class ScalaConcurrentInstrumentationModule extends InstrumentationModule {
@ -28,13 +22,4 @@ public class ScalaConcurrentInstrumentationModule extends InstrumentationModule
public List<TypeInstrumentation> typeInstrumentations() { public List<TypeInstrumentation> typeInstrumentations() {
return asList(new ScalaForkJoinPoolInstrumentation(), new ScalaForkJoinTaskInstrumentation()); return asList(new ScalaForkJoinPoolInstrumentation(), new ScalaForkJoinTaskInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
Map<String, String> map = new HashMap<>();
map.put(Runnable.class.getName(), State.class.getName());
map.put(Callable.class.getName(), State.class.getName());
map.put(TASK_CLASS_NAME, State.class.getName());
return Collections.unmodifiableMap(map);
}
} }

View File

@ -6,7 +6,6 @@
package io.opentelemetry.javaagent.instrumentation.servlet.v2_2; package io.opentelemetry.javaagent.instrumentation.servlet.v2_2;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.not; import static net.bytebuddy.matcher.ElementMatchers.not;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
@ -15,7 +14,6 @@ import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
@ -38,9 +36,4 @@ public class Servlet2InstrumentationModule extends InstrumentationModule {
"javax.servlet", "javax.servlet",
Servlet2InstrumentationModule.class.getPackage().getName() + ".Servlet2Advice")); Servlet2InstrumentationModule.class.getPackage().getName() + ".Servlet2Advice"));
} }
@Override
public Map<String, String> contextStore() {
return singletonMap("javax.servlet.ServletResponse", Integer.class.getName());
}
} }

View File

@ -5,8 +5,6 @@
package io.opentelemetry.javaagent.instrumentation.servlet.v5_0; package io.opentelemetry.javaagent.instrumentation.servlet.v5_0;
import static java.util.Collections.singletonMap;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.instrumentation.servlet.common.async.AsyncContextInstrumentation; import io.opentelemetry.javaagent.instrumentation.servlet.common.async.AsyncContextInstrumentation;
import io.opentelemetry.javaagent.instrumentation.servlet.common.dispatcher.RequestDispatcherInstrumentation; import io.opentelemetry.javaagent.instrumentation.servlet.common.dispatcher.RequestDispatcherInstrumentation;
@ -16,7 +14,6 @@ import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
public class JakartaServletInstrumentationModule extends InstrumentationModule { public class JakartaServletInstrumentationModule extends InstrumentationModule {
@ -39,11 +36,6 @@ public class JakartaServletInstrumentationModule extends InstrumentationModule {
BASE_PACKAGE, adviceClassName(".dispatcher.RequestDispatcherAdvice"))); BASE_PACKAGE, adviceClassName(".dispatcher.RequestDispatcherAdvice")));
} }
@Override
public Map<String, String> contextStore() {
return singletonMap(BASE_PACKAGE + ".RequestDispatcher", String.class.getName());
}
private static String adviceClassName(String suffix) { private static String adviceClassName(String suffix) {
return JakartaServletInstrumentationModule.class.getPackage().getName() + suffix; return JakartaServletInstrumentationModule.class.getPackage().getName() + suffix;
} }

View File

@ -5,8 +5,6 @@
package io.opentelemetry.javaagent.instrumentation.servlet.javax; package io.opentelemetry.javaagent.instrumentation.servlet.javax;
import static java.util.Collections.singletonMap;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.instrumentation.servlet.common.dispatcher.RequestDispatcherInstrumentation; import io.opentelemetry.javaagent.instrumentation.servlet.common.dispatcher.RequestDispatcherInstrumentation;
import io.opentelemetry.javaagent.instrumentation.servlet.common.response.HttpServletResponseInstrumentation; import io.opentelemetry.javaagent.instrumentation.servlet.common.response.HttpServletResponseInstrumentation;
@ -14,7 +12,6 @@ import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
public class JavaxServletInstrumentationModule extends InstrumentationModule { public class JavaxServletInstrumentationModule extends InstrumentationModule {
@ -33,11 +30,6 @@ public class JavaxServletInstrumentationModule extends InstrumentationModule {
BASE_PACKAGE, adviceClassName(".dispatcher.RequestDispatcherAdvice"))); BASE_PACKAGE, adviceClassName(".dispatcher.RequestDispatcherAdvice")));
} }
@Override
protected Map<String, String> contextStore() {
return singletonMap(BASE_PACKAGE + ".RequestDispatcher", String.class.getName());
}
private static String adviceClassName(String suffix) { private static String adviceClassName(String suffix) {
return JavaxServletInstrumentationModule.class.getPackage().getName() + suffix; return JavaxServletInstrumentationModule.class.getPackage().getName() + suffix;
} }

View File

@ -21,9 +21,7 @@ import io.opentelemetry.javaagent.instrumentation.spring.batch.step.StepBuilderH
import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
@ -37,17 +35,6 @@ public class SpringBatchInstrumentationModule extends InstrumentationModule {
return hasClassesNamed("org.springframework.batch.core.jsr.launch.JsrJobOperator"); return hasClassesNamed("org.springframework.batch.core.jsr.launch.JsrJobOperator");
} }
@Override
protected Map<String, String> contextStore() {
Map<String, String> context = new HashMap<>();
String contextAndScope =
"io.opentelemetry.javaagent.instrumentation.spring.batch.ContextAndScope";
context.put("org.springframework.batch.core.JobExecution", contextAndScope);
context.put("org.springframework.batch.core.StepExecution", contextAndScope);
context.put("org.springframework.batch.core.scope.context.ChunkContext", contextAndScope);
return context;
}
@Override @Override
public List<TypeInstrumentation> typeInstrumentations() { public List<TypeInstrumentation> typeInstrumentations() {
return Arrays.asList( return Arrays.asList(

View File

@ -7,14 +7,11 @@ package io.opentelemetry.javaagent.instrumentation.spring.core;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.instrumentation.api.concurrent.State;
import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List; import java.util.List;
import java.util.Map;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
@ -28,11 +25,6 @@ public class SpringCoreInstrumentationModule extends InstrumentationModule {
return hasClassesNamed("org.springframework.core.task.SimpleAsyncTaskExecutor"); return hasClassesNamed("org.springframework.core.task.SimpleAsyncTaskExecutor");
} }
@Override
protected Map<String, String> contextStore() {
return singletonMap(Runnable.class.getName(), State.class.getName());
}
@Override @Override
public List<TypeInstrumentation> typeInstrumentations() { public List<TypeInstrumentation> typeInstrumentations() {
return singletonList(new SimpleAsyncTaskExecutorInstrumentation()); return singletonList(new SimpleAsyncTaskExecutorInstrumentation());

View File

@ -6,13 +6,11 @@
package io.opentelemetry.javaagent.instrumentation.vertx.client; package io.opentelemetry.javaagent.instrumentation.vertx.client;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import com.google.auto.service.AutoService; import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.List; import java.util.List;
import java.util.Map;
@AutoService(InstrumentationModule.class) @AutoService(InstrumentationModule.class)
public class VertxClientInstrumentationModule extends InstrumentationModule { public class VertxClientInstrumentationModule extends InstrumentationModule {
@ -25,9 +23,4 @@ public class VertxClientInstrumentationModule extends InstrumentationModule {
public List<TypeInstrumentation> typeInstrumentations() { public List<TypeInstrumentation> typeInstrumentations() {
return singletonList(new HttpRequestInstrumentation()); return singletonList(new HttpRequestInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
return singletonMap("io.vertx.core.http.HttpClientRequest", Contexts.class.getName());
}
} }

View File

@ -192,7 +192,7 @@ public abstract class InstrumentationModule {
} }
private InstrumentationContextProvider getContextProvider() { private InstrumentationContextProvider getContextProvider() {
Map<String, String> contextStore = contextStore(); Map<String, String> contextStore = getMuzzleContextStoreClasses();
if (!contextStore.isEmpty()) { if (!contextStore.isEmpty()) {
return new FieldBackedProvider(getClass(), contextStore); return new FieldBackedProvider(getClass(), contextStore);
} else { } else {
@ -303,6 +303,20 @@ public abstract class InstrumentationModule {
return EMPTY; return EMPTY;
} }
/**
* Returns a map of {@code class-name to context-class-name}. Keys (and their subclasses) will be
* associated with a context class stored in the value.
*
* <p>The actual implementation of this method is generated automatically during compilation by
* the {@link io.opentelemetry.javaagent.tooling.muzzle.collector.MuzzleCodeGenerationPlugin}
* ByteBuddy plugin.
*
* <p><b>This method is generated automatically, do not override it.</b>
*/
protected Map<String, String> getMuzzleContextStoreClasses() {
return Collections.emptyMap();
}
/** /**
* Instrumentation modules can override this method to provide additional helper classes that are * Instrumentation modules can override this method to provide additional helper classes that are
* not located in instrumentation packages described in {@link InstrumentationClassPredicate} and * not located in instrumentation packages described in {@link InstrumentationClassPredicate} and
@ -346,16 +360,6 @@ public abstract class InstrumentationModule {
/** Returns a list of all individual type instrumentation in this module. */ /** Returns a list of all individual type instrumentation in this module. */
public abstract List<TypeInstrumentation> typeInstrumentations(); public abstract List<TypeInstrumentation> typeInstrumentations();
/**
* Context stores to define for this instrumentation.
*
* <p>A map of {@code class-name to context-class-name}. Keys (and their subclasses) will be
* associated with a context of the value.
*/
protected Map<String, String> contextStore() {
return Collections.emptyMap();
}
/** /**
* Allows instrumentation modules to disable themselves by default, or to additionally disable * Allows instrumentation modules to disable themselves by default, or to additionally disable
* themselves on some other condition. * themselves on some other condition.

View File

@ -10,6 +10,7 @@ import io.opentelemetry.javaagent.tooling.Utils;
import io.opentelemetry.javaagent.tooling.muzzle.Reference; import io.opentelemetry.javaagent.tooling.muzzle.Reference;
import io.opentelemetry.javaagent.tooling.muzzle.matcher.ReferenceMatcher; import io.opentelemetry.javaagent.tooling.muzzle.matcher.ReferenceMatcher;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -42,6 +43,8 @@ class MuzzleCodeGenerator implements AsmVisitorWrapper {
public static final String MUZZLE_REF_MATCHER_FIELD_NAME = "muzzleReferenceMatcher"; public static final String MUZZLE_REF_MATCHER_FIELD_NAME = "muzzleReferenceMatcher";
public static final String MUZZLE_REF_MATCHER_METHOD_NAME = "getMuzzleReferenceMatcher"; public static final String MUZZLE_REF_MATCHER_METHOD_NAME = "getMuzzleReferenceMatcher";
public static final String MUZZLE_HELPER_CLASSES_METHOD_NAME = "getMuzzleHelperClassNames"; public static final String MUZZLE_HELPER_CLASSES_METHOD_NAME = "getMuzzleHelperClassNames";
public static final String MUZZLE_CONTEXT_STORE_CLASSES_METHOD_NAME =
"getMuzzleContextStoreClasses";
@Override @Override
public int mergeWriter(int flags) { public int mergeWriter(int flags) {
@ -138,6 +141,7 @@ class MuzzleCodeGenerator implements AsmVisitorWrapper {
generateMuzzleHelperClassNamesMethod(collector); generateMuzzleHelperClassNamesMethod(collector);
generateMuzzleReferenceMatcherMethod(collector); generateMuzzleReferenceMatcherMethod(collector);
generateMuzzleReferenceMatcherField(); generateMuzzleReferenceMatcherField();
generateMuzzleContextStoreClassesMethod(collector);
super.visitEnd(); super.visitEnd();
} }
@ -518,6 +522,63 @@ class MuzzleCodeGenerator implements AsmVisitorWrapper {
null); null);
} }
private void generateMuzzleContextStoreClassesMethod(ReferenceCollector collector) {
/*
* protected Map<String, String> getMuzzleContextStoreClasses() {
* Map<String, String> contextStore = new HashMap();
* contextStore.put(..., ...);
* return contextStore;
* }
*/
MethodVisitor mv =
super.visitMethod(
Opcodes.ACC_PROTECTED,
MUZZLE_CONTEXT_STORE_CLASSES_METHOD_NAME,
"()Ljava/util/Map;",
null,
null);
mv.visitCode();
Map<String, String> contextStoreClasses = collector.getContextStoreClasses();
mv.visitTypeInsn(Opcodes.NEW, "java/util/HashMap");
// stack: map
mv.visitInsn(Opcodes.DUP);
// stack: map, map
mv.visitLdcInsn(contextStoreClasses.size());
// stack: map, map, size
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/HashMap", "<init>", "(I)V", false);
// stack: map
mv.visitVarInsn(Opcodes.ASTORE, 1);
// stack: <empty>
contextStoreClasses.forEach(
(className, contextClassName) -> {
mv.visitVarInsn(Opcodes.ALOAD, 1);
// stack: map
mv.visitLdcInsn(className);
// stack: map, className
mv.visitLdcInsn(contextClassName);
// stack: map, className, contextClassName
mv.visitMethodInsn(
Opcodes.INVOKEINTERFACE,
"java/util/Map",
"put",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
true);
// stack: previousValue
mv.visitInsn(Opcodes.POP);
// stack: <empty>
});
mv.visitVarInsn(Opcodes.ALOAD, 1);
// stack: map
mv.visitInsn(Opcodes.ARETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
private static final Pattern ANONYMOUS_ENUM_CONSTANT_CLASS = private static final Pattern ANONYMOUS_ENUM_CONSTANT_CLASS =
Pattern.compile("(?<enumClass>.*)\\$[0-9]+$"); Pattern.compile("(?<enumClass>.*)\\$[0-9]+$");

View File

@ -0,0 +1,12 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.tooling.muzzle.collector;
public class MuzzleCompilationException extends RuntimeException {
public MuzzleCompilationException(String message) {
super(message);
}
}

View File

@ -5,6 +5,7 @@
package io.opentelemetry.javaagent.tooling.muzzle.collector; package io.opentelemetry.javaagent.tooling.muzzle.collector;
import com.google.common.collect.EvictingQueue;
import io.opentelemetry.javaagent.tooling.Utils; import io.opentelemetry.javaagent.tooling.Utils;
import io.opentelemetry.javaagent.tooling.muzzle.InstrumentationClassPredicate; import io.opentelemetry.javaagent.tooling.muzzle.InstrumentationClassPredicate;
import io.opentelemetry.javaagent.tooling.muzzle.Reference; import io.opentelemetry.javaagent.tooling.muzzle.Reference;
@ -115,6 +116,7 @@ class ReferenceCollectingClassVisitor extends ClassVisitor {
// helper super classes which are themselves also helpers // helper super classes which are themselves also helpers
// this is needed for injecting the helper classes into the class loader in the correct order // this is needed for injecting the helper classes into the class loader in the correct order
private final Set<String> helperSuperClasses = new HashSet<>(); private final Set<String> helperSuperClasses = new HashSet<>();
private final Map<String, String> contextStoreClasses = new LinkedHashMap<>();
private String refSourceClassName; private String refSourceClassName;
private Type refSourceType; private Type refSourceType;
@ -137,6 +139,10 @@ class ReferenceCollectingClassVisitor extends ClassVisitor {
return helperSuperClasses; return helperSuperClasses;
} }
Map<String, String> getContextStoreClasses() {
return contextStoreClasses;
}
private void addExtendsReference(Reference ref) { private void addExtendsReference(Reference ref) {
addReference(ref); addReference(ref);
if (instrumentationClassPredicate.isInstrumentationClass(ref.getClassName())) { if (instrumentationClassPredicate.isInstrumentationClass(ref.getClassName())) {
@ -240,7 +246,8 @@ class ReferenceCollectingClassVisitor extends ClassVisitor {
// Additional references we could check // Additional references we could check
// - Classes in signature (return type, params) and visible from this package // - Classes in signature (return type, params) and visible from this package
return new AdviceReferenceMethodVisitor( return new AdviceReferenceMethodVisitor(
super.visitMethod(access, name, descriptor, signature, exceptions)); new InstrumentationContextMethodVisitor(
super.visitMethod(access, name, descriptor, signature, exceptions)));
} }
private static VisibilityFlag computeVisibilityFlag(int access) { private static VisibilityFlag computeVisibilityFlag(int access) {
@ -332,6 +339,7 @@ class ReferenceCollectingClassVisitor extends ClassVisitor {
.withFlag(computeMinimumClassAccess(refSourceType, underlyingFieldType)) .withFlag(computeMinimumClassAccess(refSourceType, underlyingFieldType))
.build()); .build());
} }
super.visitFieldInsn(opcode, owner, name, descriptor); super.visitFieldInsn(opcode, owner, name, descriptor);
} }
@ -349,6 +357,11 @@ class ReferenceCollectingClassVisitor extends ClassVisitor {
// * return type // * return type
Type methodType = Type.getMethodType(descriptor); Type methodType = Type.getMethodType(descriptor);
Type ownerType =
owner.startsWith("[")
? underlyingType(Type.getType(owner))
: Type.getType("L" + owner + ";");
{ // ref for method return type { // ref for method return type
Type returnType = underlyingType(methodType.getReturnType()); Type returnType = underlyingType(methodType.getReturnType());
if (returnType.getSort() == Type.OBJECT) { if (returnType.getSort() == Type.OBJECT) {
@ -371,11 +384,6 @@ class ReferenceCollectingClassVisitor extends ClassVisitor {
} }
} }
Type ownerType =
owner.startsWith("[")
? underlyingType(Type.getType(owner))
: Type.getType("L" + owner + ";");
List<Reference.Flag> methodFlags = new ArrayList<>(); List<Reference.Flag> methodFlags = new ArrayList<>();
methodFlags.add( methodFlags.add(
opcode == Opcodes.INVOKESTATIC ? OwnershipFlag.STATIC : OwnershipFlag.NON_STATIC); opcode == Opcodes.INVOKESTATIC ? OwnershipFlag.STATIC : OwnershipFlag.NON_STATIC);
@ -395,6 +403,7 @@ class ReferenceCollectingClassVisitor extends ClassVisitor {
methodType.getReturnType(), methodType.getReturnType(),
methodType.getArgumentTypes()) methodType.getArgumentTypes())
.build()); .build());
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
} }
@ -408,6 +417,7 @@ class ReferenceCollectingClassVisitor extends ClassVisitor {
.withFlag(computeMinimumClassAccess(refSourceType, typeObj)) .withFlag(computeMinimumClassAccess(refSourceType, typeObj))
.build()); .build());
} }
super.visitTypeInsn(opcode, type); super.visitTypeInsn(opcode, type);
} }
@ -456,4 +466,106 @@ class ReferenceCollectingClassVisitor extends ClassVisitor {
super.visitLdcInsn(value); super.visitLdcInsn(value);
} }
} }
private class InstrumentationContextMethodVisitor extends MethodVisitor {
// this data structure will remember last two LDC <class> instructions before
// InstrumentationContext.get() call
private final EvictingQueue<String> lastTwoClassConstants = EvictingQueue.create(2);
InstrumentationContextMethodVisitor(MethodVisitor methodVisitor) {
super(Opcodes.ASM7, methodVisitor);
}
@Override
public void visitInsn(int opcode) {
registerOpcode(opcode, null);
super.visitInsn(opcode);
}
@Override
public void visitIntInsn(int opcode, int operand) {
registerOpcode(opcode, null);
super.visitIntInsn(opcode, operand);
}
@Override
public void visitVarInsn(int opcode, int var) {
registerOpcode(opcode, null);
super.visitVarInsn(opcode, var);
}
@Override
public void visitTypeInsn(int opcode, String type) {
registerOpcode(opcode, null);
super.visitTypeInsn(opcode, type);
}
@Override
public void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
registerOpcode(opcode, null);
super.visitFieldInsn(opcode, owner, name, descriptor);
}
@Override
public void visitMethodInsn(
int opcode, String owner, String name, String descriptor, boolean isInterface) {
Type methodType = Type.getMethodType(descriptor);
Type ownerType = Type.getType("L" + owner + ";");
// remember used context classes if this is an InstrumentationContext.get() call
if ("io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext"
.equals(ownerType.getClassName())
&& "get".equals(name)
&& methodType.getArgumentTypes().length == 2) {
// in case of invalid scenario (not using .class ref directly) don't store anything and
// clear the last LDC <class> stack
// note that FieldBackedProvider also check for an invalid context call in the runtime
if (lastTwoClassConstants.remainingCapacity() == 0) {
String className = lastTwoClassConstants.poll();
String contextClassName = lastTwoClassConstants.poll();
contextStoreClasses.put(className, contextClassName);
} else {
throw new MuzzleCompilationException(
"Invalid InstrumentationContext#get(Class, Class) usage: you cannot pass variables,"
+ " method parameters, compute classes; class references need to be passed"
+ " directly to the get() method");
}
}
registerOpcode(opcode, null);
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
}
@Override
public void visitJumpInsn(int opcode, Label label) {
registerOpcode(opcode, null);
super.visitJumpInsn(opcode, label);
}
@Override
public void visitLdcInsn(Object value) {
registerOpcode(Opcodes.LDC, value);
super.visitLdcInsn(value);
}
private void registerOpcode(int opcode, Object value) {
// check if this is an LDC <class> instruction; if so, remember the class that was used
// we need to remember last two LDC <class> instructions that were executed before
// InstrumentationContext.get() call
if (opcode == Opcodes.LDC) {
if (value instanceof Type) {
Type type = (Type) value;
if (type.getSort() == Type.OBJECT) {
lastTwoClassConstants.add(type.getClassName());
return;
}
}
}
// instruction other than LDC <class> visited; pop the first element if present - this will
// prevent adding wrong context key pairs in case of an invalid scenario
lastTwoClassConstants.poll();
}
}
} }

View File

@ -46,6 +46,7 @@ import net.bytebuddy.jar.asm.ClassReader;
public class ReferenceCollector { public class ReferenceCollector {
private final Map<String, Reference> references = new LinkedHashMap<>(); private final Map<String, Reference> references = new LinkedHashMap<>();
private final MutableGraph<String> helperSuperClassGraph = GraphBuilder.directed().build(); private final MutableGraph<String> helperSuperClassGraph = GraphBuilder.directed().build();
private final Map<String, String> contextStoreClasses = new LinkedHashMap<>();
private final Set<String> visitedClasses = new HashSet<>(); private final Set<String> visitedClasses = new HashSet<>();
private final InstrumentationClassPredicate instrumentationClassPredicate; private final InstrumentationClassPredicate instrumentationClassPredicate;
@ -142,6 +143,7 @@ public class ReferenceCollector {
collectHelperClasses( collectHelperClasses(
isAdviceClass, visitedClassName, cv.getHelperClasses(), cv.getHelperSuperClasses()); isAdviceClass, visitedClassName, cv.getHelperClasses(), cv.getHelperSuperClasses());
contextStoreClasses.putAll(cv.getContextStoreClasses());
} catch (IOException e) { } catch (IOException e) {
throw new IllegalStateException("Error reading class " + visitedClassName, e); throw new IllegalStateException("Error reading class " + visitedClassName, e);
} }
@ -232,4 +234,8 @@ public class ReferenceCollector {
} }
return helpersWithNoDeps; return helpersWithNoDeps;
} }
public Map<String, String> getContextStoreClasses() {
return contextStoreClasses;
}
} }

View File

@ -47,15 +47,6 @@ public class ContextTestInstrumentationModule extends InstrumentationModule {
return singletonList(new ContextTestInstrumentation()); return singletonList(new ContextTestInstrumentation());
} }
@Override
public Map<String, String> contextStore() {
Map<String, String> store = new HashMap<>(3);
store.put("library.KeyClass", getClass().getName() + "$Context");
store.put("library.UntransformableKeyClass", getClass().getName() + "$Context");
store.put("library.DisabledKeyClass", getClass().getName() + "$Context");
return store;
}
public static class ContextTestInstrumentation implements TypeInstrumentation { public static class ContextTestInstrumentation implements TypeInstrumentation {
@Override @Override
public ElementMatcher<? super TypeDescription> typeMatcher() { public ElementMatcher<? super TypeDescription> typeMatcher() {
@ -71,13 +62,6 @@ public class ContextTestInstrumentationModule extends InstrumentationModule {
transformers.put(named("getContextCount"), GetApiUsageAdvice.class.getName()); transformers.put(named("getContextCount"), GetApiUsageAdvice.class.getName());
transformers.put(named("putContextCount"), PutApiUsageAdvice.class.getName()); transformers.put(named("putContextCount"), PutApiUsageAdvice.class.getName());
transformers.put(named("removeContextCount"), RemoveApiUsageAdvice.class.getName()); transformers.put(named("removeContextCount"), RemoveApiUsageAdvice.class.getName());
transformers.put(
named("incorrectKeyClassUsage"), IncorrectKeyClassContextApiUsageAdvice.class.getName());
transformers.put(
named("incorrectContextClassUsage"),
IncorrectContextClassContextApiUsageAdvice.class.getName());
transformers.put(
named("incorrectCallUsage"), IncorrectCallContextApiUsageAdvice.class.getName());
return transformers; return transformers;
} }
} }
@ -142,30 +126,6 @@ public class ContextTestInstrumentationModule extends InstrumentationModule {
} }
} }
public static class IncorrectKeyClassContextApiUsageAdvice {
@Advice.OnMethodExit
public static void methodExit() {
InstrumentationContext.get(Object.class, Context.class);
}
}
public static class IncorrectContextClassContextApiUsageAdvice {
@Advice.OnMethodExit
public static void methodExit() {
InstrumentationContext.get(KeyClass.class, Object.class);
}
}
public static class IncorrectCallContextApiUsageAdvice {
@Advice.OnMethodExit
public static void methodExit() {
// Our instrumentation doesn't handle variables being passed to InstrumentationContext.get,
// so we make sure that this actually fails instrumentation.
Class clazz = null;
InstrumentationContext.get(clazz, Object.class);
}
}
public static class Context { public static class Context {
public static final ContextStore.Factory<Context> FACTORY = Context::new; public static final ContextStore.Factory<Context> FACTORY = Context::new;

View File

@ -15,9 +15,6 @@ import java.lang.reflect.Field
import java.lang.reflect.Method import java.lang.reflect.Method
import java.lang.reflect.Modifier import java.lang.reflect.Modifier
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
import library.IncorrectCallUsageKeyClass
import library.IncorrectContextClassUsageKeyClass
import library.IncorrectKeyClassUsageKeyClass
import library.KeyClass import library.KeyClass
import library.UntransformableKeyClass import library.UntransformableKeyClass
import net.bytebuddy.agent.ByteBuddyAgent import net.bytebuddy.agent.ByteBuddyAgent
@ -187,21 +184,6 @@ class FieldBackedProviderTest extends AgentInstrumentationSpecification {
new KeyClass().incrementContextCount() == 1 new KeyClass().incrementContextCount() == 1
new UntransformableKeyClass().incrementContextCount() == 1 new UntransformableKeyClass().incrementContextCount() == 1
} }
def "incorrect key class usage fails at class load time"() {
expect:
!new IncorrectKeyClassUsageKeyClass().isInstrumented()
}
def "incorrect context class usage fails at class load time"() {
expect:
!new IncorrectContextClassUsageKeyClass().isInstrumented()
}
def "incorrect call usage fails at class load time"() {
expect:
!new IncorrectCallUsageKeyClass().isInstrumented()
}
} }

View File

@ -1,17 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package library;
public class IncorrectCallUsageKeyClass {
public boolean isInstrumented() {
return false;
}
public int incorrectCallUsage() {
// instrumentation will not apply to this class because advice incorrectly uses context api
return -1;
}
}

View File

@ -1,17 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package library;
public class IncorrectContextClassUsageKeyClass {
public boolean isInstrumented() {
return false;
}
public int incorrectContextClassUsage() {
// instrumentation will not apply to this class because advice incorrectly uses context api
return -1;
}
}

View File

@ -1,17 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package library;
public class IncorrectKeyClassUsageKeyClass {
public boolean isInstrumented() {
return false;
}
public int incorrectKeyClassUsage() {
// instrumentation will not apply to this class because advice incorrectly uses context api
return -1;
}
}

View File

@ -14,9 +14,12 @@ import static muzzle.TestClasses.LdcAdvice
import static muzzle.TestClasses.MethodBodyAdvice import static muzzle.TestClasses.MethodBodyAdvice
import external.instrumentation.ExternalHelper import external.instrumentation.ExternalHelper
import io.opentelemetry.context.Context
import io.opentelemetry.instrumentation.InstrumentationContextTestClasses
import io.opentelemetry.instrumentation.OtherTestHelperClasses import io.opentelemetry.instrumentation.OtherTestHelperClasses
import io.opentelemetry.instrumentation.TestHelperClasses import io.opentelemetry.instrumentation.TestHelperClasses
import io.opentelemetry.javaagent.tooling.muzzle.Reference import io.opentelemetry.javaagent.tooling.muzzle.Reference
import io.opentelemetry.javaagent.tooling.muzzle.collector.MuzzleCompilationException
import io.opentelemetry.javaagent.tooling.muzzle.collector.ReferenceCollector import io.opentelemetry.javaagent.tooling.muzzle.collector.ReferenceCollector
import spock.lang.Specification import spock.lang.Specification
import spock.lang.Unroll import spock.lang.Unroll
@ -255,6 +258,33 @@ class ReferenceCollectorTest extends Specification {
collector.sortedHelperClasses.isEmpty() collector.sortedHelperClasses.isEmpty()
} }
def "should collect context store classes"() {
when:
def collector = new ReferenceCollector({ false })
collector.collectReferencesFromAdvice(InstrumentationContextTestClasses.ValidAdvice.name)
then:
def contextStore = collector.getContextStoreClasses()
contextStore == [
(InstrumentationContextTestClasses.Key1.name): Context.name,
(InstrumentationContextTestClasses.Key2.name): Context.name
]
}
def "should not collect context store classes for invalid scenario: #desc"() {
when:
def collector = new ReferenceCollector({ false })
collector.collectReferencesFromAdvice(adviceClassName)
then:
thrown(MuzzleCompilationException)
where:
desc | adviceClassName
"passing arbitrary variables or parameters to InstrumentationContext.get()" | InstrumentationContextTestClasses.NotUsingClassRefAdvice.name
"storing class ref in a local var" | InstrumentationContextTestClasses.PassingVariableAdvice.name
}
private static assertHelperSuperClassMethod(Reference reference, boolean isAbstract) { private static assertHelperSuperClassMethod(Reference reference, boolean isAbstract) {
assertMethod reference, 'abstractMethod', '()I', assertMethod reference, 'abstractMethod', '()I',
VisibilityFlag.PROTECTED, VisibilityFlag.PROTECTED,

View File

@ -0,0 +1,40 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation;
import io.opentelemetry.context.Context;
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
public class InstrumentationContextTestClasses {
public static class ValidAdvice {
public static void advice() {
Runnable.class.getName();
InstrumentationContext.get(Key1.class, Context.class);
Key2.class.getName();
Key1.class.getName();
InstrumentationContext.get(Key2.class, Context.class);
}
}
public static class NotUsingClassRefAdvice {
public static void advice(Class<?> key, Class<?> context) {
Key2.class.getName();
Key1.class.getName();
InstrumentationContext.get(key, context);
}
}
public static class PassingVariableAdvice {
public static void advice() {
Class<?> context = Context.class;
InstrumentationContext.get(Key1.class, context);
}
}
public static class Key1 {}
public static class Key2 {}
}