

# AWS X-Ray SDK for Java
X-Ray SDK for Java

**Note**  
X-Ray SDK/Daemon Maintenance Notice – On February 25th, 2026, the AWS X-Ray SDKs/Daemon will enter maintenance mode, where AWS will limit X-Ray SDK and Daemon releases to address security issues only. For more information on the support timeline, see [X-Ray SDK and Daemon Support timeline](xray-sdk-daemon-timeline.md). We recommend to migrate to OpenTelemetry. For more information on migrating to OpenTelemetry, see [Migrating from X-Ray instrumentation to OpenTelemetry instrumentation ](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-migration.html).

The X-Ray SDK for Java is a set of libraries for Java web applications that provide classes and methods for generating and sending trace data to the X-Ray daemon. Trace data includes information about incoming HTTP requests served by the application, and calls that the application makes to downstream services using the AWS SDK, HTTP clients, or an SQL database connector. You can also create segments manually and add debug information in annotations and metadata.

The X-Ray SDK for Java is an open source project. You can follow the project and submit issues and pull requests on GitHub: [github.com/aws/aws-xray-sdk-java](https://github.com/aws/aws-xray-sdk-java)

Start by [adding `AWSXRayServletFilter` as a servlet filter](xray-sdk-java-filters.md) to trace incoming requests. A servlet filter creates a [segment](xray-concepts.md#xray-concepts-segments). While the segment is open, you can use the SDK client's methods to add information to the segment and create subsegments to trace downstream calls. The SDK also automatically records exceptions that your application throws while the segment is open.

Starting in release 1.3, you can instrument your application using [aspect-oriented programming (AOP) in Spring](xray-sdk-java-aop-spring.md). What this means is that you can instrument your application, while it is running on AWS, without adding any code to your application's runtime.

Next, use the X-Ray SDK for Java to instrument your AWS SDK for Java clients by [including the SDK Instrumentor submodule](#xray-sdk-java-dependencies) in your build configuration. Whenever you make a call to a downstream AWS service or resource with an instrumented client, the SDK records information about the call in a subsegment. AWS services and the resources that you access within the services appear as downstream nodes on the trace map to help you identify errors and throttling issues on individual connections.

If you don't want to instrument all downstream calls to AWS services, you can leave out the Instrumentor submodule and choose which clients to instrument. Instrument individual clients by [adding a `TracingHandler`](xray-sdk-java-awssdkclients.md) to an AWS SDK service client.

Other X-Ray SDK for Java submodules provide instrumentation for downstream calls to HTTP web APIs and SQL databases. You can [use the X-Ray SDK for Java versions of `HTTPClient` and `HTTPClientBuilder`](xray-sdk-java-httpclients.md) in the Apache HTTP submodule to instrument Apache HTTP clients. To instrument SQL queries, [add the SDK's interceptor to your data source](xray-sdk-java-sqlclients.md).

After you start using the SDK, customize its behavior by [configuring the recorder and servlet filter](xray-sdk-java-configuration.md). You can add plugins to record data about the compute resources running your application, customize sampling behavior by defining sampling rules, and set the log level to see more or less information from the SDK in your application logs.

Record additional information about requests and the work that your application does in [annotations and metadata](xray-sdk-java-segment.md). Annotations are simple key-value pairs that are indexed for use with [filter expressions](xray-console-filters.md), so that you can search for traces that contain specific data. Metadata entries are less restrictive and can record entire objects and arrays — anything that can be serialized into JSON.

**Annotations and Metadata**  
Annotations and metadata are arbitrary text that you add to segments with the X-Ray SDK. Annotations are indexed for use with filter expressions. Metadata are not indexed, but can be viewed in the raw segment with the X-Ray console or API. Anyone that you grant read access to X-Ray can view this data.

When you have a lot of instrumented clients in your code, a single request segment can contain many subsegments, one for each call made with an instrumented client. You can organize and group subsegments by wrapping client calls in [custom subsegments](xray-sdk-java-subsegments.md). You can create a custom subsegment for an entire function or any section of code, and record metadata and annotations on the subsegment instead of writing everything on the parent segment.

## Submodules


You can download the X-Ray SDK for Java from Maven. The X-Ray SDK for Java is split into submodules by use case, with a bill of materials for version management:
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-core/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-core/) (required) – Basic functionality for creating segments and transmitting segments. Includes `AWSXRayServletFilter` for instrumenting incoming requests.
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-aws-sdk/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-aws-sdk/) – Instruments calls to AWS services made with AWS SDK for Java clients by adding a tracing client as a request handler.
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-aws-sdk-v2/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-aws-sdk-v2/) – Instruments calls to AWS services made with AWS SDK for Java 2.2 and later clients by adding a tracing client as a request intereceptor.
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-aws-sdk-instrumentor/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-aws-sdk-instrumentor/) – With `aws-xray-recorder-sdk-aws-sdk`, instruments all AWS SDK for Java clients automatically.
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-aws-sdk-v2-instrumentor/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-aws-sdk-v2-instrumentor/) – With `aws-xray-recorder-sdk-aws-sdk-v2`, instruments all AWS SDK for Java 2.2 and later clients automatically.
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-apache-http/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-apache-http/) – Instruments outbound HTTP calls made with Apache HTTP clients.
+  [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-spring/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-spring/) – Provides interceptors for Spring AOP Framework applications.
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-sql-postgres/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-sql-postgres/) – Instruments outbound calls to a PostgreSQL database made with JDBC.
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-sql-mysql/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-sql-mysql/) – Instruments outbound calls to a MySQL database made with JDBC.
+ [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-bom/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-bom/) – Provides a bill of materials that you can use to specify the version to use for all submodules.
+  [https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-metrics/](https://mvnrepository.com/artifact/com.amazonaws/aws-xray-recorder-sdk-metrics/) – Publish unsampled Amazon CloudWatch metrics from your collected X-Ray segments.

If you use Maven or Gradle to build your application, [add the X-Ray SDK for Java to your build configuration](#xray-sdk-java-dependencies).

For reference documentation of the SDK's classes and methods, see [AWS X-Ray SDK for Java API Reference](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc).

## Requirements


The X-Ray SDK for Java requires Java 8 or later, Servlet API 3, the AWS SDK, and Jackson.

The SDK depends on the following libraries at compile and runtime:
+ AWS SDK for Java version 1.11.398 or later
+ Servlet API 3.1.0

These dependencies are declared in the SDK's `pom.xml` file and are included automatically if you build using Maven or Gradle.

If you use a library that is included in the X-Ray SDK for Java, you must use the included version. For example, if you already depend on Jackson at runtime and include JAR files in your deployment for that dependency, you must remove those JAR files because the SDK JAR includes its own versions of Jackson libraries. 

## Dependency management


The X-Ray SDK for Java is available from Maven:
+ **Group** – `com.amazonaws`
+ **Artifact** – `aws-xray-recorder-sdk-bom`
+ **Version** – `2.11.0`

If you use Maven to build your application, add the SDK as a dependency in your `pom.xml` file.

**Example pom.xml - dependencies**  

```
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-xray-recorder-sdk-bom</artifactId>
      <version>2.11.0</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
<dependencies>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-core</artifactId>
  </dependency>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-apache-http</artifactId>
  </dependency>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-aws-sdk</artifactId>
  </dependency>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-aws-sdk-instrumentor</artifactId>
  </dependency>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-sql-postgres</artifactId>
  </dependency>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-xray-recorder-sdk-sql-mysql</artifactId>
  </dependency>
</dependencies>
```

For Gradle, add the SDK as a compile-time dependency in your `build.gradle` file.

**Example build.gradle - dependencies**  

```
dependencies {
  compile("org.springframework.boot:spring-boot-starter-web")
  testCompile("org.springframework.boot:spring-boot-starter-test")
  compile("com.amazonaws:aws-java-sdk-dynamodb")
  compile("com.amazonaws:aws-xray-recorder-sdk-core")
  compile("com.amazonaws:aws-xray-recorder-sdk-aws-sdk")
  compile("com.amazonaws:aws-xray-recorder-sdk-aws-sdk-instrumentor")
  compile("com.amazonaws:aws-xray-recorder-sdk-apache-http")
  compile("com.amazonaws:aws-xray-recorder-sdk-sql-postgres")
  compile("com.amazonaws:aws-xray-recorder-sdk-sql-mysql")
  testCompile("junit:junit:4.11")
}
dependencyManagement {
    imports {
        mavenBom('com.amazonaws:aws-java-sdk-bom:1.11.39')
        mavenBom('com.amazonaws:aws-xray-recorder-sdk-bom:2.11.0')
    }
}
```

If you use Elastic Beanstalk to deploy your application, you can use Maven or Gradle to build on-instance each time you deploy, instead of building and uploading a large archive that includes all of your dependencies. See the [sample application](xray-scorekeep.md) for an example that uses Gradle.

# AWS X-Ray auto-instrumentation agent for Java
Auto-instrumentation agent

**Note**  
X-Ray SDK/Daemon Maintenance Notice – On February 25th, 2026, the AWS X-Ray SDKs/Daemon will enter maintenance mode, where AWS will limit X-Ray SDK and Daemon releases to address security issues only. For more information on the support timeline, see [X-Ray SDK and Daemon Support timeline](xray-sdk-daemon-timeline.md). We recommend to migrate to OpenTelemetry. For more information on migrating to OpenTelemetry, see [Migrating from X-Ray instrumentation to OpenTelemetry instrumentation ](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-migration.html).

The AWS X-Ray auto-instrumentation agent for Java is a tracing solution that instruments your Java web applications with minimal development effort. The agent enables tracing for servlet-based applications and all of the agent's downstream requests made with supported frameworks and libraries. This includes downstream Apache HTTP requests, AWS SDK requests, and SQL queries made using a JDBC driver. The agent propagates X-Ray context, including all active segments and subsegments, across threads. All of the configurations and versatility of the X-Ray SDK are still available with the Java agent. Suitable defaults were chosen to ensure that the agent works with minimal effort.

The X-Ray agent solution is best suited for servlet-based, request-response Java web application servers. If your application uses an asynchronous framework, or is not well modeled as a request-response service, you might want to consider manual instrumentation with the SDK instead. 

The X-Ray agent is built using the Distributed Systems Comprehension toolkit, or DiSCo. DiSCo is an open source framework for building Java agents that can be used in distributed systems. While it is not necessary to understand DiSCo to use the X-Ray agent, you can learn more about the project by visiting its [homepage on GitHub](https://github.com/awslabs/disco). The X-Ray agent is also fully open-sourced. To view the source code, make contributions, or raise issues about the agent, visit its [repository on GitHub](https://github.com/aws/aws-xray-java-agent).

## Sample application


The [eb-java-scorekeep](https://github.com/aws-samples/eb-java-scorekeep/tree/xray-agent) sample application is adapted to be instrumented with the X-Ray agent. This branch contains no servlet filter or recorder configuration, as these functions are done by the agent. To run the application locally or using AWS resources, follow the steps in the sample application's readme file. The instructions for using the sample app to generate X-Ray traces are in the [sample app’s tutorial](xray-scorekeep.md).

## Getting started


To get started with the X-Ray auto-instrumentation Java agent in your own application, follow these steps.

1. Run the X-Ray daemon in your environment. For more information, see [AWS X-Ray daemon](xray-daemon.md).

1. Download the [latest distribution of the agent](https://github.com/aws/aws-xray-java-agent/releases/latest/download/xray-agent.zip). Unzip the archive and note its location in your file system. Its contents should look like the following.

   ```
   disco 
   ├── disco-java-agent.jar 
   └── disco-plugins 
       ├── aws-xray-agent-plugin.jar 
       ├── disco-java-agent-aws-plugin.jar 
       ├── disco-java-agent-sql-plugin.jar 
       └── disco-java-agent-web-plugin.jar
   ```

1. Modify the JVM arguments of your application to include the following, which enables the agent. Ensure the `-javaagent` argument is placed *before* the `-jar` argument if applicable. The process to modify JVM arguments varies depending on the tools and frameworks you use to launch your Java server. Consult the documentation of your server framework for specific guidance.

   ```
   -javaagent:/<path-to-disco>/disco-java-agent.jar=pluginPath=/<path-to-disco>/disco-plugins
   ```

1. To specify how the name of your application appears on the X-Ray console, set the `AWS_XRAY_TRACING_NAME` environment variable or the `com.amazonaws.xray.strategy.tracingName` system property. If no name is provided, a default name is used.

1. Restart your server or container. Incoming requests and their downstream calls are now traced. If you don’t see the expected results, see [Troubleshooting](#XRayAutoInstrumentationAgent-Troubleshooting).

## Configuration


The X-Ray agent is configured by an external, user-provided JSON file. By default, this file is at the root of the user’s classpath (for example, in their `resources` directory) named `xray-agent.json`. You can configure a custom location for the config file by setting the `com.amazonaws.xray.configFile` system property to the absolute filesystem path of your configuration file.

An example configuration file is shown next.

```
{     
    "serviceName": "XRayInstrumentedService", 
    "contextMissingStrategy": "LOG_ERROR", 
    "daemonAddress": "127.0.0.1:2000", 
    "tracingEnabled": true, 
    "samplingStrategy": "CENTRAL",     
    "traceIdInjectionPrefix": "prefix",     
    "samplingRulesManifest": "/path/to/manifest",     
    "awsServiceHandlerManifest": "/path/to/manifest",     
    "awsSdkVersion": 2,     
    "maxStackTraceLength": 50,     
    "streamingThreshold": 100,     
    "traceIdInjection": true,     
    "pluginsEnabled": true,     
    "collectSqlQueries": false 
}
```

### Configuration specification


The following table describes valid values for each property. Property names are case sensitive, but their keys are not. For properties that can be overridden by environment variables and system properties, the order of priority is always environment variable, then system property, and then configuration file. For information about properties that you can override, see [Environment variables](xray-sdk-java-configuration.md#xray-sdk-java-configuration-envvars). All fields are optional.


|  Property name  |  Type  |  Valid values  |  Description  |  Environment variable  |  System property  |  Default  | 
| --- | --- | --- | --- | --- | --- | --- | 
|  serviceName  |  String  |  Any string  |  The name of your instrumented service as it will appear in the X-Ray console.  |  AWS\$1XRAY\$1TRACING\$1NAME  |  com.amazonaws.xray.strategy.tracingName  |  XRayInstrumentedService  | 
|  contextMissingStrategy  |  String  |  LOG\$1ERROR, IGNORE\$1ERROR  |  The action taken by the agent when it attempts to use the X-Ray segment context but none is present.  |  AWS\$1XRAY\$1CONTEXT\$1MISSING  |  com.amazonaws.xray.strategy.contextMissingStrategy  |  LOG\$1ERROR  | 
|  daemonAddress  |  String  |  Formatted IP address and port, or list of TCP and UDP address  |  The address the agent uses to communicate with the X-Ray daemon.  |  AWS\$1XRAY\$1DAEMON\$1ADDRESS  |  com.amazonaws.xray.emitter.daemonAddress  |  127.0.0.1:2000  | 
|  tracingEnabled  |  Boolean  |  True, False  |  Enables instrumentation by the X-Ray agent.  |  AWS\$1XRAY\$1TRACING\$1ENABLED  |  com.amazonaws.xray.tracingEnabled  |  TRUE  | 
|  samplingStrategy  |  String  |  CENTRAL, LOCAL, NONE, ALL  |  The sampling strategy used by the agent. ALL captures all requests, NONE captures no requests. See [sampling rules](xray-sdk-java-configuration.md#xray-sdk-java-configuration-sampling).  |  N/A  |  N/A  |  CENTRAL  | 
|  traceIdInjectionPrefix  |  String  |  Any string  |  Includes the provided prefix before injected trace IDs in logs.  |  N/A  |  N/A  |  None (empty string)  | 
|  samplingRulesManifest  |  String  |  An absolute file path  |  The path to a custom sampling rules file to be used as the source of sampling rules for the local sampling strategy, or the fallback rules for the central strategy.  |  N/A  |  N/A  |   [DefaultSamplingRules.json](https://github.com/aws/aws-xray-sdk-java/blob/master/aws-xray-recorder-sdk-core/src/main/resources/com/amazonaws/xray/strategy/sampling/DefaultSamplingRules.json)   | 
|   awsServiceHandlerManifest   |  String  |  An absolute file path  |  The path to a custom parameter allow list, which captures additional information from AWS SDK clients.  |  N/A  |  N/A  |   [DefaultOperationParameterWhitelist.json](https://github.com/aws/aws-xray-sdk-java/blob/master/aws-xray-recorder-sdk-aws-sdk-v2/src/main/resources/com/amazonaws/xray/interceptors/DefaultOperationParameterWhitelist.json)   | 
|  awsSdkVersion  |  Integer  |  1, 2  |  Version of the [AWS SDK for Java](https://docs.aws.amazon.com/sdk-for-java/index.html) you’re using. Ignored if `awsServiceHandlerManifest` is not also set.  |  N/A  |  N/A  |  2  | 
|  maxStackTraceLength  |  Integer  |  Non-negative integers  |  The maximum lines of a stack trace to record in a trace.  |  N/A  |  N/A  |  50  | 
|  streamingThreshold  |  Integer  |  Non-negative integers  |  After at least this many subsegments are closed, they are streamed to the daemon out-of-band to avoid chunks being too large.  |  N/A  |  N/A  |  100  | 
|  traceIdInjection  |  Boolean  |  True, False  |  Enables X-Ray trace ID injection into logs if the dependencies and configuration described in [logging config](xray-sdk-java-configuration.md#xray-sdk-java-configuration-logging) are also added. Otherwise, does nothing.  |  N/A  |  N/A  |  TRUE  | 
|  pluginsEnabled  |  Boolean  |  True, False  |  Enables plugins that record metadata about the AWS environments you’re operating in. See [plugins](xray-sdk-java-configuration.md#xray-sdk-java-configuration-plugins).  |  N/A  |  N/A  |  TRUE  | 
|  collectSqlQueries  |  Boolean  |  True, False  |  Records SQL query strings in SQL subsegments on a best-effort basis.  |  N/A  |  N/A  |  FALSE  | 
|  contextPropagation  |  Boolean  |  True, False  |  Automatically propagates X-Ray context between threads if true. Otherwise, uses Thread Local to store context and manual propagation across threads is required.  |  N/A  |  N/A  |  TRUE  | 

### Logging configuration


The X-Ray agent's log level can be configured in the same way as the X-Ray SDK for Java. See [Logging](xray-sdk-java-configuration.md#xray-sdk-java-configuration-logging) for more information on configuring logging with the X-Ray SDK for Java. 

### Manual instrumentation


If you’d like to perform manual instrumentation in addition to the agent’s auto-instrumentation, add the X-Ray SDK as a dependency to your project. Note that the SDK's custom servlet filters mentioned in [Tracing Incoming Requests](xray-sdk-java-filters.md) are not compatible with the X-Ray agent. 

**Note**  
You must use the latest version of the X-Ray SDK to perform manual instrumentation while also using the agent. 

If you are working in a Maven project, add the following dependencies to your `pom.xml` file. 

```
<dependencies> 
  <dependency> 
    <groupId>com.amazonaws</groupId> 
    <artifactId>aws-xray-recorder-sdk-core</artifactId> 
    <version>2.11.0</version> 
  </dependency> 
  </dependencies>
```

If you are working in a Gradle project, add the following dependencies to your `build.gradle` file.

```
implementation 'com.amazonaws:aws-xray-recorder-sdk-core:2.11.0' 
```

You can add [ custom subsegments](xray-sdk-java-subsegments.md) in addition to [annotations, metadata, and user IDs](xray-sdk-java-segment.md) while using the agent, just as you would with the normal SDK. The agent automatically propagates context across threads, so no workarounds to propagate context should be necessary when working with multithreaded applications.

## Troubleshooting


Since the agent offers fully automatic instrumentation, it can be difficult to identify the root cause of a problem when you are experiencing issues. If the X-Ray agent is not working as expected for you, review the following problems and solutions. The X-Ray agent and SDK use Jakarta Commons Logging (JCL). To see the logging output, ensure that a bridge connecting JCL to your logging backend is on the classpath, as in the following example: `log4j-jcl` or `jcl-over-slf4j`.

### Problem: I’ve enabled the Java agent on my application but don’t see anything on the X-Ray console


 **Is the X-Ray daemon running on the same machine?** 

If not, see the [X-Ray daemon documentation](https://docs.aws.amazon.com/xray/latest/devguide/xray-daemon.html) to set it up.

 **In your application logs, do you see a message like "Initializing the X-Ray agent recorder"?** 

If you have correctly added the agent to your application, this message is logged at INFO level when your application starts, before it starts taking requests. If this message is not there, then the Java agent is not running with your Java process. Make sure you’ve followed all the setup steps correctly with no typos.

 **In your application logs, do you see several error messages saying something like "Suppressing AWS X-Ray context missing exception"?** 

These errors occur because the agent is trying to instrument downstream requests, like AWS SDK requests or SQL queries, but the agent was unable to automatically create a segment. If you see many of these errors, the agent might not be the best tool for your use case and you might want to consider manual instrumentation with the X-Ray SDK instead. Alternatively, you can enable X-Ray SDK [debug logs](xray-sdk-java-configuration.md#xray-sdk-java-configuration-logging) to see the stack trace of where the context-missing exceptions are occurring. You can wrap these portions of your code with custom segments, which should resolve these errors. For an example of wrapping downstream requests with custom segments, see the sample code in [instrumenting startup code](scorekeep-startup.md).

### Problem: Some of the segments I expect do not appear on the X-Ray console


 **Does your application use multithreading?**

 If some segments that you expect to be created are not appearing in your console, background threads in your application might be the cause. If your application performs tasks using background threads that are “fire and forget,” like making a one-off call to a Lambda function with the AWS SDK, or polling some HTTP endpoint periodically, that may confuse the agent while it is propagating context across threads. To verify this is your problem, enable X-Ray SDK debug logs and check for messages like: *Not emitting segment named <NAME > as it parents in-progress subsegments*. To work around this, you can try joining the background threads before your server returns to ensure all the work done in them is recorded. Or, you can set the agent’s `contextPropagation` configuration to `false` to disable context propagation in background threads. If you do this, you’ll have to manually instrument those threads with custom segments or ignore the context missing exceptions they produce. 

**Have you set up sampling rules?** 

 If there are seemingly random or unexpected segments appearing on the X-Ray console, or the segments you expect to be on the console aren’t, you might be experiencing a sampling issue. The X-Ray agent applies centralized sampling to all segments it creates, using the rules from the X-Ray console. The default rule is 1 segment per second, plus 5% of segments afterward, are sampled. This means segments that are created rapidly with the agent might not be sampled. To resolve this, you should create custom sampling rules on the X-Ray console that appropriately sample the desired segments. For more information, see [sampling](xray-console-sampling.md). 

# Configuring the X-Ray SDK for Java
Configuration

**Note**  
X-Ray SDK/Daemon Maintenance Notice – On February 25th, 2026, the AWS X-Ray SDKs/Daemon will enter maintenance mode, where AWS will limit X-Ray SDK and Daemon releases to address security issues only. For more information on the support timeline, see [X-Ray SDK and Daemon Support timeline](xray-sdk-daemon-timeline.md). We recommend to migrate to OpenTelemetry. For more information on migrating to OpenTelemetry, see [Migrating from X-Ray instrumentation to OpenTelemetry instrumentation ](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-migration.html).

The X-Ray SDK for Java includes a class named `AWSXRay` that provides the global recorder. This is a `TracingHandler` that you can use to instrument your code. You can configure the global recorder to customize the `AWSXRayServletFilter` that creates segments for incoming HTTP calls.

**Topics**
+ [

## Service plugins
](#xray-sdk-java-configuration-plugins)
+ [

## Sampling rules
](#xray-sdk-java-configuration-sampling)
+ [

## Logging
](#xray-sdk-java-configuration-logging)
+ [

## Segment listeners
](#xray-sdk-java-configuration-listeners)
+ [

## Environment variables
](#xray-sdk-java-configuration-envvars)
+ [

## System properties
](#xray-sdk-java-configuration-sysprops)

## Service plugins


Use `plugins` to record information about the service hosting your application.

**Plugins**
+ Amazon EC2 – `EC2Plugin` adds the instance ID, Availability Zone, and the CloudWatch Logs Group.
+ Elastic Beanstalk – `ElasticBeanstalkPlugin` adds the environment name, version label, and deployment ID.
+ Amazon ECS – `ECSPlugin` adds the container ID.
+ Amazon EKS – `EKSPlugin` adds the container ID, cluster name, pod ID, and the CloudWatch Logs Group.

![\[Segment resource data with Amazon EC2 and Elastic Beanstalk plugins.\]](http://docs.aws.amazon.com/xray/latest/devguide/images/scorekeep-PUTrules-segment-resources.png)


To use a plugin, call `withPlugin` on your `AWSXRayRecorderBuilder`.

**Example src/main/java/scorekeep/WebConfig.java - recorder**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
import [com.amazonaws.xray.AWSXRayRecorderBuilder](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRayRecorderBuilder.html);
import [com.amazonaws.xray.plugins.EC2Plugin](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/plugins/EC2Plugin.html);
import [com.amazonaws.xray.plugins.ElasticBeanstalkPlugin](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/plugins/ElasticBeanstalkPlugin.html);
import [com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/strategy/sampling/LocalizedSamplingStrategy.html);

@Configuration
public class WebConfig {
...
  static {
    AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard().withPlugin(new EC2Plugin()).withPlugin(new ElasticBeanstalkPlugin());

    URL ruleFile = WebConfig.class.getResource("/sampling-rules.json");
    builder.withSamplingStrategy(new LocalizedSamplingStrategy(ruleFile));

    AWSXRay.setGlobalRecorder(builder.build());
  }
}
```

The SDK also uses plugin settings to set the `origin` field on the segment. This indicates the type of AWS resource that runs your application. When you use multiple plugins, the SDK uses the following resolution order to determine the origin: ElasticBeanstalk > EKS > ECS > EC2.

## Sampling rules


The SDK uses the sampling rules you define in the X-Ray console to determine which requests to record. The default rule traces the first request each second, and five percent of any additional requests across all services sending traces to X-Ray. [Create additional rules in the X-Ray console](xray-console-sampling.md) to customize the amount of data recorded for each of your applications.

The SDK applies custom rules in the order in which they are defined. If a request matches multiple custom rules, the SDK applies only the first rule.

**Note**  
If the SDK can't reach X-Ray to get sampling rules, it reverts to a default local rule of the first request each second, and five percent of any additional requests per host. This can occur if the host doesn't have permission to call sampling APIs, or can't connect to the X-Ray daemon, which acts as a TCP proxy for API calls made by the SDK.

You can also configure the SDK to load sampling rules from a JSON document. The SDK can use local rules as a backup for cases where X-Ray sampling is unavailable, or use local rules exclusively.

**Example sampling-rules.json**  

```
{
  "version": 2,
  "rules": [
    {
      "description": "Player moves.",
      "host": "*",
      "http_method": "*",
      "url_path": "/api/move/*",
      "fixed_target": 0,
      "rate": 0.05
    }
  ],
  "default": {
    "fixed_target": 1,
    "rate": 0.1
  }
}
```

This example defines one custom rule and a default rule. The custom rule applies a five-percent sampling rate with no minimum number of requests to trace for paths under `/api/move/`. The default rule traces the first request each second and 10 percent of additional requests.

The disadvantage of defining rules locally is that the fixed target is applied by each instance of the recorder independently, instead of being managed by the X-Ray service. As you deploy more hosts, the fixed rate is multiplied, making it harder to control the amount of data recorded.

On AWS Lambda, you cannot modify the sampling rate. If your function is called by an instrumented service, calls that generated requests that were sampled by that service will be recorded by Lambda. If active tracing is enabled and no tracing header is present, Lambda makes the sampling decision.

To provide backup rules in Spring, configure the global recorder with a `CentralizedSamplingStrategy` in a configuration class.

**Example src/main/java/myapp/WebConfig.java - recorder configuration**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
import [com.amazonaws.xray.AWSXRayRecorderBuilder](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRayRecorderBuilder.html);
import [com.amazonaws.xray.javax.servlet.AWSXRayServletFilter](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html);
import [com.amazonaws.xray.plugins.EC2Plugin](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/plugins/EC2Plugin.html);
import [com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/strategy/sampling/LocalizedSamplingStrategy.html);

@Configuration
public class WebConfig {

  static {
  AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard().withPlugin(new EC2Plugin());

  URL ruleFile = WebConfig.class.getResource("/sampling-rules.json");
  builder.withSamplingStrategy(new CentralizedSamplingStrategy(ruleFile));

  AWSXRay.setGlobalRecorder(builder.build());
}
```

For Tomcat, add a listener that extends `ServletContextListener` and register the listener in the deployment descriptor.

**Example src/com/myapp/web/Startup.java**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
import [com.amazonaws.xray.AWSXRayRecorderBuilder](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRayRecorderBuilder.html);
import [com.amazonaws.xray.plugins.EC2Plugin](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/plugins/EC2Plugin.html);
import [com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/strategy/sampling/LocalizedSamplingStrategy.html);

import java.net.URL;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class Startup implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent event) {
        AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard().withPlugin(new EC2Plugin());

        URL ruleFile = Startup.class.getResource("/sampling-rules.json");
        builder.withSamplingStrategy(new CentralizedSamplingStrategy(ruleFile));

        AWSXRay.setGlobalRecorder(builder.build());
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) { }
}
```

**Example WEB-INF/web.xml**  

```
...
  <listener>
    <listener-class>com.myapp.web.Startup</listener-class>
  </listener>
```

To use local rules only, replace the `CentralizedSamplingStrategy` with a `LocalizedSamplingStrategy`.

```
builder.withSamplingStrategy(new LocalizedSamplingStrategy(ruleFile));
```

## Logging


By default, the SDK outputs `ERROR`-level messages to your application logs. You can enable debug-level logging on the SDK to output more detailed logs to your application log file. Valid log levels are `DEBUG`, `INFO`, `WARN`, `ERROR`, and `FATAL`. `FATAL` log level silences all log messages because the SDK does not log at fatal level.

**Example application.properties**  
Set the logging level with the `logging.level.com.amazonaws.xray` property.  

```
logging.level.com.amazonaws.xray = DEBUG
```

Use debug logs to identify issues, such as unclosed subsegments, when you [generate subsegments manually](xray-sdk-java-subsegments.md).

### Trace ID injection into logs


To expose the current fully qualified trace ID to your log statements, you can inject the ID into the mapped diagnostic context (MDC). Using the `SegmentListener` interface, methods are called from the X-Ray recorder during segment lifecycle events. When a segment or subsegment begins, the qualified trace ID is injected into the MDC with the key `AWS-XRAY-TRACE-ID`. When that segment ends, the key is removed from the MDC. This exposes the trace ID to the logging library in use. When a subsegment ends, its parent ID is injected into the MDC.

**Example fully qualified trace ID**  
The fully qualified ID is represented as `TraceID@EntityID`  

```
1-5df42873-011e96598b447dfca814c156@541b3365be3dafc3
```

This feature works with Java applications instrumented with the AWS X-Ray SDK for Java, and supports the following logging configurations:
+ SLF4J front-end API with Logback backend
+ SLF4J front-end API with Log4J2 backend
+ Log4J2 front-end API with Log4J2 backend

See the following tabs for the needs of each front end and each backend.

------
#### [ SLF4J Frontend ]

1. Add the following Maven dependency to your project.

   ```
   <dependency>
       <groupId>com.amazonaws</groupId>
       <artifactId>aws-xray-recorder-sdk-slf4j</artifactId>
       <version>2.11.0</version>
   </dependency>
   ```

1. Include the `withSegmentListener` method when building the `AWSXRayRecorder`. This adds a `SegmentListener` class, which automatically injects new trace IDs into the SLF4J MDC.

   The `SegmentListener` takes an optional string as a parameter to configure the log statement prefix. The prefix can be configured in the following ways:
   + **None** – Uses the default `AWS-XRAY-TRACE-ID` prefix.
   + **Empty** – Uses an empty string (e.g. `""`).
   + **Custom** – Uses a custom prefix as defined in the string.  
**Example `AWSXRayRecorderBuilder` statement**  

   ```
   AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder
           .standard().withSegmentListener(new SLF4JSegmentListener("CUSTOM-PREFIX"));
   ```

------
#### [ Log4J2 front end ]

1. Add the following Maven dependency to your project.

   ```
   <dependency>
       <groupId>com.amazonaws</groupId>
       <artifactId>aws-xray-recorder-sdk-log4j</artifactId>
       <version>2.11.0</version>
   </dependency>
   ```

1. Include the `withSegmentListener` method when building the `AWSXRayRecorder`. This will add a `SegmentListener` class, which automatically injects new fully qualified trace IDs into the SLF4J MDC.

   The `SegmentListener` takes an optional string as a parameter to configure the log statement prefix. The prefix can be configured in the following ways:
   + **None** – Uses the default `AWS-XRAY-TRACE-ID` prefix.
   + **Empty** – Uses an empty string (e.g. `""`) and removes the prefix.
   + **Custom** – Uses the custom prefix defined in the string.  
**Example `AWSXRayRecorderBuilder` statement**  

   ```
   AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder
           .standard().withSegmentListener(new Log4JSegmentListener("CUSTOM-PREFIX"));
   ```

------
#### [ Logback backend ]

To insert the trace ID into your log events, you must modify the logger's `PatternLayout`, which formats each logging statement.

1. Find where the `patternLayout` is configured. You can do this programmatically, or through an XML configuration file. To learn more, see [Logback configuration](http://logback.qos.ch/manual/configuration.html).

1. Insert `%X{AWS-XRAY-TRACE-ID}` anywhere in the `patternLayout` to insert the trace ID in future logging statements. `%X{}` indicates that you are retrieving a value with the provided key from the MDC. To learn more about PatternLayouts in Logback, see [PatternLayout](https://logback.qos.ch/manual/layouts.html#ClassicPatternLayout).

------
#### [ Log4J2 backend ]

1. Find where the `patternLayout` is configured. You can do this programmatically, or through a configuration file written in XML, JSON, YAML, or properties format. 

   To learn more about configuring Log4J2 through a configuration file, see [Configuration](https://logging.apache.org/log4j/2.x/manual/configuration.html). 

   To learn more about configuring Log4J2 programmatically, see [Programmatic Configuration](https://logging.apache.org/log4j/2.x/manual/customconfig.html). 

1. Insert `%X{AWS-XRAY-TRACE-ID}` anywhere in the `PatternLayout` to insert the trace ID in future logging statements. `%X{}` indicates that you are retrieving a value with the provided key from the MDC. To learn more about PatternLayouts in Log4J2, see [Pattern Layout](https://logging.apache.org/log4j/2.x/manual/layouts.html#Pattern_Layout).

------

**Trace ID Injection Example**  
The following shows a `PatternLayout` string modified to include the trace ID. The trace ID is printed after the thread name (`%t`) and before the log level (`%-5p`).

**Example `PatternLayout` With ID injection**  

```
%d{HH:mm:ss.SSS} [%t] %X{AWS-XRAY-TRACE-ID} %-5p %m%n
```

AWS X-Ray automatically prints the key and the trace ID in the log statement for easy parsing. The following shows a log statement using the modified `PatternLayout`.

**Example Log statement with ID injection**  

```
2019-09-10 18:58:30.844 [nio-5000-exec-4]  AWS-XRAY-TRACE-ID: 1-5d77f256-19f12e4eaa02e3f76c78f46a@1ce7df03252d99e1 WARN 1 - Your logging message here
```

 The logging message itself is housed in the pattern `%m` and is set when calling the logger.

## Segment listeners


Segment listeners are an interface to intercept lifecycle events such as the beginning and ending of segments produced by the `AWSXRayRecorder`. Implementation of a segment listener event function might be to add the same annotation to all subsegments when they are created with [https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#onBeginSubsegment-com.amazonaws.xray.entities.Subsegment-](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#onBeginSubsegment-com.amazonaws.xray.entities.Subsegment-), log a message after each segment is sent to the daemon using [https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#afterEndSegment-com.amazonaws.xray.entities.Segment-](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#afterEndSegment-com.amazonaws.xray.entities.Segment-), or to record queries sent by the SQL interceptors using [https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#beforeEndSubsegment-com.amazonaws.xray.entities.Subsegment-](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#beforeEndSubsegment-com.amazonaws.xray.entities.Subsegment-) to verify if the subsegment represents an SQL query, adding additional metadata if so.

To see the full list of `SegmentListener` functions, visit the documentation for the [AWS X-Ray Recorder SDK for Java API](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html).

The following example shows how to add a consistent annotation to all subsegments on creation with [https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#onBeginSubsegment-com.amazonaws.xray.entities.Subsegment-](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#onBeginSubsegment-com.amazonaws.xray.entities.Subsegment-) and to print a log message at the end of each segment with [https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#afterEndSegment-com.amazonaws.xray.entities.Segment-](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#afterEndSegment-com.amazonaws.xray.entities.Segment-). 

**Example MySegmentListener.java**  

```
import com.amazonaws.xray.entities.Segment;
import com.amazonaws.xray.entities.Subsegment;
import com.amazonaws.xray.listeners.SegmentListener;

public class MySegmentListener implements SegmentListener {
    .....
    
    @Override
    public void onBeginSubsegment(Subsegment subsegment) {
        subsegment.putAnnotation("annotationKey", "annotationValue");
    }
    
    @Override
    public void afterEndSegment(Segment segment) {
        // Be mindful not to mutate the segment
        logger.info("Segment with ID " + segment.getId());
    }
}
```

This custom segment listener is then referenced when building the `AWSXRayRecorder`.

**Example AWSXRayRecorderBuilder statement**  

```
AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder
        .standard().withSegmentListener(new MySegmentListener());
```

## Environment variables


You can use environment variables to configure the X-Ray SDK for Java. The SDK supports the following variables.
+ `AWS_XRAY_CONTEXT_MISSING` – Set to `RUNTIME_ERROR` to throw exceptions when your instrumented code attempts to record data when no segment is open.

**Valid Values**
  + `RUNTIME_ERROR` – Throw a runtime exception.
  + `LOG_ERROR` – Log an error and continue (default).
  + `IGNORE_ERROR` – Ignore error and continue.

  Errors related to missing segments or subsegments can occur when you attempt to use an instrumented client in startup code that runs when no request is open, or in code that spawns a new thread.
+ `AWS_XRAY_DAEMON_ADDRESS` – Set the host and port of the X-Ray daemon listener. By default, the SDK uses `127.0.0.1:2000` for both trace data (UDP) and sampling (TCP). Use this variable if you have configured the daemon to [listen on a different port](xray-daemon-configuration.md) or if it is running on a different host.

**Format**
  + **Same port** – `address:port`
  + **Different ports** – `tcp:address:port udp:address:port`
+ `AWS_LOG_GROUP` – Set the name of a log group to log group associated with your application. If your log group uses the same AWS account and region as your application, X-Ray will automatically search for your application's segment data using this specified log group. For more information about log groups, see [Working with log groups and streams](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html).
+ `AWS_XRAY_TRACING_NAME` – Set a service name that the SDK uses for segments. Overrides the service name that you set on the servlet filter's [segment naming strategy](xray-sdk-java-filters.md#xray-sdk-java-filters-naming).

Environment variables override equivalent [system properties](#xray-sdk-java-configuration-sysprops) and values set in code.

## System properties


You can use system properties as a JVM-specific alternative to [environment variables](#xray-sdk-java-configuration-envvars). The SDK supports the following properties:
+ `com.amazonaws.xray.strategy.tracingName` – Equivalent to `AWS_XRAY_TRACING_NAME`.
+ `com.amazonaws.xray.emitters.daemonAddress` – Equivalent to `AWS_XRAY_DAEMON_ADDRESS`.
+ `com.amazonaws.xray.strategy.contextMissingStrategy` – Equivalent to `AWS_XRAY_CONTEXT_MISSING`.

If both a system property and the equivalent environment variable are set, the environment variable value is used. Either method overrides values set in code.

# Tracing incoming requests with the X-Ray SDK for Java
Incoming requests

**Note**  
X-Ray SDK/Daemon Maintenance Notice – On February 25th, 2026, the AWS X-Ray SDKs/Daemon will enter maintenance mode, where AWS will limit X-Ray SDK and Daemon releases to address security issues only. For more information on the support timeline, see [X-Ray SDK and Daemon Support timeline](xray-sdk-daemon-timeline.md). We recommend to migrate to OpenTelemetry. For more information on migrating to OpenTelemetry, see [Migrating from X-Ray instrumentation to OpenTelemetry instrumentation ](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-migration.html).

You can use the X-Ray SDK to trace incoming HTTP requests that your application serves on an EC2 instance in Amazon EC2, AWS Elastic Beanstalk, or Amazon ECS.

Use a `Filter` to instrument incoming HTTP requests. When you add the X-Ray servlet filter to your application, the X-Ray SDK for Java creates a segment for each sampled request. This segment includes timing, method, and disposition of the HTTP request. Additional instrumentation creates subsegments on this segment.

**Note**  
For AWS Lambda functions, Lambda creates a segment for each sampled request. See [AWS Lambda and AWS X-Ray](xray-services-lambda.md) for more information.

Each segment has a name that identifies your application in the service map. The segment can be named statically, or you can configure the SDK to name it dynamically based on the host header in the incoming request. Dynamic naming lets you group traces based on the domain name in the request, and apply a default name if the name doesn't match an expected pattern (for example, if the host header is forged).

**Forwarded Requests**  
If a load balancer or other intermediary forwards a request to your application, X-Ray takes the client IP from the `X-Forwarded-For` header in the request instead of from the source IP in the IP packet. The client IP that is recorded for a forwarded request can be forged, so it should not be trusted.

When a request is forwarded, the SDK sets an additional field in the segment to indicate this. If the segment contains the field `x_forwarded_for` set to `true`, the client IP was taken from the `X-Forwarded-For` header in the HTTP request.

The message handler creates a segment for each incoming request with an `http` block that contains the following information:
+ **HTTP method** – GET, POST, PUT, DELETE, etc.
+ **Client address** – The IP address of the client that sent the request.
+ **Response code** – The HTTP response code for the completed request.
+ **Timing** – The start time (when the request was received) and end time (when the response was sent).
+ **User agent** — The `user-agent` from the request.
+ **Content length** — The `content-length` from the response.

**Topics**
+ [

## Adding a tracing filter to your application (Tomcat)
](#xray-sdk-java-filters-tomcat)
+ [

## Adding a tracing filter to your application (spring)
](#xray-sdk-java-filters-spring)
+ [

## Configuring a segment naming strategy
](#xray-sdk-java-filters-naming)

## Adding a tracing filter to your application (Tomcat)


For Tomcat, add a `<filter>` to your project's `web.xml` file. Use the `fixedName` parameter to specify a [service name](#xray-sdk-java-filters-naming) to apply to segments created for incoming requests.

**Example WEB-INF/web.xml - Tomcat**  

```
<filter>
  <filter-name>AWSXRayServletFilter</filter-name>
  <filter-class>com.amazonaws.xray.javax.servlet.AWSXRayServletFilter</filter-class>
  <init-param>
    <param-name>fixedName</param-name>
    <param-value>MyApp</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>AWSXRayServletFilter</filter-name>
  <url-pattern>*</url-pattern>
</filter-mapping>
```

## Adding a tracing filter to your application (spring)


For Spring, add a `Filter` to your `WebConfig` class. Pass the segment name to the [https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html) constructor as a string.

**Example src/main/java/myapp/WebConfig.java - spring**  

```
package myapp;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
import javax.servlet.Filter;
import [com.amazonaws.xray.javax.servlet.AWSXRayServletFilter](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html);

@Configuration
public class WebConfig {

  @Bean
  public Filter TracingFilter() {
    return new AWSXRayServletFilter("Scorekeep");
  }
}
```

## Configuring a segment naming strategy


AWS X-Ray uses a *service name* to identify your application and distinguish it from the other applications, databases, external APIs, and AWS resources that your application uses. When the X-Ray SDK generates segments for incoming requests, it records your application's service name in the segment's [name field](xray-api-segmentdocuments.md#api-segmentdocuments-fields).

The X-Ray SDK can name segments after the hostname in the HTTP request header. However, this header can be forged, which could result in unexpected nodes in your service map. To prevent the SDK from naming segments incorrectly due to requests with forged host headers, you must specify a default name for incoming requests.

If your application serves requests for multiple domains, you can configure the SDK to use a dynamic naming strategy to reflect this in segment names. A dynamic naming strategy allows the SDK to use the hostname for requests that match an expected pattern, and apply the default name to requests that don't.

For example, you might have a single application serving requests to three subdomains– `www.example.com`, `api.example.com`, and `static.example.com`. You can use a dynamic naming strategy with the pattern `*.example.com` to identify segments for each subdomain with a different name, resulting in three service nodes on the service map. If your application receives requests with a hostname that doesn't match the pattern, you will see a fourth node on the service map with a fallback name that you specify.

To use the same name for all request segments, specify the name of your application when you initialize the servlet filter, as shown in [the previous section](#xray-sdk-java-filters-tomcat). This has the same effect as creating a fixed [SegmentNamingStrategy](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/strategy/SegmentNamingStrategy.html) by calling `SegmentNamingStrategy.fixed()` and passing it to the [https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html) constructor.

**Note**  
You can override the default service name that you define in code with the `AWS_XRAY_TRACING_NAME` [environment variable](xray-sdk-java-configuration.md#xray-sdk-java-configuration-envvars).

A dynamic naming strategy defines a pattern that hostnames should match, and a default name to use if the hostname in the HTTP request does not match the pattern. To name segments dynamically in Tomcat, use the `dynamicNamingRecognizedHosts` and `dynamicNamingFallbackName` to define the pattern and default name, respectively.

**Example WEB-INF/web.xml - servlet filter with dynamic naming**  

```
<filter>
  <filter-name>AWSXRayServletFilter</filter-name>
  <filter-class>com.amazonaws.xray.javax.servlet.AWSXRayServletFilter</filter-class>
  <init-param>
    <param-name>dynamicNamingRecognizedHosts</param-name>
    <param-value>*.example.com</param-value>
  </init-param>
  <init-param>
    <param-name>dynamicNamingFallbackName</param-name>
    <param-value>MyApp</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>AWSXRayServletFilter</filter-name>
  <url-pattern>*</url-pattern>
</filter-mapping>
```

For Spring, create a dynamic [SegmentNamingStrategy](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/strategy/SegmentNamingStrategy.html) by calling `SegmentNamingStrategy.dynamic()`, and pass it to the `AWSXRayServletFilter` constructor.

**Example src/main/java/myapp/WebConfig.java - servlet filter with dynamic naming**  

```
package myapp;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
import javax.servlet.Filter;
import [com.amazonaws.xray.javax.servlet.AWSXRayServletFilter](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html);
import [com.amazonaws.xray.strategy.SegmentNamingStrategy](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/strategy/SegmentNamingStrategy.html);

@Configuration
public class WebConfig {

  @Bean
  public Filter TracingFilter() {
    return new AWSXRayServletFilter(SegmentNamingStrategy.dynamic("MyApp", "*.example.com"));
  }
}
```

# Tracing AWS SDK calls with the X-Ray SDK for Java
AWS SDK clients

**Note**  
X-Ray SDK/Daemon Maintenance Notice – On February 25th, 2026, the AWS X-Ray SDKs/Daemon will enter maintenance mode, where AWS will limit X-Ray SDK and Daemon releases to address security issues only. For more information on the support timeline, see [X-Ray SDK and Daemon Support timeline](xray-sdk-daemon-timeline.md). We recommend to migrate to OpenTelemetry. For more information on migrating to OpenTelemetry, see [Migrating from X-Ray instrumentation to OpenTelemetry instrumentation ](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-migration.html).

When your application makes calls to AWS services to store data, write to a queue, or send notifications, the X-Ray SDK for Java tracks the calls downstream in [subsegments](xray-sdk-java-subsegments.md). Traced AWS services and resources that you access within those services (for example, an Amazon S3 bucket or Amazon SQS queue), appear as downstream nodes on the trace map in the X-Ray console.

The X-Ray SDK for Java automatically instruments all AWS SDK clients when you include the `aws-sdk` and an `aws-sdk-instrumentor` [submodules](xray-sdk-java.md#xray-sdk-java-submodules) in your build. If you don't include the Instrumentor submodule, you can choose to instrument some clients while excluding others.

To instrument individual clients, remove the `aws-sdk-instrumentor` submodule from your build and add an `XRayClient` as a `TracingHandler` on your AWS SDK client using the service's client builder.

For example, to instrument an `AmazonDynamoDB` client, pass a tracing handler to `AmazonDynamoDBClientBuilder`.

**Example MyModel.java - DynamoDB client**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
import [com.amazonaws.xray.handlers.TracingHandler](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/handlers/TracingHandler.html);

...
public class MyModel {
  private AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
        .withRegion(Regions.fromName(System.getenv("AWS_REGION")))
        .withRequestHandlers(new TracingHandler(AWSXRay.getGlobalRecorder()))
        .build();
...
```

For all services, you can see the name of the API called in the X-Ray console. For a subset of services, the X-Ray SDK adds information to the segment to provide more granularity in the service map.

For example, when you make a call with an instrumented DynamoDB client, the SDK adds the table name to the segment for calls that target a table. In the console, each table appears as a separate node in the service map, with a generic DynamoDB node for calls that don't target a table.

**Example Subsegment for a call to DynamoDB to save an item**  

```
{
  "id": "24756640c0d0978a",
  "start_time": 1.480305974194E9,
  "end_time": 1.4803059742E9,
  "name": "DynamoDB",
  "namespace": "aws",
  "http": {
    "response": {
      "content_length": 60,
      "status": 200
    }
  },
  "aws": {
    "table_name": "scorekeep-user",
    "operation": "UpdateItem",
    "request_id": "UBQNSO5AEM8T4FDA4RQDEB94OVTDRVV4K4HIRGVJF66Q9ASUAAJG",
  }
}
```

When you access named resources, calls to the following services create additional nodes in the service map. Calls that don't target specific resources create a generic node for the service.
+ **Amazon DynamoDB** – Table name
+ **Amazon Simple Storage Service** – Bucket and key name
+ **Amazon Simple Queue Service** – Queue name

To instrument downstream calls to AWS services with AWS SDK for Java 2.2 and later, you can omit the `aws-xray-recorder-sdk-aws-sdk-v2-instrumentor` module from your build configuration. Include the `aws-xray-recorder-sdk-aws-sdk-v2 module` instead, then instrument individual clients by configuring them with a `TracingInterceptor`. 

**Example AWS SDK for Java 2.2 and later - tracing interceptor**  

```
import com.amazonaws.xray.interceptors.TracingInterceptor;
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
//...
public class MyModel {
private DynamoDbClient client = DynamoDbClient.builder()
.region(Region.US_WEST_2)
.overrideConfiguration(ClientOverrideConfiguration.builder()
.addExecutionInterceptor(new TracingInterceptor())
.build()
)
.build();
//...
```

# Tracing calls to downstream HTTP web services with the X-Ray SDK for Java
Outgoing HTTP calls

**Note**  
X-Ray SDK/Daemon Maintenance Notice – On February 25th, 2026, the AWS X-Ray SDKs/Daemon will enter maintenance mode, where AWS will limit X-Ray SDK and Daemon releases to address security issues only. For more information on the support timeline, see [X-Ray SDK and Daemon Support timeline](xray-sdk-daemon-timeline.md). We recommend to migrate to OpenTelemetry. For more information on migrating to OpenTelemetry, see [Migrating from X-Ray instrumentation to OpenTelemetry instrumentation ](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-migration.html).

When your application makes calls to microservices or public HTTP APIs, you can use the X-Ray SDK for Java's version of `HttpClient` to instrument those calls and add the API to the service graph as a downstream service.

The X-Ray SDK for Java includes `DefaultHttpClient` and `HttpClientBuilder` classes that can be used in place of the Apache HttpComponents equivalents to instrument outgoing HTTP calls.
+ `com.amazonaws.xray.proxies.apache.http.DefaultHttpClient` - `org.apache.http.impl.client.DefaultHttpClient`
+ `com.amazonaws.xray.proxies.apache.http.HttpClientBuilder` - `org.apache.http.impl.client.HttpClientBuilder`

These libraries are in the [`aws-xray-recorder-sdk-apache-http`](xray-sdk-java.md) submodule.

You can replace your existing import statements with the X-Ray equivalent to instrument all clients, or use the fully qualified name when you initialize a client to instrument specific clients.

**Example HttpClientBuilder**  

```
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import [com.amazonaws.xray.proxies.apache.http.HttpClientBuilder](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/proxies/apache/http/HttpClientBuilder.html);
...
  public String randomName() throws IOException {
    CloseableHttpClient httpclient = HttpClientBuilder.create().build();
    HttpGet httpGet = new HttpGet("http://names.example.com/api/");
    CloseableHttpResponse response = httpclient.execute(httpGet);
    try {
      HttpEntity entity = response.getEntity();
      InputStream inputStream = entity.getContent();
      ObjectMapper mapper = new ObjectMapper();
      Map<String, String> jsonMap = mapper.readValue(inputStream, Map.class);
      String name = jsonMap.get("name");
      EntityUtils.consume(entity);
      return name;
    } finally {
      response.close();
    }
  }
```

When you instrument a call to a downstream web api, the X-Ray SDK for Java records a subsegment with information about the HTTP request and response. X-Ray uses the subsegment to generate an inferred segment for the remote API.

**Example Subsegment for a downstream HTTP call**  

```
{
  "id": "004f72be19cddc2a",
  "start_time": 1484786387.131,
  "end_time": 1484786387.501,
  "name": "names.example.com",
  "namespace": "remote",
  "http": {
    "request": {
      "method": "GET",
      "url": "https://names.example.com/"
    },
    "response": {
      "content_length": -1,
      "status": 200
    }
  }
}
```

**Example Inferred segment for a downstream HTTP call**  

```
{
  "id": "168416dc2ea97781",
  "name": "names.example.com",
  "trace_id": "1-62be1272-1b71c4274f39f122afa64eab",
  "start_time": 1484786387.131,
  "end_time": 1484786387.501,
  "parent_id": "004f72be19cddc2a",
  "http": {
    "request": {
      "method": "GET",
      "url": "https://names.example.com/"
    },
    "response": {
      "content_length": -1,
      "status": 200
    }
  },
  "inferred": true
}
```

# Tracing SQL queries with the X-Ray SDK for Java
SQL queries

**Note**  
X-Ray SDK/Daemon Maintenance Notice – On February 25th, 2026, the AWS X-Ray SDKs/Daemon will enter maintenance mode, where AWS will limit X-Ray SDK and Daemon releases to address security issues only. For more information on the support timeline, see [X-Ray SDK and Daemon Support timeline](xray-sdk-daemon-timeline.md). We recommend to migrate to OpenTelemetry. For more information on migrating to OpenTelemetry, see [Migrating from X-Ray instrumentation to OpenTelemetry instrumentation ](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-migration.html).

## SQL Interceptors


Instrument SQL database queries by adding the X-Ray SDK for Java JDBC interceptor to your data source configuration.
+  **PostgreSQL** – `com.amazonaws.xray.sql.postgres.TracingInterceptor` 
+  **MySQL** – `com.amazonaws.xray.sql.mysql.TracingInterceptor` 

These interceptors are in the [`aws-xray-recorder-sql-postgres` and `aws-xray-recorder-sql-mysql` submodules](xray-sdk-java.md), respectively. They implement `org.apache.tomcat.jdbc.pool.JdbcInterceptor` and are compatible with Tomcat connection pools.

**Note**  
SQL interceptors do not record the SQL query itself within subsegments for security purposes.

For Spring, add the interceptor in a properties file and build the data source with Spring Boot's `DataSourceBuilder`.

**Example `src/main/java/resources/application.properties` - PostgreSQL JDBC interceptor**  

```
spring.datasource.continue-on-error=true
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.jdbc-interceptors=com.amazonaws.xray.sql.postgres.TracingInterceptor
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL94Dialect
```

**Example `src/main/java/myapp/WebConfig.java` - Data source**  

```
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

import javax.servlet.Filter;
import javax.sql.DataSource;
import java.net.URL;

@Configuration
@EnableAutoConfiguration
@EnableJpaRepositories("myapp")
public class RdsWebConfig {

  @Bean
  @ConfigurationProperties(prefix = "spring.datasource")
  public DataSource dataSource() {
      logger.info("Initializing PostgreSQL datasource");
      return DataSourceBuilder.create()
              .driverClassName("org.postgresql.Driver")
              .url("jdbc:postgresql://" + System.getenv("RDS_HOSTNAME") + ":" + System.getenv("RDS_PORT") + "/ebdb")
              .username(System.getenv("RDS_USERNAME"))
              .password(System.getenv("RDS_PASSWORD"))
              .build();
  }
...
}
```

For Tomcat, call `setJdbcInterceptors` on the JDBC data source with a reference to the X-Ray SDK for Java class.

**Example `src/main/myapp/model.java` - Data source**  

```
import org.apache.tomcat.jdbc.pool.DataSource;
...
DataSource source = new DataSource();
source.setUrl(url);
source.setUsername(user);
source.setPassword(password);
source.setDriverClassName("com.mysql.jdbc.Driver");
source.setJdbcInterceptors("com.amazonaws.xray.sql.mysql.TracingInterceptor;");
```

The Tomcat JDBC Data Source library is included in the X-Ray SDK for Java, but you can declare it as a provided dependency to document that you use it.

**Example `pom.xml` - JDBC data source**  

```
<dependency>
  <groupId>org.apache.tomcat</groupId>
  <artifactId>tomcat-jdbc</artifactId>
  <version>8.0.36</version>
  <scope>provided</scope>
</dependency>
```

## Native SQL Tracing Decorator

+ Add [https://github.com/aws/aws-xray-sdk-java/tree/master/aws-xray-recorder-sdk-sql](https://github.com/aws/aws-xray-sdk-java/tree/master/aws-xray-recorder-sdk-sql) to your dependencies. 
+ Decorate your database datasource, connection, or statement. 

  ```
  dataSource = TracingDataSource.decorate(dataSource)
  connection = TracingConnection.decorate(connection)
  statement = TracingStatement.decorateStatement(statement)
  preparedStatement = TracingStatement.decoratePreparedStatement(preparedStatement, sql)
  callableStatement = TracingStatement.decorateCallableStatement(callableStatement, sql)
  ```

# Generating custom subsegments with the X-Ray SDK for Java
Custom subsegments

**Note**  
X-Ray SDK/Daemon Maintenance Notice – On February 25th, 2026, the AWS X-Ray SDKs/Daemon will enter maintenance mode, where AWS will limit X-Ray SDK and Daemon releases to address security issues only. For more information on the support timeline, see [X-Ray SDK and Daemon Support timeline](xray-sdk-daemon-timeline.md). We recommend to migrate to OpenTelemetry. For more information on migrating to OpenTelemetry, see [Migrating from X-Ray instrumentation to OpenTelemetry instrumentation ](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-migration.html).

Subsegments extend a trace's [segment](xray-concepts.md#xray-concepts-segments) with details about work done in order to serve a request. Each time you make a call with an instrumented client, the X-Ray SDK records the information generated in a subsegment. You can create additional subsegments to group other subsegments, to measure the performance of a section of code, or to record annotations and metadata.

To manage subsegments, use the `beginSubsegment` and `endSubsegment` methods.

**Example GameModel.java - custom subsegment**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
...
  public void saveGame(Game game) throws SessionNotFoundException {
    // wrap in subsegment
    Subsegment subsegment = AWSXRay.beginSubsegment("Save Game");
    try {
      // check session
      String sessionId = game.getSession();
      if (sessionModel.loadSession(sessionId) == null ) {
        throw new SessionNotFoundException(sessionId);
      }
      mapper.save(game);
    } catch (Exception e) {
      subsegment.addException(e);
      throw e;
    } finally {
      AWSXRay.endSubsegment();
    }
  }
```

In this example, the code within the subsegment loads the game's session from DynamoDB with a method on the session model, and uses the AWS SDK for Java's DynamoDB mapper to save the game. Wrapping this code in a subsegment makes the calls DynamoDB children of the `Save Game` subsegment in the trace view in the console.

![\[Timeline showing Scorekeep and DynamoDB operations with durations and status checks.\]](http://docs.aws.amazon.com/xray/latest/devguide/images/scorekeep-PUTrules-timeline-subsegments.png)


If the code in your subsegment throws checked exceptions, wrap it in a `try` block and call `AWSXRay.endSubsegment()` in a `finally` block to ensure that the subsegment is always closed. If a subsegment is not closed, the parent segment cannot be completed and won't be sent to X-Ray.

For code that doesn't throw checked exceptions, you can pass the code to `AWSXRay.CreateSubsegment` as a Lambda function.

**Example Subsegment Lambda function**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);

AWSXRay.createSubsegment("getMovies", (subsegment) -> {
    // function code
});
```

When you create a subsegment within a segment or another subsegment, the X-Ray SDK for Java generates an ID for it and records the start time and end time.

**Example Subsegment with metadata**  

```
"subsegments": [{
  "id": "6f1605cd8a07cb70",
  "start_time": 1.480305974194E9,
  "end_time": 1.4803059742E9,
  "name": "Custom subsegment for UserModel.saveUser function",
  "metadata": {
    "debug": {
      "test": "Metadata string from UserModel.saveUser"
    }
  },
```

For asynchronous and multi-threaded programming, you must manually pass the subsegment to the `endSubsegment()` method to ensure it is closed correctly because the X-Ray context may be modified during async execution. If an asynchronous subsegment is closed after its parent segment is closed, this method will automatically stream the entire segment to the X-Ray daemon.

**Example Asynchronous Subsegment**  

```
@GetMapping("/api")
public ResponseEntity<?> api() {
  CompletableFuture.runAsync(() -> {
      Subsegment subsegment = AWSXRay.beginSubsegment("Async Work");
      try {
          Thread.sleep(3000);
      } catch (InterruptedException e) {
          subsegment.addException(e);
          throw e;
      } finally {
          AWSXRay.endSubsegment(subsegment);
      }
  });
  return ResponseEntity.ok().build();
}
```

# Add annotations and metadata to segments with the X-Ray SDK for Java
Annotations and metadata

**Note**  
X-Ray SDK/Daemon Maintenance Notice – On February 25th, 2026, the AWS X-Ray SDKs/Daemon will enter maintenance mode, where AWS will limit X-Ray SDK and Daemon releases to address security issues only. For more information on the support timeline, see [X-Ray SDK and Daemon Support timeline](xray-sdk-daemon-timeline.md). We recommend to migrate to OpenTelemetry. For more information on migrating to OpenTelemetry, see [Migrating from X-Ray instrumentation to OpenTelemetry instrumentation ](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-migration.html).

You can record additional information about requests, the environment, or your application with annotations and metadata. You can add annotations and metadata to the segments that the X-Ray SDK creates, or to custom subsegments that you create.

**Annotations** are key-value pairs with string, number, or Boolean values. Annotations are indexed for use with [filter expressions](xray-console-filters.md). Use annotations to record data that you want to use to group traces in the console, or when calling the [https://docs.aws.amazon.com/xray/latest/api/API_GetTraceSummaries.html](https://docs.aws.amazon.com/xray/latest/api/API_GetTraceSummaries.html) API.

**Metadata** are key-value pairs that can have values of any type, including objects and lists, but are not indexed for use with filter expressions. Use metadata to record additional data that you want stored in the trace but don't need to use with search.

In addition to annotations and metadata, you can also [record user ID strings](#xray-sdk-java-segment-userid) on segments. User IDs are recorded in a separate field on segments and are indexed for use with search.

**Topics**
+ [

## Recording annotations with the X-Ray SDK for Java
](#xray-sdk-java-segment-annotations)
+ [

## Recording metadata with the X-Ray SDK for Java
](#xray-sdk-java-segment-metadata)
+ [

## Recording user IDs with the X-Ray SDK for Java
](#xray-sdk-java-segment-userid)

## Recording annotations with the X-Ray SDK for Java


Use annotations to record information on segments or subsegments that you want indexed for search.

**Annotation Requirements**
+ **Keys** – The key for an X-Ray annotation can have up to 500 alphanumeric characters. You cannot use spaces or symbols other than a dot or period ( . )
+ **Values** – The value for an X-Ray annotation can have up to 1,000 Unicode characters.
+ The number of **Annotations** – You can use up to 50 annotations per trace.

**To record annotations**

1. Get a reference to the current segment or subsegment from `AWSXRay`.

   ```
   import [com.amazonaws.xray.AWSXRay](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
   import [com.amazonaws.xray.entities.Segment](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Segment.html);
   ...
   Segment document = AWSXRay.getCurrentSegment();
   ```

   or

   ```
   import [com.amazonaws.xray.AWSXRay](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
   import [com.amazonaws.xray.entities.Subsegment](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Subsegment.html);
   ...
   Subsegment document = AWSXRay.getCurrentSubsegment();
   ```

1. Call `putAnnotation` with a String key, and a Boolean, Number, or String value.

   ```
   document.putAnnotation("mykey", "my value");
   ```

   The following example shows how to call `putAnnotation` with a String key that includes a dot, and a Boolean, Number, or String value.

   ```
   document.putAnnotation("testkey.test", "my value");
   ```

The SDK records annotations as key-value pairs in an `annotations` object in the segment document. Calling `putAnnotation` twice with the same key overwrites previously recorded values on the same segment or subsegment.

To find traces that have annotations with specific values, use the `annotation[key]` keyword in a [filter expression](xray-console-filters.md).

**Example [https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/GameModel.java](https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/GameModel.java) – Annotations and metadata**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
import [com.amazonaws.xray.entities.Segment](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Segment.html);
import [com.amazonaws.xray.entities.Subsegment](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Subsegment.html);
...
  public void saveGame(Game game) throws SessionNotFoundException {
    // wrap in subsegment
    Subsegment subsegment = AWSXRay.beginSubsegment("## GameModel.saveGame");
    try {
      // check session
      String sessionId = game.getSession();
      if (sessionModel.loadSession(sessionId) == null ) {
        throw new SessionNotFoundException(sessionId);
      }
      Segment segment = AWSXRay.getCurrentSegment();
      subsegment.putMetadata("resources", "game", game);
      segment.putAnnotation("gameid", game.getId());
      mapper.save(game);
    } catch (Exception e) {
      subsegment.addException(e);
      throw e;
    } finally {
      AWSXRay.endSubsegment();
    }
  }
```

## Recording metadata with the X-Ray SDK for Java


Use metadata to record information on segments or subsegments that you don't need indexed for search. Metadata values can be strings, numbers, Booleans, or any object that can be serialized into a JSON object or array.

**To record metadata**

1. Get a reference to the current segment or subsegment from `AWSXRay`.

   ```
   import [com.amazonaws.xray.AWSXRay](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
   import [com.amazonaws.xray.entities.Segment](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Segment.html);
   ...
   Segment document = AWSXRay.getCurrentSegment();
   ```

   or

   ```
   import [com.amazonaws.xray.AWSXRay](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
   import [com.amazonaws.xray.entities.Subsegment](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Subsegment.html);
   ...
   Subsegment document = AWSXRay.getCurrentSubsegment();
   ```

1. Call `putMetadata` with a String namespace, String key, and a Boolean, Number, String, or Object value.

   ```
   document.putMetadata("my namespace", "my key", "my value");
   ```

   or

   Call `putMetadata` with just a key and value.

   ```
   document.putMetadata("my key", "my value");
   ```

If you don't specify a namespace, the SDK uses `default`. Calling `putMetadata` twice with the same key overwrites previously recorded values on the same segment or subsegment.

**Example [https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/GameModel.java](https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/GameModel.java) – Annotations and metadata**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
import [com.amazonaws.xray.entities.Segment](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Segment.html);
import [com.amazonaws.xray.entities.Subsegment](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Subsegment.html);
...
  public void saveGame(Game game) throws SessionNotFoundException {
    // wrap in subsegment
    Subsegment subsegment = AWSXRay.beginSubsegment("## GameModel.saveGame");
    try {
      // check session
      String sessionId = game.getSession();
      if (sessionModel.loadSession(sessionId) == null ) {
        throw new SessionNotFoundException(sessionId);
      }
      Segment segment = AWSXRay.getCurrentSegment();
      subsegment.putMetadata("resources", "game", game);
      segment.putAnnotation("gameid", game.getId());
      mapper.save(game);
    } catch (Exception e) {
      subsegment.addException(e);
      throw e;
    } finally {
      AWSXRay.endSubsegment();
    }
  }
```

## Recording user IDs with the X-Ray SDK for Java


Record user IDs on request segments to identify the user who sent the request.

**To record user IDs**

1. Get a reference to the current segment from `AWSXRay`.

   ```
   import [com.amazonaws.xray.AWSXRay](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
   import [com.amazonaws.xray.entities.Segment](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Segment.html);
   ...
   Segment document = AWSXRay.getCurrentSegment();
   ```

1. Call `setUser` with a string ID of the user who sent the request.

   ```
   document.setUser("U12345");
   ```

You can call `setUser` in your controllers to record the user ID as soon as your application starts processing a request. If you will only use the segment to set the user ID, you can chain the calls in a single line.

**Example [src/main/java/scorekeep/MoveController.java](https://github.com/awslabs/eb-java-scorekeep/tree/xray/src/main/java/scorekeep/MoveController.java) – User ID**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
...
  @RequestMapping(value="/{userId}", method=RequestMethod.POST)
  public Move newMove(@PathVariable String sessionId, @PathVariable String gameId, @PathVariable String userId, @RequestBody String move) throws SessionNotFoundException, GameNotFoundException, StateNotFoundException, RulesException {
    AWSXRay.getCurrentSegment().setUser(userId);
    return moveFactory.newMove(sessionId, gameId, userId, move);
  }
```

To find traces for a user ID, use the `user` keyword in a [filter expression](xray-console-filters.md).

## AWS X-Ray metrics for the X-Ray SDK for Java
Monitoring

**Note**  
X-Ray SDK/Daemon Maintenance Notice – On February 25th, 2026, the AWS X-Ray SDKs/Daemon will enter maintenance mode, where AWS will limit X-Ray SDK and Daemon releases to address security issues only. For more information on the support timeline, see [X-Ray SDK and Daemon Support timeline](xray-sdk-daemon-timeline.md). We recommend to migrate to OpenTelemetry. For more information on migrating to OpenTelemetry, see [Migrating from X-Ray instrumentation to OpenTelemetry instrumentation ](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-migration.html).

This topic describes the AWS X-Ray namespace, metrics, and dimensions. You can use the X-Ray SDK for Java to publish unsampled Amazon CloudWatch metrics from your collected X-Ray segments. These metrics are derived from the segment’s start and end time, and the error, fault, and throttled status flags. Use these trace metrics to expose retries and dependency issues within subsegments. 

CloudWatch is a metrics repository. A metric is the fundamental concept in CloudWatch and represents a time-ordered set of data points. You (or AWS services) publish metrics data points into CloudWatch and you retrieve statistics about those data points as an ordered set of time-series data. 

Metrics are uniquely defined by a name, a namespace, and one or more dimensions. Each data point has a timestamp and, optionally, a unit of measure. When you request statistics, the returned data stream is identified by namespace, metric name, and dimension. 

For more information about CloudWatch, see the [https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/](https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/). 

### X-Ray CloudWatch metrics


The `ServiceMetrics/SDK` namespace includes the following metrics.


| Metric | Statistics available | Description | Units | 
| --- | --- | --- | --- | 
|  `Latency`  |  Average, Minimum, Maximum, Count  |  The difference between the start and end time. Average, minimum, and maximum all describe operational latency. Count describes call count.  |  Milliseconds  | 
|  `ErrorRate`  |  Average, Sum  |  The rate of requests that failed with a `4xx Client Error` status code, resulting in an error.  |  Percent  | 
|  `FaultRate`  |  Average, Sum  |  The rate of traces that failed with a `5xx Server Error` status code, resulting in a fault.  |  Percent  | 
|  `ThrottleRate`  |  Average, Sum  |  The rate of throttled traces that return a `429` status code. This is a subset of the `ErrorRate` metric.   |  Percent  | 
|  `OkRate`  |  Average, Sum  |  The rate of traced requests resulting in an `OK` status code.   |  Percent  | 

### X-Ray CloudWatch dimensions


Use the dimensions in the following table to refine the metrics returned for your X-Ray instrumented Java applications.


| Dimension | Description | 
| --- | --- | 
|  `ServiceType`  |  The type of the service, for example, `AWS::EC2::Instance` or `NONE`, if not known.  | 
|  `ServiceName`  |  The canonical name for the service.  | 

### Enable X-Ray CloudWatch metrics


Use the following procedure to enable trace metrics in your instrumented Java application.

**To configure trace metrics**

1. Add the `aws-xray-recorder-sdk-metrics` package as an Apache Maven dependency. For more information, see [X-Ray SDK for Java Submodules](#xray-sdk-java-submodules).

1. Enable a new `MetricsSegmentListener()` as part of the global recorder build.  
**Example src/com/myapp/web/Startup.java**  

   ```
   import com.amazonaws.xray.AWSXRay;
   import com.amazonaws.xray.AWSXRayRecorderBuilder;
   import com.amazonaws.xray.plugins.EC2Plugin;
   import com.amazonaws.xray.plugins.ElasticBeanstalkPlugin;
   import com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy;
   
   @Configuration
   public class WebConfig {
   ...
     static {
       AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder
                                           .standard()
                                           .withPlugin(new EC2Plugin())
                                           .withPlugin(new ElasticBeanstalkPlugin())
                                           .withSegmentListener(new MetricsSegmentListener());
   
       URL ruleFile = WebConfig.class.getResource("/sampling-rules.json");
       builder.withSamplingStrategy(new LocalizedSamplingStrategy(ruleFile));
   
       AWSXRay.setGlobalRecorder(builder.build());
     }
   }
   ```

1. Deploy the CloudWatch agent to collect metrics using Amazon Elastic Compute Cloud (Amazon EC2), Amazon Elastic Container Service (Amazon ECS), or Amazon Elastic Kubernetes Service (Amazon EKS):
   +  To configure Amazon EC2, see [ Installing the CloudWatch agent](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-on-EC2-Instance.html).
   +  To configure Amazon ECS, see [Monitor Amazon ECS containers using Container Insights](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/cloudwatch-container-insights.html).
   +  To configure Amazon EKS, see [ Install the CloudWatch agent by using the Amazon CloudWatch Observability EKS add-on](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Observability-EKS-addon.html).

1. Configure the SDK to communicate with the CloudWatch agent. By default, the SDK communicates with the CloudWatch agent on the address `127.0.0.1`. You can configure alternate addresses by setting the environment variable or Java property to `address:port`.  
**Example Environment variable**  

   ```
   AWS_XRAY_METRICS_DAEMON_ADDRESS=address:port
   ```  
**Example Java property**  

   ```
   com.amazonaws.xray.metrics.daemonAddress=address:port
   ```

**To validate configuration**

1. Sign in to the AWS Management Console and open the CloudWatch console at [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/).

1. Open the **Metrics** tab to observe the influx of your metrics. 

1. (Optional) In the CloudWatch console, on the **Logs** tab, open the `ServiceMetricsSDK` log group. Look for a log stream that matches the host metrics, and confirm the log messages.

# Passing segment context between threads in a multithreaded application
Multithreading

**Note**  
X-Ray SDK/Daemon Maintenance Notice – On February 25th, 2026, the AWS X-Ray SDKs/Daemon will enter maintenance mode, where AWS will limit X-Ray SDK and Daemon releases to address security issues only. For more information on the support timeline, see [X-Ray SDK and Daemon Support timeline](xray-sdk-daemon-timeline.md). We recommend to migrate to OpenTelemetry. For more information on migrating to OpenTelemetry, see [Migrating from X-Ray instrumentation to OpenTelemetry instrumentation ](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-migration.html).

When you create a new thread in your application, the `AWSXRayRecorder` doesn't maintain a reference to the current segment or subsegment [Entity](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Entity.html). If you use an instrumented client in the new thread, the SDK tries to write to a segment that doesn't exist, causing a [SegmentNotFoundException](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/exceptions/SegmentNotFoundException.html).

To avoid throwing exceptions during development, you can configure the recorder with a [ContextMissingStrategy](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/strategy/ContextMissingStrategy.html) that tells it to log an error instead. You can configure the strategy in code with [SetContextMissingStrategy](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRayRecorder.html#setContextMissingStrategy(com.amazonaws.xray.strategy.ContextMissingStrategy)), or configure equivalent options with an [environment variable](xray-sdk-java-configuration.md#xray-sdk-java-configuration-envvars) or [system property](xray-sdk-java-configuration.md#xray-sdk-java-configuration-sysprops).

One way to address the error is to use a new segment by calling [beginSegment](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRayRecorder.html#beginSegment(java.lang.String)) when you start the thread and [endSegment](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRayRecorder.html#endSegment--) when you close it. This works if you are instrumenting code that doesn't run in response to an HTTP request, like code that runs when your application starts.

If you use multiple threads to handle incoming requests, you can pass the current segment or subsegment to the new thread and provide it to the global recorder. This ensures that the information recorded within the new thread is associated with the same segment as the rest of the information recorded about that request. Once the segment is available in the new thread, you can execute any runnable with access to that segment's context using the `segment.run(() -> { ... })` method.

See [Using instrumented clients in worker threads](scorekeep-workerthreads.md) for an example.

## Using X-Ray with Asynchronous Programming


 The X-Ray SDK for Java can be used in asynchronous Java programs with [SegmentContextExecutors](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/contexts/SegmentContextExecutors.html). The SegmentContextExecutor implements the Executor interface, which means it can be passed into all asynchronous operations of a [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html). This ensures that any asynchronous operations will be executed with the correct segment in its context. 

**Example App.java: Passing SegmentContextExecutor to CompletableFuture**  

```
DynamoDbAsyncClient client = DynamoDbAsyncClient.create();

AWSXRay.beginSegment();

// ...

client.getItem(request).thenComposeAsync(response -> {
    // If we did not provide the segment context executor, this request would not be traced correctly.
    return client.getItem(request2);
}, SegmentContextExecutors.newSegmentContextExecutor());
```

# AOP with Spring and the X-Ray SDK for Java
AOP with Spring

**Note**  
X-Ray SDK/Daemon Maintenance Notice – On February 25th, 2026, the AWS X-Ray SDKs/Daemon will enter maintenance mode, where AWS will limit X-Ray SDK and Daemon releases to address security issues only. For more information on the support timeline, see [X-Ray SDK and Daemon Support timeline](xray-sdk-daemon-timeline.md). We recommend to migrate to OpenTelemetry. For more information on migrating to OpenTelemetry, see [Migrating from X-Ray instrumentation to OpenTelemetry instrumentation ](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-migration.html).

This topic describes how to use the X-Ray SDK and the Spring Framework to instrument your application without changing its core logic. This means that there is now a non-invasive way to instrument your applications running remotely in AWS.

**To enable AOP in spring**

1. [Configure Spring](#xray-sdk-java-aop-spring-configuration)

1. [Add a tracing filter to your application](#xray-sdk-java-aop-filters-spring)

1. [Annotate your code or implement an interface](#xray-sdk-java-aop-annotate-or-implement)

1. [Activate X-Ray in your application](#xray-sdk-java-aop-activate-xray)

## Configuring Spring


You can use Maven or Gradle to configure Spring to use AOP to instrument your application.

If you use Maven to build your application, add the following dependency in your `pom.xml` file.

```
<dependency> 
     <groupId>com.amazonaws</groupId> 
     <artifactId>aws-xray-recorder-sdk-spring</artifactId> 
     <version>2.11.0</version> 
</dependency>
```

For Gradle, add the following dependency in your `build.gradle` file.

```
compile 'com.amazonaws:aws-xray-recorder-sdk-spring:2.11.0'
```

## Configuring Spring Boot


In addition to the Spring dependency described in the previous section, if you’re using Spring Boot, add the following dependency if it’s not already on your classpath. 

Maven:

```
<dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-aop</artifactId> 
     <version>2.5.2</version> 
</dependency>
```

Gradle:

```
compile 'org.springframework.boot:spring-boot-starter-aop:2.5.2'
```

## Adding a tracing filter to your application


Add a `Filter` to your `WebConfig` class. Pass the segment name to the [https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html) constructor as a string. For more information about tracing filters and instrumenting incoming requests, see [Tracing incoming requests with the X-Ray SDK for Java](xray-sdk-java-filters.md).

**Example src/main/java/myapp/WebConfig.java - spring**  

```
package myapp;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
import javax.servlet.Filter;
import [com.amazonaws.xray.javax.servlet.AWSXRayServletFilter](https://docs.aws.amazon.com/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html);

@Configuration
public class WebConfig {

  @Bean
  public Filter TracingFilter() {
    return new AWSXRayServletFilter("Scorekeep");
  }
}
```

## Jakarta Support


 Spring 6 uses [Jakarta](https://spring.io/blog/2022/11/16/spring-framework-6-0-goes-ga) instead of Javax for its Enterprise Edition. To support this new namespace, X-Ray has created a parallel set of classes that live in their own Jakarta namespace. 

For the filter classes, replace `javax` with `jakarta`. When configuring a segment naming strategy, add `jakarta` before the naming strategy class name, as in the following example:

```
package myapp;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
import jakarta.servlet.Filter;
import com.amazonaws.xray.jakarta.servlet.AWSXRayServletFilter;
import com.amazonaws.xray.strategy.jakarta.SegmentNamingStrategy;

@Configuration
public class WebConfig {
    @Bean
    public Filter TracingFilter() {
        return new AWSXRayServletFilter(SegmentNamingStrategy.dynamic("Scorekeep"));
    }
}
```

## Annotating your code or implementing an interface


Your classes must either be annotated with the `@XRayEnabled` annotation, or implement the `XRayTraced` interface. This tells the AOP system to wrap the functions of the affected class for X-Ray instrumentation.

## Activating X-Ray in your application


To activate X-Ray tracing in your application, your code must extend the abstract class `BaseAbstractXRayInterceptor` by overriding the following methods.
+ `generateMetadata`—This function allows customization of the metadata attached to the current function’s trace. By default, the class name of the executing function is recorded in the metadata. You can add more data if you need additional information.
+ `xrayEnabledClasses`—This function is empty, and should remain so. It serves as the host for a pointcut instructing the interceptor about which methods to wrap. Define the pointcut by specifying which of the classes that are annotated with `@XRayEnabled` to trace. The following pointcut statement tells the interceptor to wrap all controller beans annotated with the `@XRayEnabled` annotation.

  ```
  @Pointcut(“@within(com.amazonaws.xray.spring.aop.XRayEnabled) && bean(*Controller)”)
  ```

 If your project is using Spring Data JPA, consider extending from `AbstractXRayInterceptor` instead of `BaseAbstractXRayInterceptor`. 

## Example


The following code extends the abstract class `BaseAbstractXRayInterceptor`.

```
@Aspect
@Component
public class XRayInspector extends BaseAbstractXRayInterceptor {    
    @Override    
    protected Map<String, Map<String, Object>> generateMetadata(ProceedingJoinPoint proceedingJoinPoint, Subsegment subsegment) throws Exception {      
        return super.generateMetadata(proceedingJoinPoint, subsegment);    
    }    
  
  @Override    
  @Pointcut("@within(com.amazonaws.xray.spring.aop.XRayEnabled) && bean(*Controller)")    
  public void xrayEnabledClasses() {}
  
}
```

The following code is a class that will be instrumented by X-Ray.

```
@Service
@XRayEnabled
public class MyServiceImpl implements MyService {    
    private final MyEntityRepository myEntityRepository;    
    
    @Autowired    
    public MyServiceImpl(MyEntityRepository myEntityRepository) {        
        this.myEntityRepository = myEntityRepository;    
    }    
    
    @Transactional(readOnly = true)    
    public List<MyEntity> getMyEntities(){        
        try(Stream<MyEntity> entityStream = this.myEntityRepository.streamAll()){            
            return entityStream.sorted().collect(Collectors.toList());        
        }    
    }
}
```

If you've configured your application correctly, you should see the complete call stack of the application, from the controller down through the service calls, as shown in the following screen shot of the console.

![\[Timeline showing API call duration and breakdown of server operations for metering service.\]](http://docs.aws.amazon.com/xray/latest/devguide/images/aop-spring-console.png)
