diff --git a/build.gradle b/build.gradle index 0a78aa1..c2b39ff 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ plugins { project.ext { group = 'com.newrelic.instrumentation' - javaAgentVersion = '6.4.0' + javaAgentVersion = '6.0.0' // Aligned with minimum Java major version supported by latest Java Agent javaVersion = JavaVersion.VERSION_1_8 diff --git a/reactor-core-2.x/build.gradle b/reactor-core-2.x/build.gradle deleted file mode 100644 index 691aa6a..0000000 --- a/reactor-core-2.x/build.gradle +++ /dev/null @@ -1,26 +0,0 @@ - -// Build.gradle generated for instrumentation module reactor-core-2.x - -apply plugin: 'java' - -dependencies { - implementation 'io.projectreactor:reactor-core:2.0.1.RELEASE' - - // 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.labs.reactor-core-2.x' - attributes 'Implementation-Vendor': 'New Relic Labs' - attributes 'Implementation-Vendor-Id': 'com.newrelic.labs' - attributes 'Implementation-Version': 1.0 - } -} - -verifyInstrumentation { - passes 'io.projectreactor:reactor-core:[2.0.1.RELEASE]' -} diff --git a/reactor-core-2.x/src/main/java/com/nr/instrumentation/reactor/NRRunnableWrapper.java b/reactor-core-2.x/src/main/java/com/nr/instrumentation/reactor/NRRunnableWrapper.java deleted file mode 100644 index ffb4a47..0000000 --- a/reactor-core-2.x/src/main/java/com/nr/instrumentation/reactor/NRRunnableWrapper.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.nr.instrumentation.reactor; - -import com.newrelic.agent.bridge.AgentBridge; -import com.newrelic.api.agent.Token; -import com.newrelic.api.agent.Trace; - -public class NRRunnableWrapper implements Runnable { - - private Runnable delegate = null; - - private Token token = null; - private static boolean isTransformed = false; - - public NRRunnableWrapper(Runnable r, Token t) { - delegate = r; - token = t; - if(!isTransformed) { - isTransformed = true; - AgentBridge.instrumentation.retransformUninstrumentedClass(getClass()); - } - } - - @Override - @Trace(async=true) - public void run() { - if(token != null) { - token.linkAndExpire(); - token = null; - } - if(delegate != null) { - delegate.run(); - } - } - -} diff --git a/reactor-core-2.x/src/main/java/reactor/core/dispatch/AbstractLifecycleDispatcher.java b/reactor-core-2.x/src/main/java/reactor/core/dispatch/AbstractLifecycleDispatcher.java deleted file mode 100644 index 530fc6d..0000000 --- a/reactor-core-2.x/src/main/java/reactor/core/dispatch/AbstractLifecycleDispatcher.java +++ /dev/null @@ -1,9 +0,0 @@ -package reactor.core.dispatch; - -import com.newrelic.api.agent.weaver.MatchType; -import com.newrelic.api.agent.weaver.Weave; - -@Weave(type=MatchType.BaseClass) -public abstract class AbstractLifecycleDispatcher { - -} diff --git a/reactor-core-3.1/build.gradle b/reactor-core-3.1/build.gradle index 7f682ce..0a2b1f3 100644 --- a/reactor-core-3.1/build.gradle +++ b/reactor-core-3.1/build.gradle @@ -4,7 +4,7 @@ apply plugin: 'java' dependencies { - implementation 'io.projectreactor:reactor-core:3.1.0.RELEASE' + implementation 'io.projectreactor:reactor-core:3.2.11.RELEASE' // New Relic Java Agent dependencies implementation 'com.newrelic.agent.java:newrelic-agent:6.4.0' @@ -19,13 +19,13 @@ dependencies { jar { manifest { - attributes 'Implementation-Title': 'com.newrelic.instrumentation.labs.reactor-core-3.1' - attributes 'Implementation-Vendor': 'New Relic Labs' - attributes 'Implementation-Vendor-Id': 'com.newrelic.labs' + attributes 'Implementation-Title': 'com.newrelic.instrumentation.reactor-core-3.1' + attributes 'Implementation-Vendor': 'New Relic' + attributes 'Implementation-Vendor-Id': 'com.newrelic' attributes 'Implementation-Version': 1.0 } } verifyInstrumentation { - passes 'io.projectreactor:reactor-core:[3.1.0.RELEASE,3.3.0.RELEASE)' -} + passes 'io.projectreactor:reactor-core:[3.1.0.RELEASE,)' +} \ No newline at end of file diff --git a/reactor-core-3.1/src/main/java/com/nr/instrumentation/reactor/NRReactorHeaders.java b/reactor-core-3.1/src/main/java/com/nr/instrumentation/reactor/NRReactorHeaders.java deleted file mode 100644 index 526549f..0000000 --- a/reactor-core-3.1/src/main/java/com/nr/instrumentation/reactor/NRReactorHeaders.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.nr.instrumentation.reactor; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; - -import com.newrelic.api.agent.HeaderType; -import com.newrelic.api.agent.Headers; - -public class NRReactorHeaders implements Headers { - - private HashMap headers = new HashMap(); - - @Override - public HeaderType getHeaderType() { - return HeaderType.MESSAGE; - } - - @Override - public String getHeader(String name) { - return headers.get(name); - } - - @Override - public Collection getHeaders(String name) { - String value = headers.get(name); - List list = new ArrayList(); - if(value != null) { - list.add(value); - } - return list; - } - - @Override - public void setHeader(String name, String value) { - headers.put(name, value); - } - - @Override - public void addHeader(String name, String value) { - headers.put(name, value); - } - - @Override - public Collection getHeaderNames() { - return headers.keySet(); - } - - @Override - public boolean containsHeader(String name) { - return headers.containsKey(name); - } - - public boolean isEmpty() { - return headers.isEmpty(); - } - - public void clear() { - headers.clear(); - } -} diff --git a/reactor-core-3.1/src/main/java/com/nr/instrumentation/reactor/NRRunnableWrapper.java b/reactor-core-3.1/src/main/java/com/nr/instrumentation/reactor/NRRunnableWrapper.java index 15fb4da..ffb4a47 100644 --- a/reactor-core-3.1/src/main/java/com/nr/instrumentation/reactor/NRRunnableWrapper.java +++ b/reactor-core-3.1/src/main/java/com/nr/instrumentation/reactor/NRRunnableWrapper.java @@ -1,20 +1,19 @@ package com.nr.instrumentation.reactor; import com.newrelic.agent.bridge.AgentBridge; -import com.newrelic.api.agent.NewRelic; +import com.newrelic.api.agent.Token; import com.newrelic.api.agent.Trace; -import com.newrelic.api.agent.TransportType; public class NRRunnableWrapper implements Runnable { private Runnable delegate = null; - private NRReactorHeaders headers; + private Token token = null; private static boolean isTransformed = false; - public NRRunnableWrapper(Runnable r, NRReactorHeaders h) { + public NRRunnableWrapper(Runnable r, Token t) { delegate = r; - headers = h; + token = t; if(!isTransformed) { isTransformed = true; AgentBridge.instrumentation.retransformUninstrumentedClass(getClass()); @@ -22,17 +21,11 @@ public NRRunnableWrapper(Runnable r, NRReactorHeaders h) { } @Override - @Trace(dispatcher=true) + @Trace(async=true) public void run() { - boolean ignore = true; - if(headers != null) { - if(!headers.isEmpty()) { - NewRelic.getAgent().getTransaction().acceptDistributedTraceHeaders(TransportType.Other, headers); - ignore = false; - } - } - if(ignore) { - NewRelic.getAgent().getTransaction().ignore(); + if(token != null) { + token.linkAndExpire(); + token = null; } if(delegate != null) { delegate.run(); diff --git a/reactor-core-3.1/src/main/java/com/nr/instrumentation/reactor/NRSubscriberWrapper.java b/reactor-core-3.1/src/main/java/com/nr/instrumentation/reactor/NRSubscriberWrapper.java deleted file mode 100644 index 82bb5ba..0000000 --- a/reactor-core-3.1/src/main/java/com/nr/instrumentation/reactor/NRSubscriberWrapper.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.nr.instrumentation.reactor; - -import org.reactivestreams.Subscription; - -import com.newrelic.agent.bridge.AgentBridge; -import com.newrelic.api.agent.NewRelic; -import com.newrelic.api.agent.Trace; -import com.newrelic.api.agent.Transaction; - -import reactor.core.CoreSubscriber; -import reactor.core.Fuseable; -import reactor.core.Fuseable.QueueSubscription; -import reactor.core.Scannable; - -public class NRSubscriberWrapper implements CoreSubscriber, QueueSubscription { - - private CoreSubscriber actual = null; - - private static boolean isTransformed = false; - - private Subscription subscription = null; - - private NRReactorHeaders headers = null; - - private String name = null; - - public NRSubscriberWrapper(CoreSubscriber sub, Scannable s) { - if(!isTransformed) { - AgentBridge.instrumentation.retransformUninstrumentedClass(getClass()); - isTransformed = true; - } - actual = sub; - name = s.name(); - if(name == null || name.isEmpty()) name = "Scannable"; - headers = new NRReactorHeaders(); - Transaction transaction = NewRelic.getAgent().getTransaction(); - if (transaction != null) { - transaction.insertDistributedTraceHeaders(headers); - } - - } - - @Override - public void onNext(T t) { - if(!ReactorUtils.activeTransaction()) { - ReactorDispatcher.startOnNextTransaction(name, actual, t, headers); - } else { - actual.onNext(t); - } - } - - @Override - public void onError(Throwable t) { - if(!ReactorUtils.activeTransaction()) { - ReactorDispatcher.startOnErrorTransaction(name, actual, headers,t); - } else { - ReactorUtils.deActivate(); - actual.onError(t); - } - } - - @Override - public void onComplete() { - if(!ReactorUtils.activeTransaction()) { - ReactorDispatcher.startOnCompleteTransaction(name, actual, headers); - } else { - ReactorUtils.deActivate(); - actual.onComplete(); - } - } - - @Override - public void onSubscribe(Subscription s) { - if(headers == null) { - headers = new NRReactorHeaders(); - } - if(headers.isEmpty()) { - NewRelic.getAgent().getTransaction().insertDistributedTraceHeaders(headers); - } - subscription = s; - actual.onSubscribe(this); - } - - @Override - @Trace - public void request(long n) { - NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Reactor",name,"request"); - subscription.request(n); - } - - @Override - @Trace - public void cancel() { - NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Reactor",name,"cancel"); - subscription.cancel(); - } - - @Override - public T poll() { - return null; - } - - @Override - public int size() { - return 0; - } - - @Override - public boolean isEmpty() { - return true; - } - - @Override - public void clear() { - - } - - @Override - public int requestFusion(int requestedMode) { - return Fuseable.NONE; - } - -} diff --git a/reactor-core-3.1/src/main/java/com/nr/instrumentation/reactor/ReactorDispatcher.java b/reactor-core-3.1/src/main/java/com/nr/instrumentation/reactor/ReactorDispatcher.java deleted file mode 100644 index 42d5924..0000000 --- a/reactor-core-3.1/src/main/java/com/nr/instrumentation/reactor/ReactorDispatcher.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.nr.instrumentation.reactor; - -import com.newrelic.agent.bridge.AgentBridge; -import com.newrelic.api.agent.NewRelic; -import com.newrelic.api.agent.Trace; -import com.newrelic.api.agent.Transaction; -import com.newrelic.api.agent.TransportType; - -import reactor.core.CoreSubscriber; - -public class ReactorDispatcher { - - private static volatile ReactorDispatcher instance = null; - - public static ReactorDispatcher get() { - if(instance == null) { - instance = new ReactorDispatcher(); - } - return instance; - } - - private ReactorDispatcher() { - AgentBridge.instrumentation.retransformUninstrumentedClass(getClass()); - } - - @Trace(dispatcher = true) - public static void startOnNextTransaction(String name,CoreSubscriber sub, T t, NRReactorHeaders headers) { - ReactorUtils.setActive(); - NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Reactor",name,"onNext"); - Transaction transaction = NewRelic.getAgent().getTransaction(); - if (transaction != null) { - if (headers != null && !headers.isEmpty()) { - transaction.acceptDistributedTraceHeaders(TransportType.Other, headers); - } - } - sub.onNext(t); - } - - @Trace(dispatcher = true) - public static void startOnCompleteTransaction(String name,CoreSubscriber sub, NRReactorHeaders headers) { - NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Reactor",name,"onComplete"); - Transaction transaction = NewRelic.getAgent().getTransaction(); - if (transaction != null) { - if (headers != null && !headers.isEmpty()) { - transaction.acceptDistributedTraceHeaders(TransportType.Other, headers); - } - } - sub.onComplete(); - } - - @Trace(dispatcher = true) - public static void startOnErrorTransaction(String name,CoreSubscriber sub, NRReactorHeaders headers, Throwable t) { - NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Reactor",name,"onError"); - Transaction transaction = NewRelic.getAgent().getTransaction(); - if (transaction != null) { - if (headers != null && !headers.isEmpty()) { - transaction.acceptDistributedTraceHeaders(TransportType.Other, headers); - } - } - sub.onError(t); - } - -} diff --git a/reactor-core-3.1/src/main/java/com/nr/instrumentation/reactor/ReactorUtils.java b/reactor-core-3.1/src/main/java/com/nr/instrumentation/reactor/ReactorUtils.java deleted file mode 100644 index 96ed7fd..0000000 --- a/reactor-core-3.1/src/main/java/com/nr/instrumentation/reactor/ReactorUtils.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.nr.instrumentation.reactor; - -import java.util.function.BiFunction; -import java.util.function.Function; - -import org.reactivestreams.Publisher; - -import com.newrelic.api.agent.NewRelic; -import com.newrelic.api.agent.Transaction; - -import reactor.core.CoreSubscriber; -import reactor.core.Scannable; -import reactor.core.publisher.Hooks; -import reactor.core.publisher.Operators; - -public class ReactorUtils { - - - private static ThreadLocal transactionActive = new ThreadLocal() { - - @Override - protected Boolean initialValue() { - return false; - } - - }; - - public static boolean initialized = false; - - public static final String NRHEADERS = "NEWRELIC_HEADERS"; - - - public static void initialize() { - initialized = true; - //Hooks.onEachOperator("NewRelicWrapper",asOperator()); - Hooks.onLastOperator("NewRelicWrapper",asOperator()); - ReactorDispatcher.get(); - - } - - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private static Function, ? extends Publisher> asOperator() { - - return Operators.lift(new BiFunction, CoreSubscriber>() { - - @Override - public CoreSubscriber apply(Scannable t, CoreSubscriber u) { - return new NRSubscriberWrapper(u,t); - } - }); - - } - - public static boolean activeTransaction() { - Boolean active = transactionActive.get(); - Transaction txn = NewRelic.getAgent().getTransaction(); - // if transaction is NoOp then there is no active transaction - boolean isNoOp = txn.getClass().getName().toLowerCase().contains("noop"); - if(!active && !isNoOp) { - setActive(); - active = true; - } else if(active && isNoOp) { - deActivate(); - active = false; - } - return active; - } - - public static void setActive() { - transactionActive.set(true); - } - - public static void deActivate() { - transactionActive.set(false); - } -} diff --git a/reactor-core-3.1/src/main/java/reactor/core/publisher/FluxSubscribeOn.java b/reactor-core-3.1/src/main/java/reactor/core/publisher/FluxSubscribeOn.java deleted file mode 100644 index d47e72b..0000000 --- a/reactor-core-3.1/src/main/java/reactor/core/publisher/FluxSubscribeOn.java +++ /dev/null @@ -1,23 +0,0 @@ -package reactor.core.publisher; - -import com.newrelic.api.agent.weaver.Weave; -import com.newrelic.api.agent.weaver.Weaver; - -import reactor.core.CoreSubscriber; - -/** - * Included simply so the verifier only works up to version 3.3.0.RELEASE - * - * @author dhilpipre - * - * @param - */ - -@Weave -abstract class FluxSubscribeOn { - - - public void subscribe(CoreSubscriber actual) { - Weaver.callOriginal(); - } -} diff --git a/reactor-core-3.1/src/main/java/reactor/core/publisher/Flux_instrumentation.java b/reactor-core-3.1/src/main/java/reactor/core/publisher/Flux_instrumentation.java deleted file mode 100644 index c586b2b..0000000 --- a/reactor-core-3.1/src/main/java/reactor/core/publisher/Flux_instrumentation.java +++ /dev/null @@ -1,18 +0,0 @@ -package reactor.core.publisher; - -import com.newrelic.api.agent.weaver.MatchType; -import com.newrelic.api.agent.weaver.Weave; -import com.newrelic.api.agent.weaver.Weaver; -import com.nr.instrumentation.reactor.ReactorUtils; - -@Weave(originalName="reactor.core.publisher.Flux",type = MatchType.BaseClass) -public abstract class Flux_instrumentation { - - protected static Flux onAssembly(Flux source) { - if(!ReactorUtils.initialized) { - ReactorUtils.initialize(); - } - return Weaver.callOriginal(); - } - -} diff --git a/reactor-core-3.1/src/main/java/reactor/core/publisher/Mono_instrumentation.java b/reactor-core-3.1/src/main/java/reactor/core/publisher/Mono_instrumentation.java deleted file mode 100644 index 1460861..0000000 --- a/reactor-core-3.1/src/main/java/reactor/core/publisher/Mono_instrumentation.java +++ /dev/null @@ -1,17 +0,0 @@ -package reactor.core.publisher; - -import com.newrelic.api.agent.weaver.MatchType; -import com.newrelic.api.agent.weaver.Weave; -import com.newrelic.api.agent.weaver.Weaver; -import com.nr.instrumentation.reactor.ReactorUtils; - -@Weave(originalName="reactor.core.publisher.Mono",type = MatchType.BaseClass) -public abstract class Mono_instrumentation { - - protected static Mono onAssembly(Mono source) { - if(!ReactorUtils.initialized) { - ReactorUtils.initialize(); - } - return Weaver.callOriginal(); - } -} diff --git a/reactor-core-3.1/src/main/java/reactor/core/scheduler/Scheduler.java b/reactor-core-3.1/src/main/java/reactor/core/scheduler/Scheduler.java index dccba83..4174254 100644 --- a/reactor-core-3.1/src/main/java/reactor/core/scheduler/Scheduler.java +++ b/reactor-core-3.1/src/main/java/reactor/core/scheduler/Scheduler.java @@ -3,11 +3,11 @@ import java.util.concurrent.TimeUnit; import com.newrelic.api.agent.NewRelic; +import com.newrelic.api.agent.Token; import com.newrelic.api.agent.Trace; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; -import com.nr.instrumentation.reactor.NRReactorHeaders; import com.nr.instrumentation.reactor.NRRunnableWrapper; import reactor.core.Disposable; @@ -18,12 +18,13 @@ public abstract class Scheduler { @Trace public Disposable schedule(Runnable task) { if(!(task instanceof NRRunnableWrapper)) { - NRReactorHeaders nrHeaders = new NRReactorHeaders(); - NewRelic.getAgent().getTransaction().insertDistributedTraceHeaders(nrHeaders); - - if(!nrHeaders.isEmpty()) { - NRRunnableWrapper wrapper = new NRRunnableWrapper(task, nrHeaders); + Token t = NewRelic.getAgent().getTransaction().getToken(); + if(t != null && t.isActive()) { + NRRunnableWrapper wrapper = new NRRunnableWrapper(task, t); task = wrapper; + } else if(t != null) { + t.expire(); + t = null; } } return Weaver.callOriginal(); @@ -34,12 +35,13 @@ public static class Worker { public Disposable schedule(Runnable task) { if(!(task instanceof NRRunnableWrapper)) { - NRReactorHeaders nrHeaders = new NRReactorHeaders(); - NewRelic.getAgent().getTransaction().insertDistributedTraceHeaders(nrHeaders); - - if(!nrHeaders.isEmpty()) { - NRRunnableWrapper wrapper = new NRRunnableWrapper(task, nrHeaders); + Token t = NewRelic.getAgent().getTransaction().getToken(); + if(t != null && t.isActive()) { + NRRunnableWrapper wrapper = new NRRunnableWrapper(task, t); task = wrapper; + } else if(t != null) { + t.expire(); + t = null; } } return Weaver.callOriginal(); @@ -47,12 +49,13 @@ public Disposable schedule(Runnable task) { public Disposable schedule(Runnable task, long delay, TimeUnit unit) { if(!(task instanceof NRRunnableWrapper)) { - NRReactorHeaders nrHeaders = new NRReactorHeaders(); - NewRelic.getAgent().getTransaction().insertDistributedTraceHeaders(nrHeaders); - - if(!nrHeaders.isEmpty()) { - NRRunnableWrapper wrapper = new NRRunnableWrapper(task, nrHeaders); + Token t = NewRelic.getAgent().getTransaction().getToken(); + if(t != null && t.isActive()) { + NRRunnableWrapper wrapper = new NRRunnableWrapper(task, t); task = wrapper; + } else if(t != null) { + t.expire(); + t = null; } } return Weaver.callOriginal(); diff --git a/reactor-core-3.3/build.gradle b/reactor-core-3.3/build.gradle deleted file mode 100644 index 17e1468..0000000 --- a/reactor-core-3.3/build.gradle +++ /dev/null @@ -1,26 +0,0 @@ - -// Build.gradle generated for instrumentation module reactor-core-3.1 - -apply plugin: 'java' - -dependencies { - implementation 'io.projectreactor:reactor-core:3.3.0.RELEASE' - - // New Relic Java Agent dependencies - implementation 'com.newrelic.agent.java:newrelic-agent:6.4.0' - implementation 'com.newrelic.agent.java:newrelic-api:6.4.0' - implementation fileTree(include: ['*.jar'], dir: '../libs') -} - -jar { - manifest { - attributes 'Implementation-Title': 'com.newrelic.instrumentation.labs.reactor-core-3.3' - attributes 'Implementation-Vendor': 'New Relic Labs' - attributes 'Implementation-Vendor-Id': 'com.newrelic.labs' - attributes 'Implementation-Version': 1.0 - } -} - -verifyInstrumentation { - passes 'io.projectreactor:reactor-core:[3.3.0.RELEASE,)' -} diff --git a/reactor-core-3.3/src/main/java/com/nr/instrumentation/reactor/NRReactorHeaders.java b/reactor-core-3.3/src/main/java/com/nr/instrumentation/reactor/NRReactorHeaders.java deleted file mode 100644 index 526549f..0000000 --- a/reactor-core-3.3/src/main/java/com/nr/instrumentation/reactor/NRReactorHeaders.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.nr.instrumentation.reactor; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; - -import com.newrelic.api.agent.HeaderType; -import com.newrelic.api.agent.Headers; - -public class NRReactorHeaders implements Headers { - - private HashMap headers = new HashMap(); - - @Override - public HeaderType getHeaderType() { - return HeaderType.MESSAGE; - } - - @Override - public String getHeader(String name) { - return headers.get(name); - } - - @Override - public Collection getHeaders(String name) { - String value = headers.get(name); - List list = new ArrayList(); - if(value != null) { - list.add(value); - } - return list; - } - - @Override - public void setHeader(String name, String value) { - headers.put(name, value); - } - - @Override - public void addHeader(String name, String value) { - headers.put(name, value); - } - - @Override - public Collection getHeaderNames() { - return headers.keySet(); - } - - @Override - public boolean containsHeader(String name) { - return headers.containsKey(name); - } - - public boolean isEmpty() { - return headers.isEmpty(); - } - - public void clear() { - headers.clear(); - } -} diff --git a/reactor-core-3.3/src/main/java/com/nr/instrumentation/reactor/NRRunnableWrapper.java b/reactor-core-3.3/src/main/java/com/nr/instrumentation/reactor/NRRunnableWrapper.java deleted file mode 100644 index 15fb4da..0000000 --- a/reactor-core-3.3/src/main/java/com/nr/instrumentation/reactor/NRRunnableWrapper.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.nr.instrumentation.reactor; - -import com.newrelic.agent.bridge.AgentBridge; -import com.newrelic.api.agent.NewRelic; -import com.newrelic.api.agent.Trace; -import com.newrelic.api.agent.TransportType; - -public class NRRunnableWrapper implements Runnable { - - private Runnable delegate = null; - - private NRReactorHeaders headers; - private static boolean isTransformed = false; - - public NRRunnableWrapper(Runnable r, NRReactorHeaders h) { - delegate = r; - headers = h; - if(!isTransformed) { - isTransformed = true; - AgentBridge.instrumentation.retransformUninstrumentedClass(getClass()); - } - } - - @Override - @Trace(dispatcher=true) - public void run() { - boolean ignore = true; - if(headers != null) { - if(!headers.isEmpty()) { - NewRelic.getAgent().getTransaction().acceptDistributedTraceHeaders(TransportType.Other, headers); - ignore = false; - } - } - if(ignore) { - NewRelic.getAgent().getTransaction().ignore(); - } - if(delegate != null) { - delegate.run(); - } - } - -} diff --git a/reactor-core-3.3/src/main/java/com/nr/instrumentation/reactor/NRSubscriberWrapper.java b/reactor-core-3.3/src/main/java/com/nr/instrumentation/reactor/NRSubscriberWrapper.java deleted file mode 100644 index 82bb5ba..0000000 --- a/reactor-core-3.3/src/main/java/com/nr/instrumentation/reactor/NRSubscriberWrapper.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.nr.instrumentation.reactor; - -import org.reactivestreams.Subscription; - -import com.newrelic.agent.bridge.AgentBridge; -import com.newrelic.api.agent.NewRelic; -import com.newrelic.api.agent.Trace; -import com.newrelic.api.agent.Transaction; - -import reactor.core.CoreSubscriber; -import reactor.core.Fuseable; -import reactor.core.Fuseable.QueueSubscription; -import reactor.core.Scannable; - -public class NRSubscriberWrapper implements CoreSubscriber, QueueSubscription { - - private CoreSubscriber actual = null; - - private static boolean isTransformed = false; - - private Subscription subscription = null; - - private NRReactorHeaders headers = null; - - private String name = null; - - public NRSubscriberWrapper(CoreSubscriber sub, Scannable s) { - if(!isTransformed) { - AgentBridge.instrumentation.retransformUninstrumentedClass(getClass()); - isTransformed = true; - } - actual = sub; - name = s.name(); - if(name == null || name.isEmpty()) name = "Scannable"; - headers = new NRReactorHeaders(); - Transaction transaction = NewRelic.getAgent().getTransaction(); - if (transaction != null) { - transaction.insertDistributedTraceHeaders(headers); - } - - } - - @Override - public void onNext(T t) { - if(!ReactorUtils.activeTransaction()) { - ReactorDispatcher.startOnNextTransaction(name, actual, t, headers); - } else { - actual.onNext(t); - } - } - - @Override - public void onError(Throwable t) { - if(!ReactorUtils.activeTransaction()) { - ReactorDispatcher.startOnErrorTransaction(name, actual, headers,t); - } else { - ReactorUtils.deActivate(); - actual.onError(t); - } - } - - @Override - public void onComplete() { - if(!ReactorUtils.activeTransaction()) { - ReactorDispatcher.startOnCompleteTransaction(name, actual, headers); - } else { - ReactorUtils.deActivate(); - actual.onComplete(); - } - } - - @Override - public void onSubscribe(Subscription s) { - if(headers == null) { - headers = new NRReactorHeaders(); - } - if(headers.isEmpty()) { - NewRelic.getAgent().getTransaction().insertDistributedTraceHeaders(headers); - } - subscription = s; - actual.onSubscribe(this); - } - - @Override - @Trace - public void request(long n) { - NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Reactor",name,"request"); - subscription.request(n); - } - - @Override - @Trace - public void cancel() { - NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Reactor",name,"cancel"); - subscription.cancel(); - } - - @Override - public T poll() { - return null; - } - - @Override - public int size() { - return 0; - } - - @Override - public boolean isEmpty() { - return true; - } - - @Override - public void clear() { - - } - - @Override - public int requestFusion(int requestedMode) { - return Fuseable.NONE; - } - -} diff --git a/reactor-core-3.3/src/main/java/com/nr/instrumentation/reactor/ReactorDispatcher.java b/reactor-core-3.3/src/main/java/com/nr/instrumentation/reactor/ReactorDispatcher.java deleted file mode 100644 index 42d5924..0000000 --- a/reactor-core-3.3/src/main/java/com/nr/instrumentation/reactor/ReactorDispatcher.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.nr.instrumentation.reactor; - -import com.newrelic.agent.bridge.AgentBridge; -import com.newrelic.api.agent.NewRelic; -import com.newrelic.api.agent.Trace; -import com.newrelic.api.agent.Transaction; -import com.newrelic.api.agent.TransportType; - -import reactor.core.CoreSubscriber; - -public class ReactorDispatcher { - - private static volatile ReactorDispatcher instance = null; - - public static ReactorDispatcher get() { - if(instance == null) { - instance = new ReactorDispatcher(); - } - return instance; - } - - private ReactorDispatcher() { - AgentBridge.instrumentation.retransformUninstrumentedClass(getClass()); - } - - @Trace(dispatcher = true) - public static void startOnNextTransaction(String name,CoreSubscriber sub, T t, NRReactorHeaders headers) { - ReactorUtils.setActive(); - NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Reactor",name,"onNext"); - Transaction transaction = NewRelic.getAgent().getTransaction(); - if (transaction != null) { - if (headers != null && !headers.isEmpty()) { - transaction.acceptDistributedTraceHeaders(TransportType.Other, headers); - } - } - sub.onNext(t); - } - - @Trace(dispatcher = true) - public static void startOnCompleteTransaction(String name,CoreSubscriber sub, NRReactorHeaders headers) { - NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Reactor",name,"onComplete"); - Transaction transaction = NewRelic.getAgent().getTransaction(); - if (transaction != null) { - if (headers != null && !headers.isEmpty()) { - transaction.acceptDistributedTraceHeaders(TransportType.Other, headers); - } - } - sub.onComplete(); - } - - @Trace(dispatcher = true) - public static void startOnErrorTransaction(String name,CoreSubscriber sub, NRReactorHeaders headers, Throwable t) { - NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Reactor",name,"onError"); - Transaction transaction = NewRelic.getAgent().getTransaction(); - if (transaction != null) { - if (headers != null && !headers.isEmpty()) { - transaction.acceptDistributedTraceHeaders(TransportType.Other, headers); - } - } - sub.onError(t); - } - -} diff --git a/reactor-core-3.3/src/main/java/com/nr/instrumentation/reactor/ReactorUtils.java b/reactor-core-3.3/src/main/java/com/nr/instrumentation/reactor/ReactorUtils.java deleted file mode 100644 index 96ed7fd..0000000 --- a/reactor-core-3.3/src/main/java/com/nr/instrumentation/reactor/ReactorUtils.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.nr.instrumentation.reactor; - -import java.util.function.BiFunction; -import java.util.function.Function; - -import org.reactivestreams.Publisher; - -import com.newrelic.api.agent.NewRelic; -import com.newrelic.api.agent.Transaction; - -import reactor.core.CoreSubscriber; -import reactor.core.Scannable; -import reactor.core.publisher.Hooks; -import reactor.core.publisher.Operators; - -public class ReactorUtils { - - - private static ThreadLocal transactionActive = new ThreadLocal() { - - @Override - protected Boolean initialValue() { - return false; - } - - }; - - public static boolean initialized = false; - - public static final String NRHEADERS = "NEWRELIC_HEADERS"; - - - public static void initialize() { - initialized = true; - //Hooks.onEachOperator("NewRelicWrapper",asOperator()); - Hooks.onLastOperator("NewRelicWrapper",asOperator()); - ReactorDispatcher.get(); - - } - - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private static Function, ? extends Publisher> asOperator() { - - return Operators.lift(new BiFunction, CoreSubscriber>() { - - @Override - public CoreSubscriber apply(Scannable t, CoreSubscriber u) { - return new NRSubscriberWrapper(u,t); - } - }); - - } - - public static boolean activeTransaction() { - Boolean active = transactionActive.get(); - Transaction txn = NewRelic.getAgent().getTransaction(); - // if transaction is NoOp then there is no active transaction - boolean isNoOp = txn.getClass().getName().toLowerCase().contains("noop"); - if(!active && !isNoOp) { - setActive(); - active = true; - } else if(active && isNoOp) { - deActivate(); - active = false; - } - return active; - } - - public static void setActive() { - transactionActive.set(true); - } - - public static void deActivate() { - transactionActive.set(false); - } -} diff --git a/reactor-core-3.3/src/main/java/reactor/core/publisher/Flux_instrumentation.java b/reactor-core-3.3/src/main/java/reactor/core/publisher/Flux_instrumentation.java deleted file mode 100644 index c586b2b..0000000 --- a/reactor-core-3.3/src/main/java/reactor/core/publisher/Flux_instrumentation.java +++ /dev/null @@ -1,18 +0,0 @@ -package reactor.core.publisher; - -import com.newrelic.api.agent.weaver.MatchType; -import com.newrelic.api.agent.weaver.Weave; -import com.newrelic.api.agent.weaver.Weaver; -import com.nr.instrumentation.reactor.ReactorUtils; - -@Weave(originalName="reactor.core.publisher.Flux",type = MatchType.BaseClass) -public abstract class Flux_instrumentation { - - protected static Flux onAssembly(Flux source) { - if(!ReactorUtils.initialized) { - ReactorUtils.initialize(); - } - return Weaver.callOriginal(); - } - -} diff --git a/reactor-core-3.3/src/main/java/reactor/core/publisher/Mono_instrumentation.java b/reactor-core-3.3/src/main/java/reactor/core/publisher/Mono_instrumentation.java deleted file mode 100644 index 1460861..0000000 --- a/reactor-core-3.3/src/main/java/reactor/core/publisher/Mono_instrumentation.java +++ /dev/null @@ -1,17 +0,0 @@ -package reactor.core.publisher; - -import com.newrelic.api.agent.weaver.MatchType; -import com.newrelic.api.agent.weaver.Weave; -import com.newrelic.api.agent.weaver.Weaver; -import com.nr.instrumentation.reactor.ReactorUtils; - -@Weave(originalName="reactor.core.publisher.Mono",type = MatchType.BaseClass) -public abstract class Mono_instrumentation { - - protected static Mono onAssembly(Mono source) { - if(!ReactorUtils.initialized) { - ReactorUtils.initialize(); - } - return Weaver.callOriginal(); - } -} diff --git a/reactor-core-3.3/src/main/java/reactor/core/scheduler/Scheduler.java b/reactor-core-3.3/src/main/java/reactor/core/scheduler/Scheduler.java deleted file mode 100644 index dccba83..0000000 --- a/reactor-core-3.3/src/main/java/reactor/core/scheduler/Scheduler.java +++ /dev/null @@ -1,62 +0,0 @@ -package reactor.core.scheduler; - -import java.util.concurrent.TimeUnit; - -import com.newrelic.api.agent.NewRelic; -import com.newrelic.api.agent.Trace; -import com.newrelic.api.agent.weaver.MatchType; -import com.newrelic.api.agent.weaver.Weave; -import com.newrelic.api.agent.weaver.Weaver; -import com.nr.instrumentation.reactor.NRReactorHeaders; -import com.nr.instrumentation.reactor.NRRunnableWrapper; - -import reactor.core.Disposable; - -@Weave(type=MatchType.Interface) -public abstract class Scheduler { - - @Trace - public Disposable schedule(Runnable task) { - if(!(task instanceof NRRunnableWrapper)) { - NRReactorHeaders nrHeaders = new NRReactorHeaders(); - NewRelic.getAgent().getTransaction().insertDistributedTraceHeaders(nrHeaders); - - if(!nrHeaders.isEmpty()) { - NRRunnableWrapper wrapper = new NRRunnableWrapper(task, nrHeaders); - task = wrapper; - } - } - return Weaver.callOriginal(); - } - - @Weave(type=MatchType.Interface) - public static class Worker { - - public Disposable schedule(Runnable task) { - if(!(task instanceof NRRunnableWrapper)) { - NRReactorHeaders nrHeaders = new NRReactorHeaders(); - NewRelic.getAgent().getTransaction().insertDistributedTraceHeaders(nrHeaders); - - if(!nrHeaders.isEmpty()) { - NRRunnableWrapper wrapper = new NRRunnableWrapper(task, nrHeaders); - task = wrapper; - } - } - return Weaver.callOriginal(); - } - - public Disposable schedule(Runnable task, long delay, TimeUnit unit) { - if(!(task instanceof NRRunnableWrapper)) { - NRReactorHeaders nrHeaders = new NRReactorHeaders(); - NewRelic.getAgent().getTransaction().insertDistributedTraceHeaders(nrHeaders); - - if(!nrHeaders.isEmpty()) { - NRRunnableWrapper wrapper = new NRRunnableWrapper(task, nrHeaders); - task = wrapper; - } - } - return Weaver.callOriginal(); - } - } - -} diff --git a/reactor-finder/build.gradle b/reactor-finder/build.gradle index f9d84b6..eb61e39 100644 --- a/reactor-finder/build.gradle +++ b/reactor-finder/build.gradle @@ -7,16 +7,16 @@ dependencies { implementation 'io.projectreactor:reactor-core:3.2.11.RELEASE' // New Relic Java Agent dependencies - implementation 'com.newrelic.agent.java:newrelic-agent:6.4.0' - implementation 'com.newrelic.agent.java:newrelic-api:6.4.0' + 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.labs.reactor-finder' - attributes 'Implementation-Vendor': 'New Relic Labs' - attributes 'Implementation-Vendor-Id': 'com.newrelic.labs' + attributes 'Implementation-Title': 'com.newrelic.instrumentation.reactor-finder' + attributes 'Implementation-Vendor': 'New Relic' + attributes 'Implementation-Vendor-Id': 'com.newrelic' attributes 'Implementation-Version': 1.0 } } @@ -27,4 +27,4 @@ verifyInstrumentation { // Example: // passes 'javax.servlet:servlet-api:[2.2,2.5]' // exclude 'javax.servlet:servlet-api:2.4.public_draft' -} +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 2c80acf..3308289 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,4 @@ rootProject.name = 'java-instrumentation-template' include 'reactor-core-2.x' include 'reactor-core-3.1' -include 'reactor-core-3.3' include 'reactor-finder'