Skip to content

Commit 658409e

Browse files
authored
Merge pull request #19 from newrelic/fix_1.7
Fix 1.7
2 parents 41d2164 + 01097dc commit 658409e

28 files changed

+1377
-2
lines changed

Kotlin-Coroutines_1.4/build.gradle

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ jar {
2222
}
2323

2424
verifyInstrumentation {
25-
passes 'org.jetbrains.kotlinx:kotlinx-coroutines-core:[1.4.0,)'
26-
passes 'org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:[1.4.0,)'
25+
passes 'org.jetbrains.kotlinx:kotlinx-coroutines-core:[1.4.0,1.7.0)'
26+
passes 'org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:[1.4.0,1.7.0)'
2727
excludeRegex '.*SNAPSHOT'
2828
excludeRegex '.*alpha'
2929
excludeRegex '.*-eap-.*'
3030
excludeRegex '.*-native-.*'
3131
excludeRegex '.*-M[0-9]'
3232
excludeRegex '.*-rc'
33+
excludeRegex '.*-RC'
34+
excludeRegex '.*-Beta'
3335
}

Kotlin-Coroutines_1.7/build.gradle

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
// Build.gradle generated for instrumentation module Kotlin-Coroutines_1.2
3+
4+
apply plugin: 'java'
5+
6+
targetCompatibility = JavaVersion.VERSION_1_9
7+
8+
dependencies {
9+
implementation group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: '1.7.0'
10+
11+
// New Relic Java Agent dependencies
12+
implementation 'com.newrelic.agent.java:newrelic-agent:6.0.0'
13+
implementation 'com.newrelic.agent.java:newrelic-api:6.0.0'
14+
implementation fileTree(include: ['*.jar'], dir: '../libs')
15+
}
16+
17+
jar {
18+
manifest {
19+
attributes 'Implementation-Title': 'com.newrelic.instrumentation.labs.Kotlin-Coroutines_1.7'
20+
attributes 'Implementation-Vendor': 'New Relic Labs'
21+
attributes 'Implementation-Vendor-Id': 'com.newrelic.labs'
22+
attributes 'Implementation-Version': 1.0
23+
}
24+
}
25+
26+
verifyInstrumentation {
27+
passes 'org.jetbrains.kotlinx:kotlinx-coroutines-core:[1.7.0,)'
28+
passes 'org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:[1.7.0,)'
29+
excludeRegex '.*SNAPSHOT'
30+
excludeRegex '.*alpha'
31+
excludeRegex '.*-eap-.*'
32+
excludeRegex '.*-native-.*'
33+
excludeRegex '.*-M[0-9]'
34+
excludeRegex '.*-rc'
35+
excludeRegex '.*-RC'
36+
excludeRegex '.*-Beta'
37+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.newrelic.instrumentation.kotlin.coroutines;
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+
import kotlin.coroutines.Continuation;
9+
import kotlin.coroutines.CoroutineContext;
10+
11+
public class NRContinuationWrapper<T> implements Continuation<T> {
12+
13+
private Continuation<T> delegate = null;
14+
private String name = null;
15+
private static boolean isTransformed = false;
16+
17+
public NRContinuationWrapper(Continuation<T> d, String n) {
18+
delegate = d;
19+
name = n;
20+
if(!isTransformed) {
21+
AgentBridge.instrumentation.retransformUninstrumentedClass(getClass());
22+
isTransformed = true;
23+
}
24+
}
25+
26+
@Override
27+
public CoroutineContext getContext() {
28+
return delegate.getContext();
29+
}
30+
31+
@Override
32+
@Trace(async=true)
33+
public void resumeWith(Object p0) {
34+
35+
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","ContinuationWrapper","resumeWith",name != null ? name : Utils.getCoroutineName(getContext(), delegate.getClass()));
36+
Token token = Utils.getToken(getContext());
37+
if(token != null) {
38+
token.link();
39+
}
40+
delegate.resumeWith(p0);
41+
}
42+
43+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.newrelic.instrumentation.kotlin.coroutines;
2+
3+
import com.newrelic.api.agent.Token;
4+
5+
import kotlin.coroutines.AbstractCoroutineContextElement;
6+
import kotlin.coroutines.CoroutineContext;
7+
8+
public class NRCoroutineToken extends AbstractCoroutineContextElement
9+
{
10+
public static Key key = new Key();
11+
12+
public NRCoroutineToken(Token t) {
13+
super(key);
14+
token = t;
15+
}
16+
17+
private Token token = null;
18+
19+
public static final class Key implements CoroutineContext.Key<NRCoroutineToken> {
20+
private Key() {}
21+
}
22+
23+
public Token getToken() {
24+
return token;
25+
}
26+
27+
@Override
28+
public int hashCode() {
29+
return token.hashCode();
30+
}
31+
32+
@Override
33+
public boolean equals(Object obj) {
34+
if(this != obj ) {
35+
if(obj instanceof NRCoroutineToken) {
36+
NRCoroutineToken t = (NRCoroutineToken)obj;
37+
return t.token == token;
38+
}
39+
} else {
40+
return true;
41+
}
42+
return false;
43+
}
44+
45+
@Override
46+
public String toString() {
47+
return "NRCoroutineToken";
48+
}
49+
50+
51+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.newrelic.instrumentation.kotlin.coroutines;
2+
3+
import com.newrelic.agent.bridge.AgentBridge;
4+
import com.newrelic.api.agent.NewRelic;
5+
import com.newrelic.api.agent.Trace;
6+
7+
import kotlin.jvm.functions.Function1;
8+
9+
public class NRFunction1Wrapper<P1,R> implements Function1<P1, R> {
10+
11+
private Function1<P1, R> delegate = null;
12+
private String name = null;
13+
private static boolean isTransformed = false;
14+
15+
public NRFunction1Wrapper(Function1<P1, R> d, String n) {
16+
delegate = d;
17+
name = n;
18+
if(!isTransformed) {
19+
isTransformed = true;
20+
AgentBridge.instrumentation.retransformUninstrumentedClass(getClass());
21+
}
22+
}
23+
24+
@Override
25+
@Trace(dispatcher=true)
26+
public R invoke(P1 p1) {
27+
if(name != null) NewRelic.getAgent().getTracedMethod().setMetricName("Custom","WrappedSuspend",name);
28+
if(delegate != null) {
29+
return delegate.invoke(p1);
30+
}
31+
return null;
32+
}
33+
34+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.newrelic.instrumentation.kotlin.coroutines;
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+
import kotlin.coroutines.Continuation;
9+
import kotlin.jvm.functions.Function2;
10+
11+
public class NRFunction2Wrapper<P1, P2, R> implements Function2<P1, P2, R> {
12+
13+
private Function2<P1, P2, R> delegate = null;
14+
private String name = null;
15+
private static boolean isTransformed = false;
16+
public Token token = null;
17+
18+
public NRFunction2Wrapper(Function2<P1, P2, R> d,String n) {
19+
delegate = d;
20+
name = n;
21+
if(!isTransformed) {
22+
isTransformed = true;
23+
AgentBridge.instrumentation.retransformUninstrumentedClass(getClass());
24+
}
25+
}
26+
27+
@SuppressWarnings({ "rawtypes", "unchecked" })
28+
@Override
29+
@Trace(async=true)
30+
public R invoke(P1 p1, P2 p2) {
31+
if(token != null) {
32+
token.linkAndExpire();
33+
token = null;
34+
}
35+
String nameStr = null;
36+
if(p2 instanceof Continuation) {
37+
Continuation continuation = (Continuation)p2;
38+
39+
if (!Utils.ignoreContinuation(continuation.getClass(), continuation.getContext())) {
40+
NRContinuationWrapper wrapper = new NRContinuationWrapper(continuation, name);
41+
p2 = (P2) wrapper;
42+
}
43+
}
44+
if(nameStr == null) {
45+
nameStr = name;
46+
}
47+
if(nameStr != null) {
48+
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","WrappedSuspend",nameStr);
49+
}
50+
if(delegate != null) {
51+
return delegate.invoke(p1, p2);
52+
}
53+
return null;
54+
}
55+
56+
}

0 commit comments

Comments
 (0)