Skip to content

Commit e06c126

Browse files
committed
merged with suspend_fixes
2 parents c47820c + baa0439 commit e06c126

File tree

3 files changed

+108
-0
lines changed

3 files changed

+108
-0
lines changed
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+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.newrelic.instrumentation.kotlin.coroutines.tracing;
2+
3+
import java.lang.instrument.IllegalClassFormatException;
4+
import java.security.ProtectionDomain;
5+
import java.util.HashMap;
6+
import java.util.Map;
7+
import java.util.logging.Level;
8+
9+
import com.newrelic.agent.deps.org.objectweb.asm.commons.Method;
10+
import com.newrelic.agent.instrumentation.InstrumentationType;
11+
import com.newrelic.agent.instrumentation.classmatchers.ClassAndMethodMatcher;
12+
import com.newrelic.agent.instrumentation.classmatchers.OptimizedClassMatcher.Match;
13+
import com.newrelic.agent.instrumentation.classmatchers.OptimizedClassMatcherBuilder;
14+
import com.newrelic.agent.instrumentation.context.ClassMatchVisitorFactory;
15+
import com.newrelic.agent.instrumentation.context.ContextClassTransformer;
16+
import com.newrelic.agent.instrumentation.context.InstrumentationContext;
17+
import com.newrelic.agent.instrumentation.context.InstrumentationContextManager;
18+
import com.newrelic.agent.instrumentation.methodmatchers.MethodMatcher;
19+
import com.newrelic.agent.instrumentation.tracing.TraceDetailsBuilder;
20+
import com.newrelic.api.agent.NewRelic;
21+
22+
public class SuspendClassTransformer implements ContextClassTransformer {
23+
24+
private Map<String, ClassMatchVisitorFactory> matchers = null;
25+
private final InstrumentationContextManager contextMgr;
26+
27+
public SuspendClassTransformer(InstrumentationContextManager mgr) {
28+
contextMgr = mgr;
29+
matchers = new HashMap<>();
30+
}
31+
32+
protected ClassMatchVisitorFactory addMatcher(ClassAndMethodMatcher matcher) {
33+
NewRelic.getAgent().getLogger().log(Level.FINE, "Adding matcher {0} to service classtransformer", matcher);
34+
OptimizedClassMatcherBuilder builder = OptimizedClassMatcherBuilder.newBuilder();
35+
builder.addClassMethodMatcher(matcher);
36+
ClassMatchVisitorFactory matchVistor = builder.build();
37+
matchers.put(matcher.getClass().getSimpleName(), matchVistor);
38+
contextMgr.addContextClassTransformer(matchVistor, this);
39+
return matchVistor;
40+
}
41+
42+
protected void removeMatcher(ClassAndMethodMatcher matcher) {
43+
ClassMatchVisitorFactory matchVisitor = matchers.remove(matcher.getClass().getSimpleName());
44+
if(matchVisitor != null) {
45+
contextMgr.removeMatchVisitor(matchVisitor);
46+
}
47+
}
48+
49+
@Override
50+
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
51+
ProtectionDomain protectionDomain, byte[] classfileBuffer, InstrumentationContext context, Match match)
52+
throws IllegalClassFormatException {
53+
for(Method method : match.getMethods()) {
54+
for(ClassAndMethodMatcher matcher : match.getClassMatches().keySet()) {
55+
if (matcher.getMethodMatcher().matches(MethodMatcher.UNSPECIFIED_ACCESS, method.getName(),
56+
method.getDescriptor(), match.getMethodAnnotations(method))) {
57+
58+
// context.putTraceAnnotation(method, TraceDetailsBuilder.newBuilder().setTracerFactoryName(SuspendTracerFactory.TRACER_FACTORY_NAME).setDispatcher(true).setInstrumentationSourceName("CoroutinesCore").setInstrumentationType(InstrumentationType.TraceAnnotation).build());
59+
}
60+
61+
}
62+
}
63+
return null;
64+
}
65+
66+
}

settings.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ include 'Kotlin-Coroutines_1.5'
77
include 'Kotlin-Coroutines_1.7'
88
include 'Kotlin-Coroutines_1.9'
99
include 'kroto-plus-coroutines'
10+
include 'Kotlin-Coroutines-Suspends'

0 commit comments

Comments
 (0)