Skip to content

added ignores for CoroutineScope to ignore selected Coroutines, neede… #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@
import kotlin.coroutines.jvm.internal.BaseContinuationImpl;
import kotlinx.coroutines.AbstractCoroutine;
import kotlinx.coroutines.CoroutineName;
import kotlinx.coroutines.CoroutineScope;
import kotlinx.coroutines.DispatchedTask;

public class Utils implements AgentConfigListener {

private static final List<String> ignoredContinuations = new ArrayList<String>();
private static final List<String> ignoredScopes = new ArrayList<>();
private static final String CONTIGNORECONFIG = "Coroutines.ignores.continuations";
private static final String SCOPESIGNORECONFIG = "Coroutines.ignores.scopes";
private static final String DISPATCHEDIGNORECONFIG = "Coroutines.ignores.dispatched";
private static final String DELAYED_ENABLED_CONFIG = "Coroutines.delayed.enabled";

Expand Down Expand Up @@ -95,6 +98,32 @@ private static void loadConfig(Config config) {
if (ignores != null && !ignores.isEmpty()) {
DispatchedTaskIgnores.configure(ignores);
}
ignores = config.getValue(SCOPESIGNORECONFIG);
if (ignores != null && !ignores.isEmpty()) {
ignoredScopes.clear();
String[] ignoresList = ignores.split(",");

for(String ignore : ignoresList) {
if (!ignoredScopes.contains(ignore)) {
ignoredScopes.add(ignore);
NewRelic.getAgent().getLogger().log(Level.FINE, "Will ignore CoroutineScopes named {0}", ignore);
}
}
} else if(!ignoredScopes.isEmpty()) {
ignoredScopes.clear();
}

}

public static boolean ignoreScope(CoroutineScope scope) {
CoroutineContext ctx = scope.getCoroutineContext();
String name = getCoroutineName(ctx);
String className = scope.getClass().getName();
return ignoreScope(className) || ignoreScope(name);
}

public static boolean ignoreScope(String coroutineScope) {
return ignoredScopes.contains(coroutineScope);
}

public static boolean ignoreContinuation(String cont_string) {
Expand Down Expand Up @@ -193,4 +222,4 @@ public static <T> String getContinuationString(Continuation<T> continuation) {

return null;
}
}
}
112 changes: 73 additions & 39 deletions Kotlin-Coroutines_1.4/src/main/java/kotlinx/coroutines/BuildersKt.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kotlinx.coroutines;

import com.newrelic.api.agent.NewRelic;
import com.newrelic.api.agent.Token;
import com.newrelic.api.agent.Trace;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
Expand All @@ -21,9 +22,14 @@ public class BuildersKt {

@Trace(dispatcher = true)
public static final <T> T runBlocking(CoroutineContext context, Function2<? super CoroutineScope, ? super Continuation<? super T>, ? extends Object> block) {
NRCoroutineToken nrContextToken = Utils.setToken(context);
if(nrContextToken != null) {
context = context.plus(nrContextToken);
Token token = Utils.getToken(context);
if(token != null) {
token.link();
} else {
NRCoroutineToken nrContextToken = Utils.setToken(context);
if(nrContextToken != null) {
context = context.plus(nrContextToken);
}
}
String name = Utils.getCoroutineName(context);
if(name != null) {
Expand All @@ -43,23 +49,32 @@ public static final <T> T runBlocking(CoroutineContext context, Function2<? supe

@Trace(dispatcher = true)
public static final <T> Deferred<T> async(CoroutineScope scope, CoroutineContext context, CoroutineStart cStart, Function2<? super CoroutineScope, ? super Continuation<? super T>, ? extends Object> block) {
String name = Utils.getCoroutineName(context);
if(name == null) {
name = Utils.getCoroutineName(scope.getCoroutineContext());
}
if(name != null) {
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Builders","async",name);
} else {
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Builders","async");
}
if (!Utils.ignoreScope(scope)) {
String name = Utils.getCoroutineName(context);
if(name == null) {
name = Utils.getCoroutineName(scope.getCoroutineContext());
}
if(name != null) {
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Builders","async",name);
} else {
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Builders","async");
}

NRCoroutineToken nrContextToken = Utils.setToken(context);
if(nrContextToken != null) {
context = context.plus(nrContextToken);
}
if(!(block instanceof NRFunction2Wrapper)) {
NRFunction2Wrapper<? super CoroutineScope, ? super Continuation<? super T>, ? extends Object> wrapper = new NRFunction2Wrapper(block);
block = wrapper;
Token token = Utils.getToken(context);
if(token != null) {
token.link();
} else {
NRCoroutineToken nrContextToken = Utils.setToken(context);
if(nrContextToken != null) {
context = context.plus(nrContextToken);
}
}
if(!(block instanceof NRFunction2Wrapper)) {
NRFunction2Wrapper<? super CoroutineScope, ? super Continuation<? super T>, ? extends Object> wrapper = new NRFunction2Wrapper(block);
block = wrapper;
}
} else {
NewRelic.getAgent().getTransaction().ignore();
}
return Weaver.callOriginal();
}
Expand All @@ -86,24 +101,38 @@ public static final <T> Object invoke(CoroutineDispatcher dispatcher, Function2<

@Trace(dispatcher = true)
public static final kotlinx.coroutines.Job launch(CoroutineScope scope, CoroutineContext context, CoroutineStart cStart, Function2<? super CoroutineScope, ? super Continuation<? super Unit>, ? extends Object> block) {
NewRelic.getAgent().getTracedMethod().addCustomAttribute("CoroutineStart", cStart.name());
String name = Utils.getCoroutineName(context);
if(name == null) {
name = Utils.getCoroutineName(scope.getCoroutineContext());
}
if(name != null) {
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Builders","launch",name);
if (!Utils.ignoreScope(scope)) {
NewRelic.getAgent().getTracedMethod().addCustomAttribute("CoroutineStart", cStart.name());
NewRelic.getAgent().getTracedMethod().addCustomAttribute("CoroutineScope-Class", scope.getClass().getName());

String name = Utils.getCoroutineName(context);
if (name == null) {
name = Utils.getCoroutineName(scope.getCoroutineContext());
}
if (name != null) {
NewRelic.getAgent().getTracedMethod().setMetricName("Custom", "Builders", "launch", name);
NewRelic.getAgent().getTracedMethod().addCustomAttribute("CoroutineName", name);
} else {
NewRelic.getAgent().getTracedMethod().setMetricName("Custom", "Builders", "launch");
NewRelic.getAgent().getTracedMethod().addCustomAttribute("CoroutineName", "Could not determine");
}
NewRelic.getAgent().getTracedMethod().addCustomAttribute("Block", block.toString());
Token token = Utils.getToken(context);
if(token != null) {
token.link();
} else {
NRCoroutineToken nrContextToken = Utils.setToken(context);
if(nrContextToken != null) {
context = context.plus(nrContextToken);
}
}
if (!(block instanceof NRFunction2Wrapper)) {
NRFunction2Wrapper<? super CoroutineScope, ? super Continuation<? super Unit>, ? extends Object> wrapper = new NRFunction2Wrapper(
block);
block = wrapper;
}
} else {
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","Builders","launch");
}
NewRelic.getAgent().getTracedMethod().addCustomAttribute("Block", block.toString());
NRCoroutineToken nrContextToken = Utils.setToken(context);
if(nrContextToken != null) {
context = context.plus(nrContextToken);
}
if(!(block instanceof NRFunction2Wrapper)) {
NRFunction2Wrapper<? super CoroutineScope, ? super Continuation<? super Unit>, ? extends Object> wrapper = new NRFunction2Wrapper(block);
block = wrapper;
NewRelic.getAgent().getTransaction().ignore();
}
Job j = Weaver.callOriginal();
return j;
Expand All @@ -121,9 +150,14 @@ public static final <T> Object withContext(CoroutineContext context,Function2<?
NewRelic.getAgent().getTracedMethod().addCustomAttribute("Completion", completion.toString());
}

NRCoroutineToken nrContextToken = Utils.setToken(context);
if(nrContextToken != null) {
context = context.plus(nrContextToken);
Token token = Utils.getToken(context);
if(token != null) {
token.link();
} else {
NRCoroutineToken nrContextToken = Utils.setToken(context);
if(nrContextToken != null) {
context = context.plus(nrContextToken);
}
}
if(!(block instanceof NRFunction2Wrapper)) {
NRFunction2Wrapper<? super CoroutineScope, ? super Continuation<? super T>, ? extends Object> wrapper = new NRFunction2Wrapper(block);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@
import kotlin.coroutines.jvm.internal.BaseContinuationImpl;
import kotlinx.coroutines.AbstractCoroutine;
import kotlinx.coroutines.CoroutineName;
import kotlinx.coroutines.CoroutineScope;
import kotlinx.coroutines.DispatchedTask;

public class Utils implements AgentConfigListener {

private static final List<String> ignoredContinuations = new ArrayList<String>();
private static final List<String> ignoredScopes = new ArrayList<>();
private static final String CONTIGNORECONFIG = "Coroutines.ignores.continuations";
private static final String SCOPESIGNORECONFIG = "Coroutines.ignores.scopes";
private static final String DISPATCHEDIGNORECONFIG = "Coroutines.ignores.dispatched";
private static final String DELAYED_ENABLED_CONFIG = "Coroutines.delayed.enabled";

Expand Down Expand Up @@ -95,6 +98,32 @@ private static void loadConfig(Config config) {
if (ignores != null && !ignores.isEmpty()) {
DispatchedTaskIgnores.configure(ignores);
}
ignores = config.getValue(SCOPESIGNORECONFIG);
if (ignores != null && !ignores.isEmpty()) {
ignoredScopes.clear();
String[] ignoresList = ignores.split(",");

for(String ignore : ignoresList) {
if (!ignoredScopes.contains(ignore)) {
ignoredScopes.add(ignore);
NewRelic.getAgent().getLogger().log(Level.FINE, "Will ignore CoroutineScopes named {0}", ignore);
}
}
} else if(!ignoredScopes.isEmpty()) {
ignoredScopes.clear();
}

}

public static boolean ignoreScope(CoroutineScope scope) {
CoroutineContext ctx = scope.getCoroutineContext();
String name = getCoroutineName(ctx);
String className = scope.getClass().getName();
return ignoreScope(className) || ignoreScope(name);
}

public static boolean ignoreScope(String coroutineScope) {
return ignoredScopes.contains(coroutineScope);
}

public static boolean ignoreContinuation(String cont_string) {
Expand Down Expand Up @@ -193,4 +222,4 @@ public static <T> String getContinuationString(Continuation<T> continuation) {

return null;
}
}
}
Loading
Loading