Skip to content

Commit 321ae11

Browse files
committed
baseline
1 parent 7bbffa8 commit 321ae11

File tree

12 files changed

+124
-13
lines changed

12 files changed

+124
-13
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.newrelic.instrumentation.kotlin.coroutines.tracing;
2+
3+
import com.newrelic.agent.Transaction;
4+
import com.newrelic.agent.TransactionActivity;
5+
import com.newrelic.agent.tracers.ClassMethodSignature;
6+
import com.newrelic.agent.tracers.DefaultTracer;
7+
import com.newrelic.agent.tracers.Tracer;
8+
import com.newrelic.agent.tracers.metricname.SimpleMetricNameFormat;
9+
import com.newrelic.api.agent.NewRelic;
10+
import com.newrelic.instrumentation.kotlin.coroutines.Utils;
11+
12+
public class KotlinCoroutineTracer extends DefaultTracer {
13+
14+
public KotlinCoroutineTracer(Transaction transaction, ClassMethodSignature sig, Object object) {
15+
super(transaction, sig, object, new SimpleMetricNameFormat("Custom/SuspendFunction/"+Utils.getSuspendString(object.toString(), object)));
16+
}
17+
18+
@Override
19+
public void performFinishWork(long finishTime, int opcode, Object returnValue) {
20+
TransactionActivity txa = getTransactionActivity();
21+
if(txa != null) {
22+
Tracer lastTracer = txa.getLastTracer();
23+
if(!lastTracer.equals(this)) {
24+
NewRelic.recordMetric("Kotlin/Coroutines/SuspendTracer/InconsistentState", 1.0F);
25+
return;
26+
}
27+
}
28+
super.performFinishWork(finishTime, opcode, returnValue);
29+
}
30+
31+
}

Kotlin-Coroutines-Suspends/src/main/java/com/newrelic/instrumentation/kotlin/coroutines/tracing/SuspendClassMatcher.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.Collection;
55

66
import com.newrelic.agent.deps.org.objectweb.asm.ClassReader;
7+
import com.newrelic.agent.instrumentation.classmatchers.AndClassMatcher;
78
import com.newrelic.agent.instrumentation.classmatchers.ChildClassMatcher;
89
import com.newrelic.agent.instrumentation.classmatchers.ClassMatcher;
910
import com.newrelic.agent.instrumentation.classmatchers.ExactClassMatcher;
@@ -12,27 +13,29 @@
1213
public class SuspendClassMatcher extends ClassMatcher {
1314

1415
ChildClassMatcher matcher;
15-
NotMatcher nrMatcher;
16+
AndClassMatcher allMatcher;
1617

1718
public SuspendClassMatcher() {
1819
matcher = new ChildClassMatcher("kotlin.coroutines.jvm.internal.BaseContinuationImpl",false);
19-
nrMatcher = new NotMatcher(new ExactClassMatcher("com.newrelic.instrumentation.kotlin.coroutines.NRWrappedSuspend"));
20-
}
20+
allMatcher = new AndClassMatcher(new NotMatcher(new ExactClassMatcher("com.newrelic.instrumentation.kotlin.coroutines_17.NRContinuationWrapper")),
21+
new NotMatcher(new ExactClassMatcher("com.newrelic.instrumentation.kotlin.coroutines_15.NRContinuationWrapper")),
22+
new NotMatcher(new ExactClassMatcher("com.newrelic.instrumentation.kotlin.coroutines_14.NRContinuationWrapper")),
23+
new NotMatcher(new ExactClassMatcher("com.newrelic.instrumentation.kotlin.coroutines.NRContinuationWrapper"))); }
2124

2225
@Override
2326
public boolean isMatch(ClassLoader loader, ClassReader cr) {
24-
return matcher.isMatch(loader, cr) && nrMatcher.isMatch(loader, cr);
27+
return matcher.isMatch(loader, cr) && allMatcher.isMatch(loader, cr);
2528
}
2629

2730
@Override
2831
public boolean isMatch(Class<?> clazz) {
29-
return matcher.isMatch(clazz) && nrMatcher.isMatch(clazz);
32+
return matcher.isMatch(clazz) && allMatcher.isMatch(clazz);
3033
}
3134

3235
@Override
3336
public Collection<String> getClassNames() {
3437
Collection<String> childClasses = matcher.getClassNames();
35-
Collection<String> nrClasses = nrMatcher.getClassNames();
38+
Collection<String> nrClasses = allMatcher.getClassNames();
3639
if(childClasses == null && nrClasses == null) return null;
3740

3841
ArrayList<String> list = new ArrayList<>();

Kotlin-Coroutines-Suspends/src/main/java/com/newrelic/instrumentation/kotlin/coroutines/tracing/SuspendTracerFactory.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,9 @@
22

33
import com.newrelic.agent.Transaction;
44
import com.newrelic.agent.tracers.ClassMethodSignature;
5-
import com.newrelic.agent.tracers.DefaultTracer;
65
import com.newrelic.agent.tracers.Tracer;
76
import com.newrelic.agent.tracers.TracerFactory;
8-
import com.newrelic.agent.tracers.metricname.SimpleMetricNameFormat;
97
import com.newrelic.instrumentation.kotlin.coroutines.SuspendIgnores;
10-
import com.newrelic.instrumentation.kotlin.coroutines.Utils;
118

129
public class SuspendTracerFactory implements TracerFactory {
1310

@@ -19,7 +16,7 @@ public Tracer getTracer(Transaction transaction, ClassMethodSignature sig, Objec
1916
if(SuspendIgnores.ignoreSuspend(object)) {
2017
return null;
2118
}
22-
return new DefaultTracer(transaction, sig, object, new SimpleMetricNameFormat("Custom/SuspendFunction/"+Utils.getSuspendString(object.toString(), object)));
19+
return new KotlinCoroutineTracer(transaction, sig, object);
2320
}
2421

2522
}

Kotlin-Coroutines_1.4/src/main/java/com/newrelic/instrumentation/kotlin/coroutines_14/NRContinuationWrapper.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ public void resumeWith(Object p0) {
4141
}
4242
Token t = Utils.getToken(getContext());
4343
if(t != null) {
44-
t.link();
44+
if(Utils.continueWithLink()) {
45+
t.link();
46+
} else {
47+
NewRelic.recordMetric("Kotlin/Coroutines/ContinuationWrapper/TokenLinkFailed", 1.0F);
48+
}
4549
}
4650
if(delegate != null) {
4751
delegate.resumeWith(p0);

Kotlin-Coroutines_1.4/src/main/java/com/newrelic/instrumentation/kotlin/coroutines_14/Utils.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.List;
55
import java.util.logging.Level;
66

7+
import com.newrelic.agent.Transaction;
78
import com.newrelic.agent.config.AgentConfig;
89
import com.newrelic.agent.config.AgentConfigListener;
910
import com.newrelic.agent.service.ServiceFactory;
@@ -222,4 +223,13 @@ public static <T> String getContinuationString(Continuation<T> continuation) {
222223

223224
return null;
224225
}
226+
227+
public static boolean continueWithLink() {
228+
Transaction transaction = Transaction.getTransaction(false);
229+
if(transaction != null) {
230+
return transaction.getTransactionTimer() != null;
231+
}
232+
return true;
233+
}
234+
225235
}

Kotlin-Coroutines_1.5/src/main/java/com/newrelic/instrumentation/kotlin/coroutines_15/NRContinuationWrapper.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ public void resumeWith(Object p0) {
4141
}
4242
Token t = Utils.getToken(getContext());
4343
if(t != null) {
44-
t.link();
44+
if(Utils.continueWithLink()) {
45+
t.link();
46+
} else {
47+
NewRelic.recordMetric("Kotlin/Coroutines/ContinuationWrapper/TokenLinkFailed", 1.0F);
48+
}
4549
}
4650
if(delegate != null) {
4751
delegate.resumeWith(p0);

Kotlin-Coroutines_1.5/src/main/java/com/newrelic/instrumentation/kotlin/coroutines_15/Utils.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.List;
55
import java.util.logging.Level;
66

7+
import com.newrelic.agent.Transaction;
78
import com.newrelic.agent.config.AgentConfig;
89
import com.newrelic.agent.config.AgentConfigListener;
910
import com.newrelic.agent.service.ServiceFactory;
@@ -222,4 +223,14 @@ public static <T> String getContinuationString(Continuation<T> continuation) {
222223

223224
return null;
224225
}
226+
227+
public static boolean continueWithLink() {
228+
Transaction transaction = Transaction.getTransaction(false);
229+
if(transaction != null) {
230+
return transaction.getTransactionTimer() != null;
231+
}
232+
return true;
233+
}
234+
235+
225236
}

Kotlin-Coroutines_1.7/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,6 @@ verifyInstrumentation {
3434
excludeRegex '.*-rc'
3535
excludeRegex '.*-RC'
3636
excludeRegex '.*-RC[0-9]'
37+
excludeRegex '.*-RC.[0-9]'
3738
excludeRegex '.*-Beta'
3839
}

Kotlin-Coroutines_1.7/src/main/java/com/newrelic/instrumentation/kotlin/coroutines_17/NRContinuationWrapper.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ public void resumeWith(Object p0) {
4141
}
4242
Token t = Utils.getToken(getContext());
4343
if(t != null) {
44-
t.link();
44+
if(Utils.continueWithLink()) {
45+
t.link();
46+
} else {
47+
NewRelic.recordMetric("Kotlin/Coroutines/ContinuationWrapper/TokenLinkFailed", 1.0F);
48+
}
4549
}
4650
if(delegate != null) {
4751
delegate.resumeWith(p0);

Kotlin-Coroutines_1.7/src/main/java/com/newrelic/instrumentation/kotlin/coroutines_17/Utils.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.List;
55
import java.util.logging.Level;
66

7+
import com.newrelic.agent.Transaction;
78
import com.newrelic.agent.config.AgentConfig;
89
import com.newrelic.agent.config.AgentConfigListener;
910
import com.newrelic.agent.service.ServiceFactory;
@@ -222,4 +223,14 @@ public static <T> String getContinuationString(Continuation<T> continuation) {
222223

223224
return null;
224225
}
226+
227+
public static boolean continueWithLink() {
228+
Transaction transaction = Transaction.getTransaction(false);
229+
if(transaction != null) {
230+
return transaction.getTransactionTimer() != null;
231+
}
232+
return true;
233+
}
234+
235+
225236
}

0 commit comments

Comments
 (0)