From ed9dfbf60ecc3cd76fb7a0b2ec1e2b79a8f9ef5d Mon Sep 17 00:00:00 2001 From: Doug Hilpipre Date: Fri, 3 Jan 2025 12:50:52 -0600 Subject: [PATCH 1/2] switched initialization from agent Service to Premain --- .../CompletableReturnMethodMatcher.java | 2 +- .../ObservableReturnMethodMatcher.java | 2 +- .../rxjava1/RxJava1ClassAndMethodMatcher.java | 27 ++++++ .../rxjava1/RxJava1ClassMatcher.java | 2 +- .../labs/rxjava1/RxJava1ClassTransformer.java | 63 ++++++++++++ .../labs/rxjava1/RxJava1Factory.java | 26 +++++ .../labs/rxjava1/RxJava1PreMain.java | 71 ++++++++++++++ .../rxjava1/RxJava1ReturnMethodMatcher.java | 2 +- .../rxjava1/SingleReturnMethodMatcher.java | 2 +- .../rxjava1/RxJava1LoaderService.java | 96 ------------------- .../frameworks/rxjava1/RxJava1PointCut.java | 38 -------- .../CompletableReturnMethodMatcher.java | 2 +- .../finder}/FlowableReturnMethodMatcher.java | 2 +- .../finder}/MaybeReturnMethodMatcher.java | 2 +- .../ObservableReturnMethodMatcher.java | 2 +- .../finder/RxJava2ClassAndMethodMatcher.java | 27 ++++++ .../rxjava2/finder}/RxJava2ClassMatcher.java | 2 +- .../finder/RxJava2ClassTransformer.java | 63 ++++++++++++ .../labs/rxjava2/finder/RxJava2Factory.java | 26 +++++ .../rxjava2/finder}/RxJava2LoaderService.java | 2 +- .../rxjava2/finder}/RxJava2PointCut.java | 2 +- .../labs/rxjava2/finder/RxJava2PreMain.java | 71 ++++++++++++++ .../finder}/RxJava2ReturnMethodMatcher.java | 2 +- .../finder}/SingleReturnMethodMatcher.java | 2 +- .../CompletableReturnMethodMatcher.java | 2 +- .../finder}/FlowableReturnMethodMatcher.java | 2 +- .../finder}/MaybeReturnMethodMatcher.java | 2 +- .../ObservableReturnMethodMatcher.java | 2 +- .../finder/RxJava3ClassAndMethodMatcher.java | 27 ++++++ .../rxjava3/finder}/RxJava3ClassMatcher.java | 2 +- .../finder/RxJava3ClassTransformer.java | 63 ++++++++++++ .../labs/rxjava3/finder/RxJava3Factory.java | 26 +++++ .../labs/rxjava3/finder/RxJava3PreMain.java | 71 ++++++++++++++ .../finder}/RxJava3ReturnMethodMatcher.java | 2 +- .../finder}/SingleReturnMethodMatcher.java | 2 +- .../rxjava3/RxJava3LoaderService.java | 96 ------------------- .../frameworks/rxjava3/RxJava3PointCut.java | 40 -------- 37 files changed, 582 insertions(+), 291 deletions(-) rename rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks => labs}/rxjava1/CompletableReturnMethodMatcher.java (93%) rename rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks => labs}/rxjava1/ObservableReturnMethodMatcher.java (95%) create mode 100644 rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1ClassAndMethodMatcher.java rename rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks => labs}/rxjava1/RxJava1ClassMatcher.java (92%) create mode 100644 rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1ClassTransformer.java create mode 100644 rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1Factory.java create mode 100644 rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1PreMain.java rename rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks => labs}/rxjava1/RxJava1ReturnMethodMatcher.java (93%) rename rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks => labs}/rxjava1/SingleReturnMethodMatcher.java (93%) delete mode 100644 rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1LoaderService.java delete mode 100644 rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1PointCut.java rename rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks/rxjava2 => labs/rxjava2/finder}/CompletableReturnMethodMatcher.java (95%) rename rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks/rxjava2 => labs/rxjava2/finder}/FlowableReturnMethodMatcher.java (95%) rename rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks/rxjava2 => labs/rxjava2/finder}/MaybeReturnMethodMatcher.java (95%) rename rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks/rxjava2 => labs/rxjava2/finder}/ObservableReturnMethodMatcher.java (95%) create mode 100644 rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2ClassAndMethodMatcher.java rename rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks/rxjava2 => labs/rxjava2/finder}/RxJava2ClassMatcher.java (92%) create mode 100644 rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2ClassTransformer.java create mode 100644 rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2Factory.java rename rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks/rxjava2 => labs/rxjava2/finder}/RxJava2LoaderService.java (97%) rename rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks/rxjava2 => labs/rxjava2/finder}/RxJava2PointCut.java (94%) create mode 100644 rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2PreMain.java rename rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks/rxjava2 => labs/rxjava2/finder}/RxJava2ReturnMethodMatcher.java (94%) rename rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks/rxjava2 => labs/rxjava2/finder}/SingleReturnMethodMatcher.java (95%) rename rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks/rxjava3 => labs/rxjava3/finder}/CompletableReturnMethodMatcher.java (95%) rename rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks/rxjava3 => labs/rxjava3/finder}/FlowableReturnMethodMatcher.java (95%) rename rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks/rxjava3 => labs/rxjava3/finder}/MaybeReturnMethodMatcher.java (95%) rename rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks/rxjava3 => labs/rxjava3/finder}/ObservableReturnMethodMatcher.java (95%) create mode 100644 rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3ClassAndMethodMatcher.java rename rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks/rxjava3 => labs/rxjava3/finder}/RxJava3ClassMatcher.java (92%) create mode 100644 rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3ClassTransformer.java create mode 100644 rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3Factory.java create mode 100644 rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3PreMain.java rename rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks/rxjava3 => labs/rxjava3/finder}/RxJava3ReturnMethodMatcher.java (94%) rename rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/{pointcuts/frameworks/rxjava3 => labs/rxjava3/finder}/SingleReturnMethodMatcher.java (95%) delete mode 100644 rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/RxJava3LoaderService.java delete mode 100644 rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/RxJava3PointCut.java diff --git a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/CompletableReturnMethodMatcher.java b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/CompletableReturnMethodMatcher.java similarity index 93% rename from rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/CompletableReturnMethodMatcher.java rename to rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/CompletableReturnMethodMatcher.java index b8afab8..8ed0a7d 100644 --- a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/CompletableReturnMethodMatcher.java +++ b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/CompletableReturnMethodMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava1; +package com.newrelic.agent.instrumentation.labs.rxjava1; import java.util.Set; diff --git a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/ObservableReturnMethodMatcher.java b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/ObservableReturnMethodMatcher.java similarity index 95% rename from rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/ObservableReturnMethodMatcher.java rename to rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/ObservableReturnMethodMatcher.java index 76fe4e9..6a72a66 100644 --- a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/ObservableReturnMethodMatcher.java +++ b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/ObservableReturnMethodMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava1; +package com.newrelic.agent.instrumentation.labs.rxjava1; import java.util.ArrayList; import java.util.List; diff --git a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1ClassAndMethodMatcher.java b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1ClassAndMethodMatcher.java new file mode 100644 index 0000000..3cbbeb4 --- /dev/null +++ b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1ClassAndMethodMatcher.java @@ -0,0 +1,27 @@ +package com.newrelic.agent.instrumentation.labs.rxjava1; + +import com.newrelic.agent.instrumentation.classmatchers.ClassAndMethodMatcher; +import com.newrelic.agent.instrumentation.classmatchers.ClassMatcher; +import com.newrelic.agent.instrumentation.methodmatchers.MethodMatcher; + +public class RxJava1ClassAndMethodMatcher implements ClassAndMethodMatcher { + + private ClassMatcher classMatcher = null; + private MethodMatcher methodMatcher = null; + + public RxJava1ClassAndMethodMatcher() { + classMatcher = new RxJava1ClassMatcher(); + methodMatcher = new RxJava1ReturnMethodMatcher(); + } + + @Override + public ClassMatcher getClassMatcher() { + return classMatcher; + } + + @Override + public MethodMatcher getMethodMatcher() { + return methodMatcher; + } + +} diff --git a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1ClassMatcher.java b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1ClassMatcher.java similarity index 92% rename from rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1ClassMatcher.java rename to rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1ClassMatcher.java index a20ec1d..54fa1ba 100644 --- a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1ClassMatcher.java +++ b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1ClassMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava1; +package com.newrelic.agent.instrumentation.labs.rxjava1; import java.util.Collection; import java.util.Collections; diff --git a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1ClassTransformer.java b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1ClassTransformer.java new file mode 100644 index 0000000..3b70265 --- /dev/null +++ b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1ClassTransformer.java @@ -0,0 +1,63 @@ +package com.newrelic.agent.instrumentation.labs.rxjava1; + +import java.lang.instrument.IllegalClassFormatException; +import java.security.ProtectionDomain; +import java.util.HashMap; +import java.util.Map; + +import com.newrelic.agent.deps.org.objectweb.asm.commons.Method; +import com.newrelic.agent.instrumentation.InstrumentationType; +import com.newrelic.agent.instrumentation.classmatchers.ClassAndMethodMatcher; +import com.newrelic.agent.instrumentation.classmatchers.OptimizedClassMatcher.Match; +import com.newrelic.agent.instrumentation.classmatchers.OptimizedClassMatcherBuilder; +import com.newrelic.agent.instrumentation.context.ClassMatchVisitorFactory; +import com.newrelic.agent.instrumentation.context.ContextClassTransformer; +import com.newrelic.agent.instrumentation.context.InstrumentationContext; +import com.newrelic.agent.instrumentation.context.InstrumentationContextManager; +import com.newrelic.agent.instrumentation.methodmatchers.MethodMatcher; +import com.newrelic.agent.instrumentation.tracing.TraceDetailsBuilder; + +public class RxJava1ClassTransformer implements ContextClassTransformer { + + private final InstrumentationContextManager contextManager; + private final Map matchers = new HashMap(); + + public RxJava1ClassTransformer(InstrumentationContextManager mgr) { + contextManager = mgr; + } + + protected void addMatcher(ClassAndMethodMatcher matcher) { + OptimizedClassMatcherBuilder builder = OptimizedClassMatcherBuilder.newBuilder(); + builder.addClassMethodMatcher(matcher); + ClassMatchVisitorFactory matchVisitor = builder.build(); + matchers.put(matcher.getClass().getSimpleName(), matchVisitor); + contextManager.addContextClassTransformer(matchVisitor, this); + } + + protected void removeMatcher(ClassAndMethodMatcher matcher) { + ClassMatchVisitorFactory matchVisitor = matchers.get(matcher.getClass().getSimpleName()); + if(matchVisitor != null) { + contextManager.removeMatchVisitor(matchVisitor); + } + } + + + @Override + public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, + ProtectionDomain protectionDomain, byte[] classfileBuffer, InstrumentationContext context, Match match) + throws IllegalClassFormatException { + for (Method method : match.getMethods()) { + for (ClassAndMethodMatcher matcher : match.getClassMatches().keySet()) { + if (matcher.getMethodMatcher().matches(MethodMatcher.UNSPECIFIED_ACCESS, method.getName(), + method.getDescriptor(), match.getMethodAnnotations(method))) { + context.putTraceAnnotation(method, TraceDetailsBuilder.newBuilder().setTracerFactoryName(RxJava1PreMain.TRACER_FACTORY) + .setInstrumentationSourceName("New Relic Labs").setInstrumentationType(InstrumentationType.TraceAnnotation).setDispatcher(false).build()); + } + + } + } + return null; + } + + +} diff --git a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1Factory.java b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1Factory.java new file mode 100644 index 0000000..980d5ba --- /dev/null +++ b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1Factory.java @@ -0,0 +1,26 @@ +package com.newrelic.agent.instrumentation.labs.rxjava1; + +import com.newrelic.agent.Transaction; +import com.newrelic.agent.tracers.AbstractTracerFactory; +import com.newrelic.agent.tracers.ClassMethodSignature; +import com.newrelic.agent.tracers.DefaultTracer; +import com.newrelic.agent.tracers.Tracer; +import com.newrelic.agent.tracers.TracerFlags; +import com.newrelic.agent.tracers.metricname.MetricNameFormat; +import com.newrelic.agent.tracers.metricname.SimpleMetricNameFormat; + +public class RxJava1Factory extends AbstractTracerFactory { + + @Override + public Tracer doGetTracer(Transaction transaction, ClassMethodSignature sig, Object object, Object[] args) { + String classname = sig.getClassName(); + String methodName = sig.getMethodName(); + + int flags = DefaultTracer.DEFAULT_TRACER_FLAGS | TracerFlags.DISPATCHER; + + MetricNameFormat metricName = new SimpleMetricNameFormat("Custom/RxJava1/RxJava1Method/"+classname+"/"+methodName); + DefaultTracer tracer = new DefaultTracer(transaction, sig, object, metricName, flags); + return tracer; + } + +} diff --git a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1PreMain.java b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1PreMain.java new file mode 100644 index 0000000..e57f624 --- /dev/null +++ b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1PreMain.java @@ -0,0 +1,71 @@ +package com.newrelic.agent.instrumentation.labs.rxjava1; + +import java.lang.instrument.Instrumentation; +import java.util.concurrent.Executors; + +import com.newrelic.agent.InstrumentationProxy; +import com.newrelic.agent.TracerService; +import com.newrelic.agent.core.CoreService; +import com.newrelic.agent.instrumentation.ClassTransformerService; +import com.newrelic.agent.instrumentation.classmatchers.ClassAndMethodMatcher; +import com.newrelic.agent.instrumentation.context.InstrumentationContextManager; +import com.newrelic.agent.service.ServiceFactory; + +public class RxJava1PreMain { + + protected static final String TRACER_FACTORY = "RXJava1_Returning"; + + public static void premain(String s, Instrumentation inst) { + + } + + public static void initialize() { + boolean done = setup(); + if(!done) { + Executors.newSingleThreadExecutor().submit(new SetupProcess()); + } + } + + private static boolean setup() { + TracerService tracerService = ServiceFactory.getTracerService(); + ClassTransformerService classTransformerService = ServiceFactory.getClassTransformerService(); + CoreService coreService = ServiceFactory.getCoreService(); + if(classTransformerService != null && coreService != null && tracerService != null) { + tracerService.registerTracerFactory(TRACER_FACTORY, new RxJava1Factory()); + + InstrumentationContextManager contextMgr = classTransformerService.getContextManager(); + InstrumentationProxy proxy = coreService.getInstrumentation(); + + if(contextMgr != null && proxy != null) { + RxJava1ClassTransformer transformer = new RxJava1ClassTransformer(contextMgr); + ClassAndMethodMatcher matcher = new RxJava1ClassAndMethodMatcher(); + transformer.addMatcher(matcher); + return true; + } + } + return false; + } + + private static class SetupProcess implements Runnable { + + + + @Override + public void run() { + boolean setupComplete = false; + + while(!setupComplete) { + setupComplete = setup(); + if(!setupComplete) { + try { + Thread.sleep(1000L); + } catch (InterruptedException e) { + } + } + } + + } + + } + +} diff --git a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1ReturnMethodMatcher.java b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1ReturnMethodMatcher.java similarity index 93% rename from rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1ReturnMethodMatcher.java rename to rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1ReturnMethodMatcher.java index 8a02c45..ed644b6 100644 --- a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1ReturnMethodMatcher.java +++ b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/RxJava1ReturnMethodMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava1; +package com.newrelic.agent.instrumentation.labs.rxjava1; import java.util.ArrayList; import java.util.List; diff --git a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/SingleReturnMethodMatcher.java b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/SingleReturnMethodMatcher.java similarity index 93% rename from rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/SingleReturnMethodMatcher.java rename to rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/SingleReturnMethodMatcher.java index 359b2d1..3156375 100644 --- a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/SingleReturnMethodMatcher.java +++ b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava1/SingleReturnMethodMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava1; +package com.newrelic.agent.instrumentation.labs.rxjava1; import java.util.Set; diff --git a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1LoaderService.java b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1LoaderService.java deleted file mode 100644 index efca03d..0000000 --- a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1LoaderService.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava1; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.logging.Level; - -import com.newrelic.agent.instrumentation.ClassTransformerService; -import com.newrelic.agent.instrumentation.PointCutClassTransformer; -import com.newrelic.agent.service.AbstractService; -import com.newrelic.agent.service.ServiceFactory; -import com.newrelic.api.agent.NewRelic; - -public class RxJava1LoaderService extends AbstractService { - - private ExecutorService executor = null; - - public RxJava1LoaderService() { - super("RxJava1LoaderService"); - } - - @Override - public boolean isEnabled() { - return true; - } - - @Override - protected void doStart() throws Exception { - ClassTransformerService classTransformerService = ServiceFactory.getClassTransformerService(); - if(classTransformerService != null) { - PointCutClassTransformer classTransformer = classTransformerService.getClassTransformer(); - if(classTransformer != null) { - RxJava1PointCut rxjava1Pointcut = new RxJava1PointCut(classTransformer); - boolean b = classTransformerService.addTraceMatcher(rxjava1Pointcut, "RxJava1"); - NewRelic.getAgent().getLogger().log(Level.FINE, "Result of adding RxJava1Pointcut is {0}", b); - } else { - NewRelic.getAgent().getLogger().log(Level.FINE, "Could not load matcher because ClassTransformer is null"); - startExecutor(); - - } - } else { - NewRelic.getAgent().getLogger().log(Level.FINE, "Could not load matcher because ClassTransformerService is null"); - startExecutor(); - } - } - - @Override - protected void doStop() throws Exception { - - } - - private boolean addTraceMatcher(ClassTransformerService classTransformerService) { - PointCutClassTransformer classTransformer = classTransformerService.getClassTransformer(); - RxJava1PointCut rxjava1Pointcut = new RxJava1PointCut(classTransformer); - return classTransformerService.addTraceMatcher(rxjava1Pointcut, "RxJava1"); - } - - private void startExecutor() { - executor = Executors.newSingleThreadExecutor(); - RunCheck runCheck = new RunCheck(); - executor.submit(runCheck); - NewRelic.getAgent().getLogger().log(Level.FINE, "Submit RunCheck to executor"); - } - - private void shutdownExecutor() { - executor.shutdown(); - NewRelic.getAgent().getLogger().log(Level.FINE, "ReactorLoaderService executor has shut down"); - } - - - private class RunCheck implements Runnable { - - @Override - public void run() { - boolean done = false; - while(!done) { - ClassTransformerService classTransformerService = ServiceFactory.getClassTransformerService(); - if(classTransformerService != null) { - PointCutClassTransformer classTransformer = classTransformerService.getClassTransformer(); - if(classTransformer != null) { - done = true; - boolean b = addTraceMatcher(classTransformerService); - NewRelic.getAgent().getLogger().log(Level.FINE, "Result of adding ReactorPointcut is {0}", b); - } - } else { - try { - Thread.sleep(5000L); - } catch (InterruptedException e) { - } - } - } - shutdownExecutor(); - } - - } - -} diff --git a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1PointCut.java b/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1PointCut.java deleted file mode 100644 index d8de24a..0000000 --- a/rxjava1-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1PointCut.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava1; - -import com.newrelic.agent.MetricNames; -import com.newrelic.agent.Transaction; -import com.newrelic.agent.instrumentation.PointCutClassTransformer; -import com.newrelic.agent.instrumentation.PointCutConfiguration; -import com.newrelic.agent.instrumentation.TracerFactoryPointCut; -import com.newrelic.agent.tracers.ClassMethodSignature; -import com.newrelic.agent.tracers.OtherRootTracer; -import com.newrelic.agent.tracers.Tracer; -import com.newrelic.agent.tracers.metricname.ClassMethodMetricNameFormat; - -public class RxJava1PointCut extends TracerFactoryPointCut { - - public RxJava1PointCut(PointCutClassTransformer classTransformer) { - super(new PointCutConfiguration("rxjava1"),new RxJava1ClassMatcher(), new RxJava1ReturnMethodMatcher()); - } - - - - @Override - public boolean isDispatcher() { - return true; - } - - @Override - protected Tracer doGetTracer(Transaction transaction, ClassMethodSignature sig, Object rx, Object[] args) { - return new RxJava1MethodTracer(transaction, sig, rx); - } - - private static class RxJava1MethodTracer extends OtherRootTracer { - - public RxJava1MethodTracer(Transaction transaction, ClassMethodSignature sig, Object rx) { - super(transaction,sig,rx, new ClassMethodMetricNameFormat(sig, rx, MetricNames.OTHER_TRANSACTION+"/RxJava1")); - } - - } -} diff --git a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/CompletableReturnMethodMatcher.java b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/CompletableReturnMethodMatcher.java similarity index 95% rename from rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/CompletableReturnMethodMatcher.java rename to rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/CompletableReturnMethodMatcher.java index b79ab69..c2d8ee2 100644 --- a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/CompletableReturnMethodMatcher.java +++ b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/CompletableReturnMethodMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava2; +package com.newrelic.agent.instrumentation.labs.rxjava2.finder; import java.util.Set; diff --git a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/FlowableReturnMethodMatcher.java b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/FlowableReturnMethodMatcher.java similarity index 95% rename from rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/FlowableReturnMethodMatcher.java rename to rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/FlowableReturnMethodMatcher.java index 63e6edd..8ded672 100644 --- a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/FlowableReturnMethodMatcher.java +++ b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/FlowableReturnMethodMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava2; +package com.newrelic.agent.instrumentation.labs.rxjava2.finder; import java.util.Set; diff --git a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/MaybeReturnMethodMatcher.java b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/MaybeReturnMethodMatcher.java similarity index 95% rename from rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/MaybeReturnMethodMatcher.java rename to rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/MaybeReturnMethodMatcher.java index 3691522..2e64334 100644 --- a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/MaybeReturnMethodMatcher.java +++ b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/MaybeReturnMethodMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava2; +package com.newrelic.agent.instrumentation.labs.rxjava2.finder; import java.util.Set; diff --git a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/ObservableReturnMethodMatcher.java b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/ObservableReturnMethodMatcher.java similarity index 95% rename from rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/ObservableReturnMethodMatcher.java rename to rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/ObservableReturnMethodMatcher.java index c42237d..359f12f 100644 --- a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/ObservableReturnMethodMatcher.java +++ b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/ObservableReturnMethodMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava2; +package com.newrelic.agent.instrumentation.labs.rxjava2.finder; import java.util.Set; diff --git a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2ClassAndMethodMatcher.java b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2ClassAndMethodMatcher.java new file mode 100644 index 0000000..d090131 --- /dev/null +++ b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2ClassAndMethodMatcher.java @@ -0,0 +1,27 @@ +package com.newrelic.agent.instrumentation.labs.rxjava2.finder; + +import com.newrelic.agent.instrumentation.classmatchers.ClassAndMethodMatcher; +import com.newrelic.agent.instrumentation.classmatchers.ClassMatcher; +import com.newrelic.agent.instrumentation.methodmatchers.MethodMatcher; + +public class RxJava2ClassAndMethodMatcher implements ClassAndMethodMatcher { + + private ClassMatcher classMatcher = null; + private MethodMatcher methodMatcher = null; + + public RxJava2ClassAndMethodMatcher() { + classMatcher = new RxJava2ClassMatcher(); + methodMatcher = new RxJava2ReturnMethodMatcher(); + } + + @Override + public ClassMatcher getClassMatcher() { + return classMatcher; + } + + @Override + public MethodMatcher getMethodMatcher() { + return methodMatcher; + } + +} diff --git a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/RxJava2ClassMatcher.java b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2ClassMatcher.java similarity index 92% rename from rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/RxJava2ClassMatcher.java rename to rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2ClassMatcher.java index 50e11e1..5b8aaea 100644 --- a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/RxJava2ClassMatcher.java +++ b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2ClassMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava2; +package com.newrelic.agent.instrumentation.labs.rxjava2.finder; import java.util.Collection; import java.util.Collections; diff --git a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2ClassTransformer.java b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2ClassTransformer.java new file mode 100644 index 0000000..af920fd --- /dev/null +++ b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2ClassTransformer.java @@ -0,0 +1,63 @@ +package com.newrelic.agent.instrumentation.labs.rxjava2.finder; + +import java.lang.instrument.IllegalClassFormatException; +import java.security.ProtectionDomain; +import java.util.HashMap; +import java.util.Map; + +import com.newrelic.agent.deps.org.objectweb.asm.commons.Method; +import com.newrelic.agent.instrumentation.InstrumentationType; +import com.newrelic.agent.instrumentation.classmatchers.ClassAndMethodMatcher; +import com.newrelic.agent.instrumentation.classmatchers.OptimizedClassMatcher.Match; +import com.newrelic.agent.instrumentation.classmatchers.OptimizedClassMatcherBuilder; +import com.newrelic.agent.instrumentation.context.ClassMatchVisitorFactory; +import com.newrelic.agent.instrumentation.context.ContextClassTransformer; +import com.newrelic.agent.instrumentation.context.InstrumentationContext; +import com.newrelic.agent.instrumentation.context.InstrumentationContextManager; +import com.newrelic.agent.instrumentation.methodmatchers.MethodMatcher; +import com.newrelic.agent.instrumentation.tracing.TraceDetailsBuilder; + +public class RxJava2ClassTransformer implements ContextClassTransformer { + + private final InstrumentationContextManager contextManager; + private final Map matchers = new HashMap(); + + public RxJava2ClassTransformer(InstrumentationContextManager mgr) { + contextManager = mgr; + } + + protected void addMatcher(ClassAndMethodMatcher matcher) { + OptimizedClassMatcherBuilder builder = OptimizedClassMatcherBuilder.newBuilder(); + builder.addClassMethodMatcher(matcher); + ClassMatchVisitorFactory matchVisitor = builder.build(); + matchers.put(matcher.getClass().getSimpleName(), matchVisitor); + contextManager.addContextClassTransformer(matchVisitor, this); + } + + protected void removeMatcher(ClassAndMethodMatcher matcher) { + ClassMatchVisitorFactory matchVisitor = matchers.get(matcher.getClass().getSimpleName()); + if(matchVisitor != null) { + contextManager.removeMatchVisitor(matchVisitor); + } + } + + + @Override + public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, + ProtectionDomain protectionDomain, byte[] classfileBuffer, InstrumentationContext context, Match match) + throws IllegalClassFormatException { + for (Method method : match.getMethods()) { + for (ClassAndMethodMatcher matcher : match.getClassMatches().keySet()) { + if (matcher.getMethodMatcher().matches(MethodMatcher.UNSPECIFIED_ACCESS, method.getName(), + method.getDescriptor(), match.getMethodAnnotations(method))) { + context.putTraceAnnotation(method, TraceDetailsBuilder.newBuilder().setTracerFactoryName(RxJava2PreMain.TRACER_FACTORY) + .setInstrumentationSourceName("New Relic Labs").setInstrumentationType(InstrumentationType.TraceAnnotation).setDispatcher(false).build()); + } + + } + } + return null; + } + + +} diff --git a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2Factory.java b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2Factory.java new file mode 100644 index 0000000..2e650d9 --- /dev/null +++ b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2Factory.java @@ -0,0 +1,26 @@ +package com.newrelic.agent.instrumentation.labs.rxjava2.finder; + +import com.newrelic.agent.Transaction; +import com.newrelic.agent.tracers.AbstractTracerFactory; +import com.newrelic.agent.tracers.ClassMethodSignature; +import com.newrelic.agent.tracers.DefaultTracer; +import com.newrelic.agent.tracers.Tracer; +import com.newrelic.agent.tracers.TracerFlags; +import com.newrelic.agent.tracers.metricname.MetricNameFormat; +import com.newrelic.agent.tracers.metricname.SimpleMetricNameFormat; + +public class RxJava2Factory extends AbstractTracerFactory { + + @Override + public Tracer doGetTracer(Transaction transaction, ClassMethodSignature sig, Object object, Object[] args) { + String classname = sig.getClassName(); + String methodName = sig.getMethodName(); + + int flags = DefaultTracer.DEFAULT_TRACER_FLAGS | TracerFlags.DISPATCHER; + + MetricNameFormat metricName = new SimpleMetricNameFormat("Custom/RxJava2/RxJava2Method/"+classname+"/"+methodName); + DefaultTracer tracer = new DefaultTracer(transaction, sig, object, metricName, flags); + return tracer; + } + +} diff --git a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/RxJava2LoaderService.java b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2LoaderService.java similarity index 97% rename from rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/RxJava2LoaderService.java rename to rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2LoaderService.java index abd439b..0220f97 100644 --- a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/RxJava2LoaderService.java +++ b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2LoaderService.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava2; +package com.newrelic.agent.instrumentation.labs.rxjava2.finder; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/RxJava2PointCut.java b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2PointCut.java similarity index 94% rename from rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/RxJava2PointCut.java rename to rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2PointCut.java index f0b625d..f6de46d 100644 --- a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/RxJava2PointCut.java +++ b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2PointCut.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava2; +package com.newrelic.agent.instrumentation.labs.rxjava2.finder; import com.newrelic.agent.MetricNames; import com.newrelic.agent.Transaction; diff --git a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2PreMain.java b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2PreMain.java new file mode 100644 index 0000000..9e236ae --- /dev/null +++ b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2PreMain.java @@ -0,0 +1,71 @@ +package com.newrelic.agent.instrumentation.labs.rxjava2.finder; + +import java.lang.instrument.Instrumentation; +import java.util.concurrent.Executors; + +import com.newrelic.agent.InstrumentationProxy; +import com.newrelic.agent.TracerService; +import com.newrelic.agent.core.CoreService; +import com.newrelic.agent.instrumentation.ClassTransformerService; +import com.newrelic.agent.instrumentation.classmatchers.ClassAndMethodMatcher; +import com.newrelic.agent.instrumentation.context.InstrumentationContextManager; +import com.newrelic.agent.service.ServiceFactory; + +public class RxJava2PreMain { + + protected static final String TRACER_FACTORY = "RXJava2_Returning"; + + public static void premain(String s, Instrumentation inst) { + + } + + public static void initialize() { + boolean done = setup(); + if(!done) { + Executors.newSingleThreadExecutor().submit(new SetupProcess()); + } + } + + private static boolean setup() { + TracerService tracerService = ServiceFactory.getTracerService(); + ClassTransformerService classTransformerService = ServiceFactory.getClassTransformerService(); + CoreService coreService = ServiceFactory.getCoreService(); + if(classTransformerService != null && coreService != null && tracerService != null) { + tracerService.registerTracerFactory(TRACER_FACTORY, new RxJava2Factory()); + + InstrumentationContextManager contextMgr = classTransformerService.getContextManager(); + InstrumentationProxy proxy = coreService.getInstrumentation(); + + if(contextMgr != null && proxy != null) { + RxJava2ClassTransformer transformer = new RxJava2ClassTransformer(contextMgr); + ClassAndMethodMatcher matcher = new RxJava2ClassAndMethodMatcher(); + transformer.addMatcher(matcher); + return true; + } + } + return false; + } + + private static class SetupProcess implements Runnable { + + + + @Override + public void run() { + boolean setupComplete = false; + + while(!setupComplete) { + setupComplete = setup(); + if(!setupComplete) { + try { + Thread.sleep(1000L); + } catch (InterruptedException e) { + } + } + } + + } + + } + +} diff --git a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/RxJava2ReturnMethodMatcher.java b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2ReturnMethodMatcher.java similarity index 94% rename from rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/RxJava2ReturnMethodMatcher.java rename to rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2ReturnMethodMatcher.java index 3efa3d7..e8d439a 100644 --- a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/RxJava2ReturnMethodMatcher.java +++ b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/RxJava2ReturnMethodMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava2; +package com.newrelic.agent.instrumentation.labs.rxjava2.finder; import java.util.ArrayList; import java.util.List; diff --git a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/SingleReturnMethodMatcher.java b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/SingleReturnMethodMatcher.java similarity index 95% rename from rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/SingleReturnMethodMatcher.java rename to rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/SingleReturnMethodMatcher.java index cdcf9ba..38f7a0e 100644 --- a/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava2/SingleReturnMethodMatcher.java +++ b/rxjava2-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava2/finder/SingleReturnMethodMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava2; +package com.newrelic.agent.instrumentation.labs.rxjava2.finder; import java.util.Set; diff --git a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/CompletableReturnMethodMatcher.java b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/CompletableReturnMethodMatcher.java similarity index 95% rename from rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/CompletableReturnMethodMatcher.java rename to rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/CompletableReturnMethodMatcher.java index 0a7962b..3b3d03a 100644 --- a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/CompletableReturnMethodMatcher.java +++ b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/CompletableReturnMethodMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava3; +package com.newrelic.agent.instrumentation.labs.rxjava3.finder; import java.util.Set; diff --git a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/FlowableReturnMethodMatcher.java b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/FlowableReturnMethodMatcher.java similarity index 95% rename from rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/FlowableReturnMethodMatcher.java rename to rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/FlowableReturnMethodMatcher.java index 9932077..4dcf374 100644 --- a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/FlowableReturnMethodMatcher.java +++ b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/FlowableReturnMethodMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava3; +package com.newrelic.agent.instrumentation.labs.rxjava3.finder; import java.util.Set; diff --git a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/MaybeReturnMethodMatcher.java b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/MaybeReturnMethodMatcher.java similarity index 95% rename from rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/MaybeReturnMethodMatcher.java rename to rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/MaybeReturnMethodMatcher.java index 7e10cdd..16f32af 100644 --- a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/MaybeReturnMethodMatcher.java +++ b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/MaybeReturnMethodMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava3; +package com.newrelic.agent.instrumentation.labs.rxjava3.finder; import java.util.Set; diff --git a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/ObservableReturnMethodMatcher.java b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/ObservableReturnMethodMatcher.java similarity index 95% rename from rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/ObservableReturnMethodMatcher.java rename to rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/ObservableReturnMethodMatcher.java index b2ef320..48c28dd 100644 --- a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/ObservableReturnMethodMatcher.java +++ b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/ObservableReturnMethodMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava3; +package com.newrelic.agent.instrumentation.labs.rxjava3.finder; import java.util.Set; diff --git a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3ClassAndMethodMatcher.java b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3ClassAndMethodMatcher.java new file mode 100644 index 0000000..a89f760 --- /dev/null +++ b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3ClassAndMethodMatcher.java @@ -0,0 +1,27 @@ +package com.newrelic.agent.instrumentation.labs.rxjava3.finder; + +import com.newrelic.agent.instrumentation.classmatchers.ClassAndMethodMatcher; +import com.newrelic.agent.instrumentation.classmatchers.ClassMatcher; +import com.newrelic.agent.instrumentation.methodmatchers.MethodMatcher; + +public class RxJava3ClassAndMethodMatcher implements ClassAndMethodMatcher { + + private ClassMatcher classMatcher = null; + private MethodMatcher methodMatcher = null; + + public RxJava3ClassAndMethodMatcher() { + classMatcher = new RxJava3ClassMatcher(); + methodMatcher = new RxJava3ReturnMethodMatcher(); + } + + @Override + public ClassMatcher getClassMatcher() { + return classMatcher; + } + + @Override + public MethodMatcher getMethodMatcher() { + return methodMatcher; + } + +} diff --git a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/RxJava3ClassMatcher.java b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3ClassMatcher.java similarity index 92% rename from rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/RxJava3ClassMatcher.java rename to rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3ClassMatcher.java index e2f60f7..5028c69 100644 --- a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/RxJava3ClassMatcher.java +++ b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3ClassMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava3; +package com.newrelic.agent.instrumentation.labs.rxjava3.finder; import java.util.Collection; import java.util.Collections; diff --git a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3ClassTransformer.java b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3ClassTransformer.java new file mode 100644 index 0000000..63db3ec --- /dev/null +++ b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3ClassTransformer.java @@ -0,0 +1,63 @@ +package com.newrelic.agent.instrumentation.labs.rxjava3.finder; + +import java.lang.instrument.IllegalClassFormatException; +import java.security.ProtectionDomain; +import java.util.HashMap; +import java.util.Map; + +import com.newrelic.agent.deps.org.objectweb.asm.commons.Method; +import com.newrelic.agent.instrumentation.InstrumentationType; +import com.newrelic.agent.instrumentation.classmatchers.ClassAndMethodMatcher; +import com.newrelic.agent.instrumentation.classmatchers.OptimizedClassMatcher.Match; +import com.newrelic.agent.instrumentation.classmatchers.OptimizedClassMatcherBuilder; +import com.newrelic.agent.instrumentation.context.ClassMatchVisitorFactory; +import com.newrelic.agent.instrumentation.context.ContextClassTransformer; +import com.newrelic.agent.instrumentation.context.InstrumentationContext; +import com.newrelic.agent.instrumentation.context.InstrumentationContextManager; +import com.newrelic.agent.instrumentation.methodmatchers.MethodMatcher; +import com.newrelic.agent.instrumentation.tracing.TraceDetailsBuilder; + +public class RxJava3ClassTransformer implements ContextClassTransformer { + + private final InstrumentationContextManager contextManager; + private final Map matchers = new HashMap(); + + public RxJava3ClassTransformer(InstrumentationContextManager mgr) { + contextManager = mgr; + } + + protected void addMatcher(ClassAndMethodMatcher matcher) { + OptimizedClassMatcherBuilder builder = OptimizedClassMatcherBuilder.newBuilder(); + builder.addClassMethodMatcher(matcher); + ClassMatchVisitorFactory matchVisitor = builder.build(); + matchers.put(matcher.getClass().getSimpleName(), matchVisitor); + contextManager.addContextClassTransformer(matchVisitor, this); + } + + protected void removeMatcher(ClassAndMethodMatcher matcher) { + ClassMatchVisitorFactory matchVisitor = matchers.get(matcher.getClass().getSimpleName()); + if(matchVisitor != null) { + contextManager.removeMatchVisitor(matchVisitor); + } + } + + + @Override + public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, + ProtectionDomain protectionDomain, byte[] classfileBuffer, InstrumentationContext context, Match match) + throws IllegalClassFormatException { + for (Method method : match.getMethods()) { + for (ClassAndMethodMatcher matcher : match.getClassMatches().keySet()) { + if (matcher.getMethodMatcher().matches(MethodMatcher.UNSPECIFIED_ACCESS, method.getName(), + method.getDescriptor(), match.getMethodAnnotations(method))) { + context.putTraceAnnotation(method, TraceDetailsBuilder.newBuilder().setTracerFactoryName(RxJava3PreMain.TRACER_FACTORY) + .setInstrumentationSourceName("New Relic Labs").setInstrumentationType(InstrumentationType.TraceAnnotation).setDispatcher(false).build()); + } + + } + } + return null; + } + + +} diff --git a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3Factory.java b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3Factory.java new file mode 100644 index 0000000..982a3d4 --- /dev/null +++ b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3Factory.java @@ -0,0 +1,26 @@ +package com.newrelic.agent.instrumentation.labs.rxjava3.finder; + +import com.newrelic.agent.Transaction; +import com.newrelic.agent.tracers.AbstractTracerFactory; +import com.newrelic.agent.tracers.ClassMethodSignature; +import com.newrelic.agent.tracers.DefaultTracer; +import com.newrelic.agent.tracers.Tracer; +import com.newrelic.agent.tracers.TracerFlags; +import com.newrelic.agent.tracers.metricname.MetricNameFormat; +import com.newrelic.agent.tracers.metricname.SimpleMetricNameFormat; + +public class RxJava3Factory extends AbstractTracerFactory { + + @Override + public Tracer doGetTracer(Transaction transaction, ClassMethodSignature sig, Object object, Object[] args) { + String classname = sig.getClassName(); + String methodName = sig.getMethodName(); + + int flags = DefaultTracer.DEFAULT_TRACER_FLAGS | TracerFlags.DISPATCHER; + + MetricNameFormat metricName = new SimpleMetricNameFormat("Custom/RxJava3/RxJava3Method/"+classname+"/"+methodName); + DefaultTracer tracer = new DefaultTracer(transaction, sig, object, metricName, flags); + return tracer; + } + +} diff --git a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3PreMain.java b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3PreMain.java new file mode 100644 index 0000000..0a17c47 --- /dev/null +++ b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3PreMain.java @@ -0,0 +1,71 @@ +package com.newrelic.agent.instrumentation.labs.rxjava3.finder; + +import java.lang.instrument.Instrumentation; +import java.util.concurrent.Executors; + +import com.newrelic.agent.InstrumentationProxy; +import com.newrelic.agent.TracerService; +import com.newrelic.agent.core.CoreService; +import com.newrelic.agent.instrumentation.ClassTransformerService; +import com.newrelic.agent.instrumentation.classmatchers.ClassAndMethodMatcher; +import com.newrelic.agent.instrumentation.context.InstrumentationContextManager; +import com.newrelic.agent.service.ServiceFactory; + +public class RxJava3PreMain { + + protected static final String TRACER_FACTORY = "RXJava3_Returning"; + + public static void premain(String s, Instrumentation inst) { + + } + + public static void initialize() { + boolean done = setup(); + if(!done) { + Executors.newSingleThreadExecutor().submit(new SetupProcess()); + } + } + + private static boolean setup() { + TracerService tracerService = ServiceFactory.getTracerService(); + ClassTransformerService classTransformerService = ServiceFactory.getClassTransformerService(); + CoreService coreService = ServiceFactory.getCoreService(); + if(classTransformerService != null && coreService != null && tracerService != null) { + tracerService.registerTracerFactory(TRACER_FACTORY, new RxJava3Factory()); + + InstrumentationContextManager contextMgr = classTransformerService.getContextManager(); + InstrumentationProxy proxy = coreService.getInstrumentation(); + + if(contextMgr != null && proxy != null) { + RxJava3ClassTransformer transformer = new RxJava3ClassTransformer(contextMgr); + ClassAndMethodMatcher matcher = new RxJava3ClassAndMethodMatcher(); + transformer.addMatcher(matcher); + return true; + } + } + return false; + } + + private static class SetupProcess implements Runnable { + + + + @Override + public void run() { + boolean setupComplete = false; + + while(!setupComplete) { + setupComplete = setup(); + if(!setupComplete) { + try { + Thread.sleep(1000L); + } catch (InterruptedException e) { + } + } + } + + } + + } + +} diff --git a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/RxJava3ReturnMethodMatcher.java b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3ReturnMethodMatcher.java similarity index 94% rename from rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/RxJava3ReturnMethodMatcher.java rename to rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3ReturnMethodMatcher.java index 97938f3..2e33603 100644 --- a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/RxJava3ReturnMethodMatcher.java +++ b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/RxJava3ReturnMethodMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava3; +package com.newrelic.agent.instrumentation.labs.rxjava3.finder; import java.util.ArrayList; import java.util.List; diff --git a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/SingleReturnMethodMatcher.java b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/SingleReturnMethodMatcher.java similarity index 95% rename from rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/SingleReturnMethodMatcher.java rename to rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/SingleReturnMethodMatcher.java index d06977e..05208ac 100644 --- a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/SingleReturnMethodMatcher.java +++ b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/labs/rxjava3/finder/SingleReturnMethodMatcher.java @@ -1,4 +1,4 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava3; +package com.newrelic.agent.instrumentation.labs.rxjava3.finder; import java.util.Set; diff --git a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/RxJava3LoaderService.java b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/RxJava3LoaderService.java deleted file mode 100644 index 70296d9..0000000 --- a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/RxJava3LoaderService.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava3; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.logging.Level; - -import com.newrelic.agent.instrumentation.ClassTransformerService; -import com.newrelic.agent.instrumentation.PointCutClassTransformer; -import com.newrelic.agent.service.AbstractService; -import com.newrelic.agent.service.ServiceFactory; -import com.newrelic.api.agent.NewRelic; - -public class RxJava3LoaderService extends AbstractService { - - private ExecutorService executor = null; - - public RxJava3LoaderService() { - super("RxJava3LoaderService"); - } - - @Override - public boolean isEnabled() { - return true; - } - - @Override - protected void doStart() throws Exception { - ClassTransformerService classTransformerService = ServiceFactory.getClassTransformerService(); - if(classTransformerService != null) { - PointCutClassTransformer classTransformer = classTransformerService.getClassTransformer(); - if(classTransformer != null) { - RxJava3PointCut rxjava3Pointcut = new RxJava3PointCut(classTransformer); - boolean b = classTransformerService.addTraceMatcher(rxjava3Pointcut, "RxJava3"); - NewRelic.getAgent().getLogger().log(Level.FINE, "Result of adding RxJava3Pointcut is {0}", b); - } else { - NewRelic.getAgent().getLogger().log(Level.FINE, "Could not load matcher because ClassTransformer is null"); - startExecutor(); - - } - } else { - NewRelic.getAgent().getLogger().log(Level.FINE, "Could not load matcher because ClassTransformerService is null"); - startExecutor(); - } - } - - @Override - protected void doStop() throws Exception { - - } - - private boolean addTraceMatcher(ClassTransformerService classTransformerService) { - PointCutClassTransformer classTransformer = classTransformerService.getClassTransformer(); - RxJava3PointCut rxjava3Pointcut = new RxJava3PointCut(classTransformer); - return classTransformerService.addTraceMatcher(rxjava3Pointcut, "RxJava3"); - } - - private void startExecutor() { - executor = Executors.newSingleThreadExecutor(); - RunCheck runCheck = new RunCheck(); - executor.submit(runCheck); - NewRelic.getAgent().getLogger().log(Level.FINE, "Submit RunCheck to executor"); - } - - private void shutdownExecutor() { - executor.shutdown(); - NewRelic.getAgent().getLogger().log(Level.FINE, "ReactorLoaderService executor has shut down"); - } - - - private class RunCheck implements Runnable { - - @Override - public void run() { - boolean done = false; - while(!done) { - ClassTransformerService classTransformerService = ServiceFactory.getClassTransformerService(); - if(classTransformerService != null) { - PointCutClassTransformer classTransformer = classTransformerService.getClassTransformer(); - if(classTransformer != null) { - done = true; - boolean b = addTraceMatcher(classTransformerService); - NewRelic.getAgent().getLogger().log(Level.FINE, "Result of adding ReactorPointcut is {0}", b); - } - } else { - try { - Thread.sleep(5000L); - } catch (InterruptedException e) { - } - } - } - shutdownExecutor(); - } - - } - -} diff --git a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/RxJava3PointCut.java b/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/RxJava3PointCut.java deleted file mode 100644 index 18e6fcd..0000000 --- a/rxjava3-finder/src/main/java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava3/RxJava3PointCut.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava3; - -import com.newrelic.agent.MetricNames; -import com.newrelic.agent.Transaction; -import com.newrelic.agent.instrumentation.PointCutClassTransformer; -import com.newrelic.agent.instrumentation.PointCutConfiguration; -import com.newrelic.agent.instrumentation.TracerFactoryPointCut; -import com.newrelic.agent.tracers.ClassMethodSignature; -import com.newrelic.agent.tracers.OtherRootTracer; -import com.newrelic.agent.tracers.Tracer; -import com.newrelic.agent.tracers.metricname.ClassMethodMetricNameFormat; - -public class RxJava3PointCut extends TracerFactoryPointCut { - - public RxJava3PointCut(PointCutClassTransformer classTransformer) { - super(new PointCutConfiguration("rxjava3"),new RxJava3ClassMatcher(), new RxJava3ReturnMethodMatcher()); - } - - - - @Override - public boolean isDispatcher() { - return true; - } - - - - @Override - protected Tracer doGetTracer(Transaction transaction, ClassMethodSignature sig, Object rx, Object[] args) { - return new RxJava3MethodTracer(transaction, sig, rx); - } - - private static class RxJava3MethodTracer extends OtherRootTracer { - - public RxJava3MethodTracer(Transaction transaction, ClassMethodSignature sig, Object rx) { - super(transaction,sig,rx, new ClassMethodMetricNameFormat(sig, rx, MetricNames.OTHER_TRANSACTION+"/RxJava3")); - } - - } -} From 1426a2a166a042b24695b8e0d87b5ed135d24dad Mon Sep 17 00:00:00 2001 From: Doug Hilpipre Date: Fri, 3 Jan 2025 12:52:07 -0600 Subject: [PATCH 2/2] switched initialization from agent Service to Premain --- rxjava2-2.0/src/main/java/io/reactivex/NRSingleWrapper.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/rxjava2-2.0/src/main/java/io/reactivex/NRSingleWrapper.java b/rxjava2-2.0/src/main/java/io/reactivex/NRSingleWrapper.java index 5538c4e..df8ca89 100644 --- a/rxjava2-2.0/src/main/java/io/reactivex/NRSingleWrapper.java +++ b/rxjava2-2.0/src/main/java/io/reactivex/NRSingleWrapper.java @@ -4,8 +4,6 @@ import com.newrelic.api.agent.NewRelic; import com.newrelic.api.agent.Trace; -import io.reactivex.SingleObserver; - public class NRSingleWrapper extends Single { private Single delegate = null;