Skip to content

newrelic/newrelic-java-kotlin-coroutines

New Relic Open Source community project banner.

GitHub forks GitHub stars GitHub watchers

GitHub all releases GitHub release (latest by date) GitHub last commit GitHub Release Date

GitHub issues GitHub issues closed GitHub pull requests GitHub pull requests closed

New Relic Java Instrumentation for Kotlin Coroutines

Provides instrumentation for Kotlin Coroutines. In particular it will trace the coroutine from its start, suspend and resume. It does this across multilple threads.

Supported Versions

Kotlin-Coroutines-Suspends - provides tracing of Kotlin Coroutine suspend functions across all versions.
Kotlin-Coroutines-1.0 - all 1.0.x versions. Kotlin-Coroutines-1.1 - all 1.1.x versions.
Kotlin-Coroutines-1.2 - all 1.2.x and 1.3.x versions.
Kotlin-Coroutines-1.4 - all 1.4.x versions.
Kotlin-Coroutines-1.5 - all 1.5.x and 1.6.x versions.
Kotlin-Coroutines-1.7 - all 1.7.x and later versions.

Installation

To use this instrumentation.
Download the latest release.
In the New Relic Java Agent directory (directory containing newrelic.jar), create a directory named extensions if it does not already exist.
Copy the jars into the extensions directory.
Restart the application.

Verification

The easiest way to see if the instrumentation has been loaded by the Java Agent is to look for the Java Agent UI's Metric Explorer and enter "supportability/weaveinstrumentation/loaded/com.newrelic.instrumentation.labs.kotlin-coroutines". If a metric is reported then the agent has loaded the instrumentation appropriate to the version of Kotlin Coroutines that you are using.
If no metric is displayed, then check for "supportability/weaveinstrumentation/skipped/com.newrelic.instrumentation.labs.kotlin-coroutines". If no metrics are displayed verify that the instrumentation jars have been deployed to the extensions directory and that the user id that runs the application has read access.

You can also check any captured transactions for Metrics that start with 'Custom/SuspendFunction/' or 'Custom/DispatchedTask'

Getting Started

After deployment of the instrumentation jars, you should be able to see the invocation of a coroutine from start to finish across any threads that it executes on.

Couroutine Name

For methods related to a coroutine (e.g. start, launch, runBlocking, etc.) it will use the CoroutineName if it is defined in the CoroutineContext or the simple name of the Coroutine class.

Continuation String

Many of the metrics created by this instrumentation will use the continuation string which is the result of calling the toString method on a Continuation object. Typically this is either Continuation at ${getStackTraceElement() or the Java class name. In the case of subclasses of AbstractCoroutine it will be the coroutine name.

The following things are captured as part of the instrumentation

Item Metric Name format Example
Suspend Functions Custom/SuspendFunction/ContinuationString Custom/SuspendFunction/Continuation at com.nrlabs.WithContextKt.main$doTaskOne(WithContext.kt:12)
Dispatched Tasks Custom/DispatchedTask//ContinuationString Custom/DispatchedTask/DispatchedContinuation[java.util.concurrent.Executors$FinalizableDelegatedExecutorService
Continuation but not Suspend Custom/ContinuationWrapper/ContinuationString Custom/ContinuationWrapper/resumeWith/createCoroutineFromSuspendFunction

Usage

Instrumentation of methods with high invocation rates can lead to CPU overhead especially if its average response time is very small (i.e. less than a few milliseconds). Therefore it is possible to configure the agent to ignore certain suspend methods, dispatched tasks and continuation resumeWiths. This configuation is done in the newrelic.yml file.

Finding Possible Methods to Ignore

Run the following NRQL query where appName is the name of the application using Kotlin Coroutines.

SELECT rate(count(newrelic.timeslice.value), 1 MINUTE) FROM Metric WHERE (metricTimesliceName Like 'Custom/DispatchedTask/%' or metricTimesliceName Like 'Custom/WrappedSuspend/%' or metricTimesliceName Like 'Custom/ContinuationWrapper%') AND appName='appName' SINCE 24 HOURS AGO FACET metricTimesliceName

The following is a screenshot of DispatchedTasks

image

At minumum consider ignoring anything over 50K.

Below each rate is the name of the metric, it has the form Custom/DispatchedTask/..., or Custom/WrappedSuspend/... or Custom/ContinuationWrapper/... depending on the query that was run. Collect a list of the remaining metric name (i.e. the ...).

Configuring Methods to Ignore

To configure methods to ignore, edit the newrelic.yml file in the New Relic Java Agent directory.

  1. Find the following lines in newrelic.yml

image

  1. Insert the following lines BEFORE the above lines being mindful of spaces at the beginning of each line (2 on first, 4 on second, 6 on third). Each list is comma separated listed from ones found in the previous section. If none are none for the particular line it can be omitted.

image

  1. Save newrelic.yml

Note that these setting are dynamic, so typically the agent should pick up changes within a minute or so and implement the changes without having to restart.

Building

If you make changes to the instrumentation code and need to build the instrumentation jars, follow these steps

  1. Set environment variable NEW_RELIC_EXTENSIONS_DIR. Its value should be the directory where you want to build the jars (i.e. the extensions directory of the Java Agent).
  2. Build one or all of the jars.
    a. To build one jar, run the command: gradlew moduleName:clean moduleName:install
    b. To build all jars, run the command: gradlew clean install
  3. Restart the application

Support

New Relic has open-sourced this project. Issues and contributions should be reported to the project here on GitHub.

We encourage you to bring your experiences and questions to the Explorers Hub where our community members collaborate on solutions and new ideas.

Contributing

We encourage your contributions to improve Salesforce Commerce Cloud for New Relic Browser! Keep in mind when you submit your pull request, you'll need to sign the CLA via the click-through using CLA-Assistant. You only have to sign the CLA one time per project. If you have any questions, or to execute our corporate CLA, required if your contribution is on behalf of a company, please drop us an email at opensource@newrelic.com.

A note about vulnerabilities

As noted in our security policy, New Relic is committed to the privacy and security of our customers and their data. We believe that providing coordinated disclosure by security researchers and engaging with the security community are important means to achieve our security goals.

If you believe you have found a security vulnerability in this project or any of New Relic's products or websites, we welcome and greatly appreciate you reporting it to New Relic through HackerOne.

License

Kotlin Coroutine Instrumentation is licensed under the Apache 2.0 License.