---
title: Java agent API: Instrument using annotation
source: https://docs.newrelic.com/docs/apm/agents/java-agent/api-guides/java-agent-api-instrument-using-annotation
---

New Relic's Java agent provides several options for [custom instrumentation](https://docs.newrelic.com/docs/agents/java-agent/custom-instrumentation/java-custom-instrumentation). One of those options is adding the Java agent API's `@Trace`, `@TraceLambda` or `@TraceByReturnType` annotations to your application code. This document describes how to use annotations.

> #### ⚠️ IMPORTANT
>
> 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](https://docs.newrelic.com/docs/agents/java-agent/custom-instrumentation/java-custom-instrumentation) for other instrumentation options.

## Annotations are enabled by default [#configure]

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. If you want to disable annotations, set `enable_custom_tracing: false` (prefaced with two spaces) in the `common` section of your `newrelic.yml`.

## @Trace [#trace]

Annotating a method with `@Trace` tells the Java agent that measurements should be taken for that method.

To add a method call as a custom trace add `@Trace` annotations to your method. Make sure that `newrelic-api.jar` appears in your classpath as it contains all these annotations.

```java
import com.newrelic.api.agent.Trace;

...

  @Trace
  public void run() {
    // background task
  }
```

### Create a new transaction [#new-trans]

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

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

### Add detail to your transactions [#detail]

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:

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

### Convert a transaction to a web request [#web-request]

To make a background task report as a web browser transaction with a [Java agent API](https://docs.newrelic.com/docs/java/java-agent-api) call: In the method annotated with `@Trace(dispatcher=true)`, call:

```java
NewRelic.setRequestAndResponse(Request request, Response response)
```

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

> #### ⚠️ IMPORTANT
>
> Even if your `Request` and `Response` objects already are present, you still need to add this API call.

### Define your own @Trace annotation class [#custom-class]

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

```java
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`:

```yml
class_transformer:
  trace_annotation_class_name: com.test.Trace
```

### Properties for @Trace [#properties]

The `@Trace` annotation supports the following properties.

**`dispatcher`**

| Type:    | Boolean |
| -------- | ------- |
| Default: | `false` |

If `true`, the agent will start a transaction when it reaches a method with this `@Trace` annotation if a transaction is not already in progress. If a transaction is already in progress, the method with this annotation will be included in the ongoing transaction, rather than starting a new one.

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

````java
@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:

````java
@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`, as in `@Trace(metricName="YourMessageHere")`, then the time spent in this method will appear as YourMessageHere in any transaction trace.

If you set the `metricName` in addition to the dispatcher, as in `@Trace(metricName="YourMessageHere", dispatcher=true)`, then the transaction name will appear as YourMessageHere in the APM **Transactions** page but the time spent in this method will not appear as YourMessageHere in any transaction trace.

Here is an example:

````java
@Trace(metricName="YourMetricName")
```

<Callout variant="important">
  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.
</Callout>

````

**`excludeFromTransactionTrace`**

| Type:    | Boolean |
| -------- | ------- |
| Default: | `false` |

If `true`, the method will be excluded from the transaction trace. The agent will still collect metrics for the method. Here is an example:

````java
@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:

````java
@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:

```java
@Trace(excludeFromTransactionTrace=true, leaf=true)
```

````

## @TraceLambda [#tracelambda]

This feature is disabled by default and must be explicitly enabled (e.g. `-Dnewrelic.config.instrumentation.trace_lambda.enabled=true`) for the annotations to take effect. The equivalent environment variable is `NEW_RELIC_INSTRUMENTATION_TRACE_LAMBDA_ENABLED`.

If your transaction traces show large blocks of uninstrumented time and you want to include lambda expressions within the trace, you can use the `@TraceLambda` annotation without parameters:

```java
import com.newrelic.api.agent.TraceLambda;

@TraceLambda
class ClassContainingLambdaExpressions() {
  // work
}
```

Lambda expressions become static methods of the containing class after compilation. By default, static methods within classes marked with the `@TraceLambda` annotation matching the annotations pattern will be marked with the `@Trace` annotation.

### Properties for @TraceLambda [#tracelambda-properties]

The `@TraceLambda` annotation supports the following properties.

**`pattern`**

| Type:    | String                                 |
| -------- | -------------------------------------- |
| Default: | `^\$?(lambda\|anonfun)\$(?\<name\>.*)` |

If you set the `pattern`, as in `@TraceLambda(pattern="YourPattern")`, then
the marked classes method names will be matched against the regex pattern
`YourPattern`. If matched the related method will be marked with the
`@Trace` annotation.

Here is an example:

````java
@TraceLambda(pattern="YourPattern")
```

````

**`includeNonstatic`**

| Type:    | Boolean |
| -------- | ------- |
| Default: | `false` |

If `true`, the marked classes nonstatic methods will be eligible for assessment against the pattern for instrumentation.

Here is an example:

````java
@TraceLambda(includeNonstatic="true")
```

````

## @TraceByReturnType [#tracebyreturntype]

To include methods with a particular return type within the trace, you can use the `@TraceByReturnType` annotation to mark a class passing the return types as a property. Methods in annotated classes that match one of the specified return types will be marked with the `@Trace` annotation.

```java
@TraceByReturnType(traceReturnTypes={Integer.class, String.class})
class ClassContainingMethods() {
  // ...
}
```

### Properties for @TraceByReturnType [#tracebyreturntype-properties]

The `@TraceByReturnType` annotation supports the following properties.

**`traceReturnTypes`**

| Type:    | List&lt;Class> |
| -------- | -------------- |
| Default: | empty list     |

If you set the `traceReturnTypes`, as in `@TraceByReturnType(traceReturnTypes={String.class})`, then the marked classes method return types will be matched against the `String.class`. All matched methods will be marked with the `@Trace` annotation.

Here is an example:

````java
@TraceByReturnType(traceReturnTypes={Integer.class, String.class})
class ClassContainingMethods() {
  public String doSomething() { // matches
    // ...
  }

  public Long somethingElse() { // does not match
    // ...
  }
}
```

````

## Performance considerations

When the Java agent is present in the JVM, it will inject code on the annotated methods. The performance hit is negligible in heavyweight operations, such as database or webservice calls, but is noticeable in methods that are called frequently, such as an accessor called thousands of times a second.

> #### ⚠️ CAUTION
>
> Do not instrument all of your methods, as this can lead to decreased performance and to a [metric grouping issue](https://docs.newrelic.com/docs/apm/other-features/metrics/metric-grouping-issues).

## More API functions [#other-api]

For more about the Java agent API and its functionality, see the [Java agent API introduction](https://docs.newrelic.com/docs/agents/java-agent/custom-instrumentation/java-agent-api).
