File tree Expand file tree Collapse file tree 12 files changed +372
-0
lines changed
com/newrelic/instrumentation/spring/web/async
org/springframework/core/task
com/newrelic/instrumentation/spring/web/async
org/springframework/web/context/request/async Expand file tree Collapse file tree 12 files changed +372
-0
lines changed Original file line number Diff line number Diff line change 11.java-version
22.git
33.github
4+ .settings
5+ .classpath
6+ .project
7+ bin
8+ build
Original file line number Diff line number Diff line change 11rootProject. name = ' java-instrumentation-template'
2+ include ' spring-async'
3+ include ' spring-web-async'
Original file line number Diff line number Diff line change 1+
2+ // Build.gradle generated for instrumentation module spring-web-async
3+
4+ apply plugin : ' java'
5+
6+ dependencies {
7+ implementation ' org.springframework:spring-core:5.0.0.RELEASE'
8+
9+ // New Relic Java Agent dependencies
10+ implementation ' com.newrelic.agent.java:newrelic-agent:6.4.0'
11+ implementation ' com.newrelic.agent.java:newrelic-api:6.4.0'
12+ implementation fileTree(include : [' *.jar' ], dir : ' ../libs' )
13+ implementation fileTree(include : [' *.jar' ], dir : ' ../test-lib' )
14+ }
15+
16+ jar {
17+ manifest {
18+ attributes ' Implementation-Title' : ' com.newrelic.instrumentation.spring-async'
19+ attributes ' Implementation-Vendor' : ' New Relic'
20+ attributes ' Implementation-Vendor-Id' : ' com.newrelic'
21+ attributes ' Implementation-Version' : 1.0
22+ }
23+ }
24+
25+ verifyInstrumentation {
26+ passes ' org.springframework:spring-core:[5.0.0.RELEASE,)'
27+ }
Original file line number Diff line number Diff line change 1+ package com .newrelic .instrumentation .spring .web .async ;
2+
3+ import java .util .concurrent .Callable ;
4+
5+ import com .newrelic .agent .bridge .AgentBridge ;
6+ import com .newrelic .api .agent .NewRelic ;
7+ import com .newrelic .api .agent .Token ;
8+ import com .newrelic .api .agent .Trace ;
9+
10+ public class NRCallableWrapper <V > implements Callable <V > {
11+
12+ private Callable <V > delegate = null ;
13+ private Token token = null ;
14+ private static boolean isTransformed = false ;
15+
16+ public NRCallableWrapper (Callable <V > d , Token t ) {
17+ delegate = d ;
18+ token = t ;
19+ if (!isTransformed ) {
20+ AgentBridge .instrumentation .retransformUninstrumentedClass (getClass ());
21+ isTransformed = true ;
22+ }
23+ }
24+
25+ @ Override
26+ @ Trace (async = true )
27+ public V call () throws Exception {
28+ if (token != null ) {
29+ NewRelic .getAgent ().getTracedMethod ().setMetricName ("Custom" ,"SpringAsync" ,"Callable" );
30+ token .linkAndExpire ();
31+ token = null ;
32+ }
33+ return delegate .call ();
34+ }
35+
36+ }
Original file line number Diff line number Diff line change 1+ package com .newrelic .instrumentation .spring .web .async ;
2+
3+ import com .newrelic .agent .bridge .AgentBridge ;
4+ import com .newrelic .api .agent .NewRelic ;
5+ import com .newrelic .api .agent .Token ;
6+ import com .newrelic .api .agent .Trace ;
7+
8+ public class NRRunnableWrapper implements Runnable {
9+
10+ private static boolean isTransformed = false ;
11+ private Runnable delegate = null ;
12+ private Token token = null ;
13+
14+ public NRRunnableWrapper (Runnable r , Token t ) {
15+ delegate = r ;
16+ token = t ;
17+ if (!isTransformed ) {
18+ isTransformed = true ;
19+ AgentBridge .instrumentation .retransformUninstrumentedClass (getClass ());
20+ }
21+ }
22+
23+ @ Override
24+ @ Trace (async = true )
25+ public void run () {
26+ if (token != null ) {
27+ NewRelic .getAgent ().getTracedMethod ().setMetricName ("Custom" ,"SpringAsync" ,"Runnable" );
28+ token .linkAndExpire ();
29+ token = null ;
30+ }
31+ delegate .run ();
32+ }
33+
34+ }
Original file line number Diff line number Diff line change 1+ package com .newrelic .instrumentation .spring .web .async ;
2+
3+ import java .util .concurrent .Callable ;
4+
5+ import com .newrelic .api .agent .NewRelic ;
6+ import com .newrelic .api .agent .Token ;
7+
8+ public class Utils {
9+
10+ public static Runnable getWrappedRunnable (Runnable r ) {
11+
12+ if (r instanceof NRRunnableWrapper ) return null ;
13+
14+ String packageName = r .getClass ().getPackage ().getName ();
15+ if (packageName .startsWith ("com.newrelic" )) return null ;
16+
17+ Token token = NewRelic .getAgent ().getTransaction ().getToken ();
18+ if (token != null && token .isActive ()) {
19+ return new NRRunnableWrapper (r , token );
20+ } else if (token != null ) {
21+ token .expire ();
22+ token = null ;
23+ }
24+ return null ;
25+ }
26+
27+ public static <V > Callable <V > getWrappedCallable (Callable <V > c ) {
28+
29+ if (c instanceof NRCallableWrapper ) return null ;
30+
31+ String packageName = c .getClass ().getPackage ().getName ();
32+ if (packageName .startsWith ("com.newrelic" )) return null ;
33+
34+ Token token = NewRelic .getAgent ().getTransaction ().getToken ();
35+ if (token != null && token .isActive ()) {
36+ return new NRCallableWrapper <V >(c , token );
37+ } else if (token != null ) {
38+ token .expire ();
39+ token = null ;
40+ }
41+ return null ;
42+ }
43+
44+ }
Original file line number Diff line number Diff line change 1+ package org .springframework .core .task ;
2+
3+ import com .newrelic .api .agent .weaver .Weave ;
4+ import com .newrelic .api .agent .weaver .Weaver ;
5+ import com .newrelic .instrumentation .spring .web .async .Utils ;
6+
7+ @ Weave
8+ public abstract class SimpleAsyncTaskExecutor {
9+
10+
11+ protected void doExecute (Runnable task ) {
12+ Runnable wrapper = Utils .getWrappedRunnable (task );
13+ if (wrapper != null ) {
14+ task = wrapper ;
15+ }
16+ Weaver .callOriginal ();
17+ }
18+ }
Original file line number Diff line number Diff line change 1+ package org .springframework .core .task .support ;
2+
3+ import java .util .concurrent .Callable ;
4+ import java .util .concurrent .Future ;
5+
6+ import org .springframework .util .concurrent .ListenableFuture ;
7+
8+ import com .newrelic .api .agent .weaver .Weave ;
9+ import com .newrelic .api .agent .weaver .Weaver ;
10+ import com .newrelic .instrumentation .spring .web .async .Utils ;
11+
12+ @ Weave
13+ public abstract class TaskExecutorAdapter {
14+
15+ public void execute (Runnable task ) {
16+ Runnable wrapper = Utils .getWrappedRunnable (task );
17+ if (wrapper != null ) {
18+ task = wrapper ;
19+ }
20+ Weaver .callOriginal ();
21+ }
22+
23+ public Future <?> submit (Runnable task ) {
24+ Runnable wrapper = Utils .getWrappedRunnable (task );
25+ if (wrapper != null ) {
26+ task = wrapper ;
27+ }
28+ return Weaver .callOriginal ();
29+ }
30+
31+ public <T > Future <T > submit (Callable <T > task ) {
32+ Callable <T > wrapper = Utils .getWrappedCallable (task );
33+ if (wrapper != null ) {
34+ task = wrapper ;
35+ }
36+ return Weaver .callOriginal ();
37+ }
38+
39+ public ListenableFuture <?> submitListenable (Runnable task ) {
40+ Runnable wrapper = Utils .getWrappedRunnable (task );
41+ if (wrapper != null ) {
42+ task = wrapper ;
43+ }
44+ return Weaver .callOriginal ();
45+ }
46+
47+ public <T > ListenableFuture <T > submitListenable (Callable <T > task ) {
48+ Callable <T > wrapper = Utils .getWrappedCallable (task );
49+ if (wrapper != null ) {
50+ task = wrapper ;
51+ }
52+ return Weaver .callOriginal ();
53+ }
54+ }
Original file line number Diff line number Diff line change 1+
2+ // Build.gradle generated for instrumentation module spring-web-async
3+
4+ apply plugin : ' java'
5+
6+ dependencies {
7+ implementation ' org.springframework:spring-web:5.0.0.RELEASE'
8+
9+ // New Relic Java Agent dependencies
10+ implementation ' com.newrelic.agent.java:newrelic-agent:6.4.0'
11+ implementation ' com.newrelic.agent.java:newrelic-api:6.4.0'
12+ implementation fileTree(include : [' *.jar' ], dir : ' ../libs' )
13+ implementation fileTree(include : [' *.jar' ], dir : ' ../test-lib' )
14+ }
15+
16+ jar {
17+ manifest {
18+ attributes ' Implementation-Title' : ' com.newrelic.instrumentation.spring-web-async'
19+ attributes ' Implementation-Vendor' : ' New Relic'
20+ attributes ' Implementation-Vendor-Id' : ' com.newrelic'
21+ attributes ' Implementation-Version' : 1.0
22+ }
23+ }
24+
25+ verifyInstrumentation {
26+ passes ' org.springframework:spring-web:[5.0.0.RELEASE,)'
27+ }
Original file line number Diff line number Diff line change 1+ package com .newrelic .instrumentation .spring .web .async ;
2+
3+ import java .util .concurrent .Callable ;
4+
5+ import com .newrelic .agent .bridge .AgentBridge ;
6+ import com .newrelic .api .agent .Token ;
7+ import com .newrelic .api .agent .Trace ;
8+
9+ public class NRCallableWrapper <V > implements Callable <V > {
10+
11+ private static boolean isTransformed = false ;
12+ private Callable <V > delegate = null ;
13+ private Token token = null ;
14+
15+ public NRCallableWrapper (Callable <V > d , Token t ) {
16+ if (!isTransformed ) {
17+ AgentBridge .instrumentation .retransformUninstrumentedClass (getClass ());
18+ isTransformed = true ;
19+ }
20+ delegate = d ;
21+ token = t ;
22+ }
23+
24+ @ Override
25+ @ Trace (async = true )
26+ public V call () throws Exception {
27+ if (token != null ) {
28+ token .link ();
29+ }
30+ return delegate .call ();
31+ }
32+
33+ public void linkToken () {
34+ if (token != null ) {
35+ token .link ();
36+ }
37+ }
38+
39+ public void expireToken () {
40+ if (token != null ) {
41+ token .expire ();
42+ token = null ;
43+ }
44+ }
45+ }
You can’t perform that action at this time.
0 commit comments