Java agent API: Instrument using annotation

New Relic's Java agent provides several options for custom instrumentation. One of those options is adding the Java agent API's @trace annotations to your application code. This document describes how to use annotations.

To use annotations, you must modify the source code. If you can't or don't want to modify your source code, see Custom instrumentation for other instrumentation options.

Configure your agent for annotations

By default, the configuration setting enable_custom_tracing is set to true in the Java agent, which is the setting required for @Trace annotations to function. This setting is not included in the newrelic.yml by default.

The only time you need to incorporate this setting into your configuration file is if you want to disable Trace annotations altogether. To do this, set enable_custom_tracing: false (prefaced with two spaces) in the common stanza of your newrelic.yml.

To detect custom traces:

  1. Make sure that newrelic-api.jar appears in your classpath.
  2. Add @Trace annotations to your code. In each class containing a method you want to instrument, call:

    import com.newrelic.api.agent.Trace;
  3. Place the @Trace annotation on each target method.

The annotation com.newrelic.api.agent.Trace is located in the newrelic-api.jar.

Create a new transaction

If transactions do not appear and you want to start a new transaction, include dispatcher=true with the @Trace annotation:

@Trace (dispatcher=true)
public void run() {
  // background task
}

Add detail to your transactions

If your transaction traces show large blocks of uninstrumented time and you want to include some more methods within the trace, you can use the @Trace annotation without parameters:

@Trace
protected void methodWithinTransaction() {
  // work
}

Convert a transaction to a web request

To make a background task report as a web browser transaction with a Java agent API call: In the method annotated with @Trace(dispatcher=true), call:

NewRelic.setRequestAndResponse(Request request, Response response)

The arguments are implementations of the Request and Response interfaces in newrelic-api.jar.

Even if your Request and Response objects already are present, you still need to add this API call.

Define your own @Trace annotation class

If you define your own @Trace annotation class, there is no dependency on the newrelic-api.jar. To define the class:

package com.test;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)

public @interface Trace {
  public static final String NULL = "";
  String metricName() default NULL;
  boolean dispatcher() default false;
  String tracerFactoryName() default NULL;
}

Then, configure the agent to use this annotation in the common section of the newrelic.yml:

class_transformer:
  trace_annotation_class_name: com.test.Trace

Properties for @Trace

The @Trace annotation supports the following properties.

dispatcher
Type: Boolean
Default: false

If true, the agent starts a transaction when it reaches this @Trace annotation, even if a transaction is not already in progress. If a transaction is in progress, then that transaction will continue.

If false (default), no metrics will be recorded if the agent has not started a transaction before the @Trace annotation is reached. For example:

@Trace(dispatcher=true)
async
Type: Boolean
Default: false

If true, this method is marked as asynchronous and the agent will trace this method if it linked to an existing transaction. For example:

@Trace(async=true)

If false (default), the method is not marked as asynchronous. If other @Trace annotations are present and the method is not executing asynchronously, it will still be traced.

metricName
Type: String
Default: (none)

This property affects transaction traces and error reporting. By default, the metric name will include the class name followed by the method name. If you do not want class followed by method, then you can use this property to change the metric name.

If you set the metricName in addition to the dispatcher, as in @Trace(metricName="YourMessageHere", dispatcher=true), then the time spent in this method will appear as YourMessageHere in any transaction trace.

This will not set the overall transaction name as you see it in the APM Transactions page. To set the transaction name, see NewRelic.setTransactionName. Here is an example:

@Trace(metricName="YourMetricName", dispatcher=true)

Do not use brackets [suffix] at the end of your transaction name. New Relic automatically strips brackets from the name. Instead, use parentheses (suffix) or other symbols if needed.

skipTransactionTrace
Type: Boolean
Default: false

If true, the agent will not collect a trace for this transaction. If the method with this annotation is reached in the middle of a transaction, then the transaction trace will still be captured, but this method will be excluded from the call chart.

This property overrides a dispatcher property of true. The agent still reports rollup metrics for the method, so you will continue to see data in the APM Transactions page. Here is an example:

@Trace(skipTransactionTrace=true)
excludeFromTransactionTrace
Type: Boolean
Default: false

If true, the method will be excluded from the call chart. The agent will still collect transaction traces and individual metrics for the method. Here is an example:

@Trace(excludeFromTransactionTrace=true)
leaf
Type: Boolean
Default: false

A leaf tracer has no child tracers. This is useful when you want all time attributed to the tracer, even if other trace points are encountered the tracer's execution.

Database tracers often act as a leaf so that all time is attributed to database activity, even if instrumented external calls are made. Here is an example:

@Trace(leaf=true)

If a leaf tracer does not participate in transaction traces, the agent can create a tracer with lower overhead. Here is an example:

@Trace(excludeFromTransactionTrace=true, leaf=true)

More API functions

For more about the Java agent API and its functionality, see the Java agent API introduction.

For more help

Join the discussion about Java monitoring in the New Relic Online Technical Community! The Technical Community is a public platform to discuss and troubleshoot your New Relic toolset.

If you need additional help, get support at support.newrelic.com.