generated from newrelic-experimental/java-instrumentation-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
386 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
|
||
// Build.gradle generated for instrumentation module rxjava1-finder | ||
|
||
apply plugin: 'java' | ||
|
||
dependencies { | ||
implementation 'io.reactivex:rxjava:1.1.0' | ||
|
||
// New Relic Java Agent dependencies | ||
implementation 'com.newrelic.agent.java:newrelic-agent:6.0.0' | ||
implementation 'com.newrelic.agent.java:newrelic-api:6.0.0' | ||
implementation fileTree(include: ['*.jar'], dir: '../libs') | ||
} | ||
|
||
jar { | ||
manifest { | ||
attributes 'Implementation-Title': 'com.newrelic.instrumentation.rxjava1-finder' | ||
attributes 'Implementation-Vendor': 'New Relic' | ||
attributes 'Implementation-Vendor-Id': 'com.newrelic' | ||
attributes 'Implementation-Version': 1.0 | ||
} | ||
} | ||
|
||
verifyInstrumentation { | ||
// Verifier plugin documentation: | ||
// https://github.com/newrelic/newrelic-gradle-verify-instrumentation | ||
// Example: | ||
// passes 'javax.servlet:servlet-api:[2.2,2.5]' | ||
// exclude 'javax.servlet:servlet-api:2.4.public_draft' | ||
} |
40 changes: 40 additions & 0 deletions
40
...ic/agent/instrumentation/pointcuts/frameworks/rxjava1/CompletableReturnMethodMatcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava1; | ||
|
||
import java.util.Set; | ||
|
||
import com.newrelic.agent.deps.org.objectweb.asm.Type; | ||
import com.newrelic.agent.deps.org.objectweb.asm.commons.Method; | ||
import com.newrelic.agent.instrumentation.methodmatchers.MethodMatcher; | ||
import com.newrelic.agent.util.asm.Utils; | ||
|
||
public class CompletableReturnMethodMatcher implements MethodMatcher { | ||
|
||
private static final String rxClassname = "rx.Completable"; | ||
|
||
public CompletableReturnMethodMatcher() { | ||
} | ||
|
||
@Override | ||
public Method[] getExactMethods() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public boolean matches(int access, String name, String desc, Set<String> annotations) { | ||
Type type = Type.getReturnType(desc); | ||
String classname = type.getClassName(); | ||
return isCompletable(classname); | ||
} | ||
|
||
private boolean isCompletable(String className) { | ||
if(Utils.isPrimitiveType(className) || className.endsWith("[]") || className.startsWith("com.newrelic")) { | ||
return false; | ||
} | ||
if(className.equals(rxClassname)) { | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
} |
64 changes: 64 additions & 0 deletions
64
...lic/agent/instrumentation/pointcuts/frameworks/rxjava1/ObservableReturnMethodMatcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava1; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Set; | ||
|
||
import com.newrelic.agent.deps.org.objectweb.asm.Type; | ||
import com.newrelic.agent.deps.org.objectweb.asm.commons.Method; | ||
import com.newrelic.agent.instrumentation.methodmatchers.MethodMatcher; | ||
import com.newrelic.agent.util.asm.Utils; | ||
|
||
public class ObservableReturnMethodMatcher implements MethodMatcher { | ||
|
||
private static final String rxClassname = "rx.Observable"; | ||
private static final String CachedObservable = "rx.internal.operators.CachedObservable"; | ||
private static final String ScalarSync = "rx.internal.util.ScalarSynchronousObservable"; | ||
private static final List<String> classList; | ||
|
||
static { | ||
classList = new ArrayList<String>(); | ||
classList.add(rxClassname); | ||
classList.add(CachedObservable); | ||
classList.add(ScalarSync); | ||
} | ||
|
||
public ObservableReturnMethodMatcher() { | ||
} | ||
|
||
@Override | ||
public Method[] getExactMethods() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public boolean matches(int access, String name, String desc, Set<String> annotations) { | ||
Type type = Type.getReturnType(desc); | ||
String classname = type.getClassName(); | ||
return isObservable(classname); | ||
} | ||
|
||
private boolean isObservable(String className) { | ||
if(Utils.isPrimitiveType(className) || className.endsWith("[]") || className.startsWith("com.newrelic")) { | ||
return false; | ||
} | ||
if(classList.contains(className)) { | ||
return true; | ||
} | ||
|
||
if(className.startsWith("rx.observables") && className.endsWith("Observable")) { | ||
return true; | ||
} | ||
|
||
if(className.startsWith("rx.observables") && className.endsWith("Subject")) { | ||
return true; | ||
} | ||
|
||
if(className.startsWith("rx.subjects") && className.endsWith("Subject")) { | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
} |
37 changes: 37 additions & 0 deletions
37
.../com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1ClassMatcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava1; | ||
|
||
import java.util.Collection; | ||
import java.util.Collections; | ||
|
||
import com.newrelic.agent.bridge.AgentBridge; | ||
import com.newrelic.agent.deps.org.objectweb.asm.ClassReader; | ||
import com.newrelic.agent.instrumentation.classmatchers.ClassMatcher; | ||
|
||
public class RxJava1ClassMatcher extends ClassMatcher { | ||
|
||
@Override | ||
public Collection<String> getClassNames() { | ||
return Collections.emptyList(); | ||
} | ||
|
||
@Override | ||
public boolean isMatch(Class<?> var1) { | ||
if(var1.isAnnotation()) return false; | ||
|
||
Package classPackage = var1.getPackage(); | ||
boolean b = !classPackage.getName().startsWith("rx."); | ||
return b; | ||
} | ||
|
||
@Override | ||
public boolean isMatch(ClassLoader loader, ClassReader cr) { | ||
if (loader == null) { | ||
loader = AgentBridge.getAgent().getClass().getClassLoader(); | ||
} | ||
String className = cr.getClassName(); | ||
|
||
boolean b = !className.startsWith("rx/"); | ||
return b; | ||
} | ||
|
||
} |
96 changes: 96 additions & 0 deletions
96
...com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1LoaderService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
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(); | ||
} | ||
|
||
} | ||
|
||
} |
38 changes: 38 additions & 0 deletions
38
...java/com/newrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1PointCut.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
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")); | ||
} | ||
|
||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
...wrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/RxJava1ReturnMethodMatcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava1; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Set; | ||
|
||
import com.newrelic.agent.instrumentation.methodmatchers.ManyMethodMatcher; | ||
import com.newrelic.agent.instrumentation.methodmatchers.MethodMatcher; | ||
|
||
public class RxJava1ReturnMethodMatcher extends ManyMethodMatcher { | ||
|
||
private static CompletableReturnMethodMatcher completableMatcher = new CompletableReturnMethodMatcher(); | ||
private static ObservableReturnMethodMatcher observableMatcher = new ObservableReturnMethodMatcher(); | ||
private static SingleReturnMethodMatcher singleMatcher = new SingleReturnMethodMatcher(); | ||
|
||
private static List<MethodMatcher> matchers; | ||
|
||
static { | ||
matchers = new ArrayList<MethodMatcher>(); | ||
matchers.add(completableMatcher); | ||
matchers.add(observableMatcher); | ||
matchers.add(singleMatcher); | ||
} | ||
|
||
public RxJava1ReturnMethodMatcher() { | ||
super(matchers); | ||
} | ||
|
||
@Override | ||
public boolean matches(int access, String name, String desc, Set<String> annotations) { | ||
for(MethodMatcher matcher : matchers) { | ||
if(matcher.matches(access, name, desc, annotations)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
} |
40 changes: 40 additions & 0 deletions
40
...ewrelic/agent/instrumentation/pointcuts/frameworks/rxjava1/SingleReturnMethodMatcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.newrelic.agent.instrumentation.pointcuts.frameworks.rxjava1; | ||
|
||
import java.util.Set; | ||
|
||
import com.newrelic.agent.deps.org.objectweb.asm.Type; | ||
import com.newrelic.agent.deps.org.objectweb.asm.commons.Method; | ||
import com.newrelic.agent.instrumentation.methodmatchers.MethodMatcher; | ||
import com.newrelic.agent.util.asm.Utils; | ||
|
||
public class SingleReturnMethodMatcher implements MethodMatcher { | ||
|
||
private static final String rxClassname = "rx.Single"; | ||
|
||
public SingleReturnMethodMatcher() { | ||
} | ||
|
||
@Override | ||
public Method[] getExactMethods() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public boolean matches(int access, String name, String desc, Set<String> annotations) { | ||
Type type = Type.getReturnType(desc); | ||
String classname = type.getClassName(); | ||
return isSingle(classname); | ||
} | ||
|
||
private boolean isSingle(String className) { | ||
if(Utils.isPrimitiveType(className) || className.endsWith("[]") || className.startsWith("com.newrelic")) { | ||
return false; | ||
} | ||
if(className.equals(rxClassname)) { | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
} |
Oops, something went wrong.