Skip to content

Commit 10bd2f7

Browse files
committed
baseline 8-7
1 parent f168d29 commit 10bd2f7

File tree

87 files changed

+2161
-1059
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+2161
-1059
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
// Build.gradle generated for instrumentation module Kotlin-Coroutines-Core
3+
4+
apply plugin: 'java'
5+
6+
dependencies {
7+
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.0'
8+
9+
// New Relic Java Agent dependencies
10+
implementation 'com.newrelic.agent.java:newrelic-agent:6.4.1'
11+
implementation 'com.newrelic.agent.java:newrelic-api:6.4.1'
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.labs.Kotlin-Coroutines-Suspends'
19+
attributes 'Implementation-Vendor': 'New Relic Labs'
20+
attributes 'Implementation-Vendor-Id': 'com.newrelic.labs'
21+
attributes 'Implementation-Version': 2.0
22+
attributes 'Agent-Class': 'com.newrelic.instrumentation.kotlin.coroutines.tracing.CoroutinesPreMain'
23+
}
24+
}
25+
26+
verifyInstrumentation {
27+
// Verifier plugin documentation:
28+
// https://github.com/newrelic/newrelic-gradle-verify-instrumentation
29+
// Example:
30+
// passes 'javax.servlet:servlet-api:[2.2,2.5]'
31+
// exclude 'javax.servlet:servlet-api:2.4.public_draft'
32+
passes 'org.jetbrains.kotlinx:kotlinx-coroutines-core:[1.4.0,)'
33+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package com.newrelic.instrumentation.kotlin.coroutines;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.logging.Level;
6+
import java.util.regex.Matcher;
7+
import java.util.regex.Pattern;
8+
9+
import com.newrelic.api.agent.Config;
10+
import com.newrelic.api.agent.NewRelic;
11+
12+
public class SuspendIgnores {
13+
14+
private static final List<String> ignoredSuspends = new ArrayList<String>();
15+
private static final String SUSPENDSIGNORECONFIG = "Coroutines.ignores.suspends";
16+
private static final List<String> ignoredPackages = new ArrayList<>();
17+
18+
static {
19+
Config config = NewRelic.getAgent().getConfig();
20+
String value = config.getValue(SUSPENDSIGNORECONFIG);
21+
init(value);
22+
ignoredPackages.add("kotlin.coroutines");
23+
ignoredPackages.add("kotlinx.coroutines");
24+
}
25+
26+
private static void init(String value) {
27+
if(value != null && !value.isEmpty()) {
28+
String[] ignores = value.split(",");
29+
for(String ignore : ignores) {
30+
addIgnore(ignore);
31+
}
32+
}
33+
}
34+
35+
public static void reset(Config config) {
36+
ignoredSuspends.clear();
37+
String value = config.getValue(SUSPENDSIGNORECONFIG);
38+
init(value);
39+
}
40+
41+
public static void addIgnore(String s) {
42+
if(!ignoredSuspends.contains(s)) {
43+
ignoredSuspends.add(s);
44+
NewRelic.getAgent().getLogger().log(Level.FINE, "Will ignore suspends named {0}", s);
45+
}
46+
}
47+
48+
public static boolean ignoreSuspend(String className) {
49+
String classNameMod = className.replace('/', '.');
50+
int index = classNameMod.lastIndexOf('.');
51+
String packageName = classNameMod.substring(0, index);
52+
53+
for(String ignored : ignoredPackages) {
54+
if(packageName.startsWith(ignored)) {
55+
return true;
56+
}
57+
}
58+
59+
boolean classNameMatch = ignoredSuspends.contains(classNameMod);
60+
61+
if(classNameMatch) {
62+
return true;
63+
}
64+
65+
for(String s : ignoredSuspends) {
66+
Pattern pattern = Pattern.compile(s);
67+
Matcher matcher = pattern.matcher(classNameMod);
68+
if(matcher.matches()) {
69+
70+
return true;
71+
}
72+
}
73+
74+
return false;
75+
}
76+
77+
public static boolean ignoreSuspend(Class<?> clazz) {
78+
79+
String className = clazz.getName();
80+
String packageName = clazz.getPackage().getName();
81+
82+
for(String ignored : ignoredPackages) {
83+
if(packageName.startsWith(ignored)) {
84+
return true;
85+
}
86+
}
87+
88+
boolean classNameMatch = ignoredSuspends.contains(className);
89+
90+
if(classNameMatch) {
91+
return true;
92+
}
93+
94+
for(String s : ignoredSuspends) {
95+
Pattern pattern = Pattern.compile(s);
96+
Matcher matcher = pattern.matcher(className);
97+
if(matcher.matches()) {
98+
return true;
99+
}
100+
}
101+
102+
return false;
103+
}
104+
105+
public static boolean ignoreSuspend(Object obj) {
106+
String objString = obj.toString();
107+
Class<?> clazz = obj.getClass();
108+
String className = clazz.getName();
109+
String packageName = clazz.getPackage().getName();
110+
111+
for(String ignored : ignoredPackages) {
112+
if(packageName.startsWith(ignored)) {
113+
return true;
114+
}
115+
}
116+
117+
boolean objStringMatch = ignoredSuspends.contains(objString);
118+
boolean classNameMatch = ignoredSuspends.contains(className);
119+
120+
if(objStringMatch || classNameMatch) {
121+
return true;
122+
}
123+
124+
for(String s : ignoredSuspends) {
125+
Pattern pattern = Pattern.compile(s);
126+
Matcher matcher1 = pattern.matcher(objString);
127+
Matcher matcher2 = pattern.matcher(className);
128+
if(matcher1.matches() || matcher2.matches()) return true;
129+
}
130+
131+
return false;
132+
}
133+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.newrelic.instrumentation.kotlin.coroutines;
2+
3+
import com.newrelic.agent.Transaction;
4+
import com.newrelic.agent.tracers.ClassMethodSignature;
5+
import com.newrelic.agent.tracers.DefaultTracer;
6+
import com.newrelic.agent.tracers.metricname.SimpleMetricNameFormat;
7+
8+
public class SuspendTracer extends DefaultTracer {
9+
10+
public SuspendTracer(Transaction transaction, ClassMethodSignature sig, Object object) {
11+
super(transaction, sig, object, new SimpleMetricNameFormat("Custom/SuspendFunction/"+Utils.getSuspendString(object.toString(), object)));
12+
}
13+
14+
15+
16+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.newrelic.instrumentation.kotlin.coroutines;
2+
3+
import com.newrelic.agent.config.AgentConfig;
4+
import com.newrelic.agent.config.AgentConfigListener;
5+
import com.newrelic.agent.service.ServiceFactory;
6+
import com.newrelic.api.agent.Config;
7+
import com.newrelic.api.agent.NewRelic;
8+
9+
public class Utils implements AgentConfigListener {
10+
11+
private static final Utils INSTANCE = new Utils();
12+
public static final String CREATEMETHOD1 = "Continuation at kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt$createCoroutineUnintercepted$$inlined$createCoroutineFromSuspendFunction$IntrinsicsKt__IntrinsicsJvmKt$4";
13+
public static final String CREATEMETHOD2 = "Continuation at kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt$createCoroutineUnintercepted$$inlined$createCoroutineFromSuspendFunction$IntrinsicsKt__IntrinsicsJvmKt$3";
14+
public static String sub = "createCoroutineFromSuspendFunction";
15+
private static final String CONT_LOC = "Continuation at";
16+
17+
static {
18+
ServiceFactory.getConfigService().addIAgentConfigListener(INSTANCE);
19+
Config config = NewRelic.getAgent().getConfig();
20+
SuspendIgnores.reset(config);
21+
}
22+
23+
@Override
24+
public void configChanged(String appName, AgentConfig agentConfig) {
25+
SuspendIgnores.reset(agentConfig);
26+
}
27+
28+
public static String getSuspendString(String cont_string, Object obj) {
29+
if(cont_string.equals(CREATEMETHOD1) || cont_string.equals(CREATEMETHOD2)) return sub;
30+
if(cont_string.startsWith(CONT_LOC)) {
31+
return cont_string;
32+
}
33+
34+
int index = cont_string.indexOf('@');
35+
if(index > -1) {
36+
return cont_string.substring(0, index);
37+
}
38+
39+
return obj.getClass().getName();
40+
}
41+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package kotlin.coroutines.jvm.internal;
2+
3+
import java.util.logging.Level;
4+
5+
import com.newrelic.api.agent.Logger;
6+
import com.newrelic.api.agent.NewRelic;
7+
import com.newrelic.api.agent.Trace;
8+
import com.newrelic.api.agent.weaver.MatchType;
9+
import com.newrelic.api.agent.weaver.Weave;
10+
import com.newrelic.api.agent.weaver.Weaver;
11+
12+
import kotlin.coroutines.Continuation;
13+
14+
@Weave(type = MatchType.BaseClass)
15+
public abstract class BaseContinuationImpl {
16+
17+
public abstract StackTraceElement getStackTraceElement();
18+
public abstract Continuation<Object> getCompletion();
19+
public abstract kotlin.coroutines.jvm.internal.CoroutineStackFrame getCallerFrame();
20+
21+
@Trace(dispatcher = true)
22+
protected Object invokeSuspend(Object obj) {
23+
Logger LOGGER = NewRelic.getAgent().getLogger();
24+
StackTraceElement element = getStackTraceElement();
25+
LOGGER.log(Level.FINE, "Call to {0}.invokeSuspend, stacktrace element {1}", getClass().getName(), element);
26+
CoroutineStackFrame caller = getCallerFrame();
27+
LOGGER.log(Level.FINE, "Call to {0}.invokeSuspend, caller stacktrace element {1}", getClass().getName(), caller != null ? caller.getStackTraceElement() : null);
28+
29+
Object result = Weaver.callOriginal();
30+
LOGGER.log(Level.FINE, "Call to {0}.invokeSuspend, input is {1}, output is {2}", getClass().getName(), obj.getClass().getName(), result.getClass().getName());
31+
32+
return result;
33+
}
34+
}

Kotlin-Coroutines_1.4/.DS_Store

6 KB
Binary file not shown.

Kotlin-Coroutines_1.4/build.gradle

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

2424
verifyInstrumentation {
25-
passes 'org.jetbrains.kotlinx:kotlinx-coroutines-core:[1.4.0,1.5.0)'
26-
passes 'org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:[1.4.0,1.5.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-.*'

Kotlin-Coroutines_1.4/java/com/newrelic/instrumentation/kotlin/coroutines/NRContinuationWrapper.java

Lines changed: 0 additions & 43 deletions
This file was deleted.

Kotlin-Coroutines_1.4/java/com/newrelic/instrumentation/kotlin/coroutines/NRCoroutineToken.java

Lines changed: 0 additions & 51 deletions
This file was deleted.

0 commit comments

Comments
 (0)