

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 配置 X-Ray SDK for Java
配置

**注意**  
X-Ray SDK/Daemon 维护通知 — 2026 年 2 月 25 日， Amazon X-Ray SDKs/Daemon 将进入维护模式，在该模式下，X-Ray SDK 和 Daemon 的发布 Amazon 将仅限于解决安全问题。有关支持时间表的更多信息，请参阅 [X-Ray SDK 和 Daemon Support 时间表](xray-sdk-daemon-timeline.md)。我们建议迁移到 OpenTelemetry。有关迁移到的更多信息 OpenTelemetry，请参阅[从 X-Ray 仪器迁移到 OpenTelemetry 仪器](https://docs.amazonaws.cn/xray/latest/devguide/xray-sdk-migration.html)。

X-Ray SDK for Java 包括提供全局记录器的、名为 `AWSXRay` 的类。这是可用于检测代码的 `TracingHandler`。您可以配置全局记录器以自定义为传入 HTTP 调用创建分段的 `AWSXRayServletFilter`。

**Topics**
+ [

## 服务插件
](#xray-sdk-java-configuration-plugins)
+ [

## 采样规则
](#xray-sdk-java-configuration-sampling)
+ [

## 日志记录
](#xray-sdk-java-configuration-logging)
+ [

## 分段侦听器
](#xray-sdk-java-configuration-listeners)
+ [

## 环境变量
](#xray-sdk-java-configuration-envvars)
+ [

## 系统属性
](#xray-sdk-java-configuration-sysprops)

## 服务插件


`plugins` 用于记录有关托管应用程序的服务的信息。

**插件**
+ Amazon EC2 — `EC2Plugin` 添加实例 ID、可用区和 CloudWatch 日志组。
+ Elastic Beanstalk - `ElasticBeanstalkPlugin` 添加环境名称、版本标签和部署 ID。
+ Amazon ECS — `ECSPlugin` 添加容器 ID。
+ Amazon EKS — `EKSPlugin` 添加容器 ID、集群名称、容器 ID 和 CloudWatch 日志组。

![\[使用 Amazon EC2 和 Elastic Beanstalk 插件对资源数据进行分段。\]](http://docs.amazonaws.cn/xray/latest/devguide/images/scorekeep-PUTrules-segment-resources.png)


要使用插件，请在 `AWSXRayRecorderBuilder` 上调用 `withPlugin`。

**Example src/main/java/scorekeep/WebConfig.java-录音机**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
import [com.amazonaws.xray.AWSXRayRecorderBuilder](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRayRecorderBuilder.html);
import [com.amazonaws.xray.plugins.EC2Plugin](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/plugins/EC2Plugin.html);
import [com.amazonaws.xray.plugins.ElasticBeanstalkPlugin](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/plugins/ElasticBeanstalkPlugin.html);
import [com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy](https://docs.amazonaws.cn/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());
  }
}
```

该 SDK 还使用插件设置为设置分段上的 `origin` 字段。这表示运行您的应用程序的 Amazon 资源类型。当您使用多个插件时，软件开发工具包使用以下解析顺序来确定来源： ElasticBeanstalk > EKS > ECS > EC2。

## 采样规则


该 SDK 使用您在 X-Ray 控制台中定义的采样规则来确定要记录的请求。默认规则跟踪每秒的第一个请求，以及所有将跟踪发送到 X-Ray 的服务的任何其他请求的百分之五。[在 X-Ray 控制台中创建其他规则](xray-console-sampling.md)以自定义为每个应用程序记录的数据量。

该 SDK 按照定义的顺序应用自定义规则。如果请求与多个自定义规则匹配，则 SDK 仅应用第一条规则。

**注意**  
如果 SDK 无法访问 X-Ray 来获取采样规则，它将恢复为默认的本地规则，即每秒第一个请求以及每个主机所有其他请求的百分之五。如果主机无权调用采样，或者无法连接到 X-Ray 守护程序 APIs，后者充当 SDK 发出的 API 调用的 TCP 代理，则可能会发生这种情况。

您还可以将 SDK 配置为从 JSON 文档加载采样规则。在 X-Ray 采样不可用的情况下，SDK 可以使用本地规则作为备份，也可以只使用本地规则。

**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
  }
}
```

此示例定义了一个自定义规则和一个默认规则。自定义规则采用百分之五的采样率，对于 `/api/move/` 之下的路径要跟踪的请求数量不设下限。默认规则中每秒的第一个请求以及其他请求的百分之十。

在本地定义规则的缺点是，固定目标由记录器的每个实例独立应用而不是由 X-Ray 服务管理。随着您部署更多主机，固定速率会成倍增加，这使得控制记录的数据量变得更加困难。

开启后 Amazon Lambda，您无法修改采样率。如果您的函数由检测服务调用，Lambda 将记录生成由该服务采样的请求的调用。如果启用了活动跟踪且不存在任何跟踪标头，则 Lambda 会做出采样决定。

要在 Spring 中提供备份规则，请使用配置类中的 `CentralizedSamplingStrategy` 配置全局记录器。

**Example src/main/java/myapp/WebConfig.java-录制器配置**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
import [com.amazonaws.xray.AWSXRayRecorderBuilder](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRayRecorderBuilder.html);
import [com.amazonaws.xray.javax.servlet.AWSXRayServletFilter](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/javax/servlet/AWSXRayServletFilter.html);
import [com.amazonaws.xray.plugins.EC2Plugin](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/plugins/EC2Plugin.html);
import [com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy](https://docs.amazonaws.cn/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());
}
```

对于 Tomcat，添加一个扩展 `ServletContextListener` 的侦听器，并在部署描述符中注册该侦听器。

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

```
import [com.amazonaws.xray.AWSXRay](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
import [com.amazonaws.xray.AWSXRayRecorderBuilder](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRayRecorderBuilder.html);
import [com.amazonaws.xray.plugins.EC2Plugin](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/plugins/EC2Plugin.html);
import [com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy](https://docs.amazonaws.cn/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>
```

若要仅使用本地规则，请将 `CentralizedSamplingStrategy` 替换为 `LocalizedSamplingStrategy`。

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

## 日志记录


默认情况下，SDK 会将 `ERROR` 级消息输出到应用程序日志。可以在 SDK 上启用调试级别日志记录，将更详细的日志输出到应用程序日志文件。有效的日志级别为 `DEBUG`、`INFO`、`WARN`、`ERROR` 和 `FATAL`。`FATAL` 日志级别会静默所有日志消息，因为 SDK 不会在严重级别记录日志。

**Example application.properties**  
使用 `logging.level.com.amazonaws.xray` 属性设置日志记录级别。  

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

当您手动[生成子分段](xray-sdk-java-subsegments.md)时，使用调试日志来识别诸如未结束子分段之类的问题。

### 跟踪 ID 注入到日志


要将当前完全限定的跟踪 ID 公开到日志语句，您可以将此 ID 注入到映射的诊断上下文 (MDC)。在分段生命周期事件过程中使用 `SegmentListener` 接口从 X-Ray 记录器调用方法。当分段或子分段开始时，使用密钥 `AWS-XRAY-TRACE-ID` 将限定的跟踪 ID 注入到 MDC 中。当该分段结束后，从 MDC 中删除密钥。这会向正在使用的日志库公开跟踪 ID。当子分段结束时，其父级 ID 将注入到 MDC 中。

**Example 完全限定的跟踪 ID**  
完全限定的 ID 表示为 `TraceID@EntityID`  

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

此功能适用于使用适用于 Java 的 Amazon X-Ray SDK 进行检测的 Java 应用程序，并支持以下日志配置：
+ SLF4带有 Logback 后端的 J 前端 API
+ SLF4带有 Log4J2 后端的 J 前端 API
+ 带有 Log4J2 后端的 Log4J2 前端 API

请查看以下选项卡，了解每个前端和每个后端的需求。

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

1. 将以下 Maven 依赖项添加到您的项目中。

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

1. 构建 `AWSXRayRecorder` 时包含 `withSegmentListener` 方法。这会添加一个`SegmentListener`类，该类会自动向 SLF4 J MDC 注 IDs 入新的轨迹。

   `SegmentListener` 采用可选字符串作为参数来配置日志语句前缀。可以通过以下方式配置前缀：
   + **无** - 使用默认 `AWS-XRAY-TRACE-ID` 前缀。
   + **空** 使用空字符串（例如 `""`）。
   + **自定义** - 使用在字符串中定义的自定义前缀。  
**Example `AWSXRayRecorderBuilder` statement**  

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

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

1. 将以下 Maven 依赖项添加到您的项目中。

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

1. 构建 `AWSXRayRecorder` 时包含 `withSegmentListener` 方法。这将添加一个`SegmentListener`类，该类会自动向 SLF4 J MDC 注 IDs 入新的完全限定轨迹。

   `SegmentListener` 采用可选字符串作为参数来配置日志语句前缀。可以通过以下方式配置前缀：
   + **无** - 使用默认 `AWS-XRAY-TRACE-ID` 前缀。
   + **空** - 使用空字符串（例如 `""`）并删除前缀。
   + **自定义** - 使用在字符串中定义的自定义前缀。  
**Example `AWSXRayRecorderBuilder` statement**  

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

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

要将跟踪 ID 插入到日志事件中，您必须修改记录器的 `PatternLayout`，它设置每个日志记录语句的格式。

1. 查找在哪里配置的 `patternLayout`。您可以通过编程方式或通过 XML 配置文件执行此操作。要了解更多信息，请参阅 [Logback 配置](http://logback.qos.ch/manual/configuration.html)。

1. 在 `patternLayout` 中的任意位置插入 `%X{}`，将跟踪 ID 插入到未来的日志记录语句中。`%X{AWS-XRAY-TRACE-ID}` 指示您正在检索的值包含由 MDC 提供的密钥。要 PatternLayouts 在 Logback 中了解更多信息，请参阅[PatternLayout](https://logback.qos.ch/manual/layouts.html#ClassicPatternLayout)。

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

1. 查找在哪里配置的 `patternLayout`。您可以通过编程方式执行此操作，也可以通过以 XML、JSON、YAML 或属性格式编写的配置文件来执行此操作。

   如需详细了解如何通过配置文件配置 Log4J2，请参阅[配置](https://logging.apache.org/log4j/2.x/manual/configuration.html)。

   如需详细了解如何以编程方式配置 Log4J2，请参阅[编程式配置](https://logging.apache.org/log4j/2.x/manual/customconfig.html)。

1. 在 `PatternLayout` 中的任意位置插入 `%X{}`，将跟踪 ID 插入到未来的日志记录语句中。`%X{AWS-XRAY-TRACE-ID}` 指示您正在检索的值包含由 MDC 提供的密钥。[要了解有关 Log4J2 PatternLayouts 的更多信息，请参阅模式布局。](https://logging.apache.org/log4j/2.x/manual/layouts.html#Pattern_Layout)

------

**跟踪 ID 注入示例**  
以下显示了一个经过修改包含跟踪 ID 的 `PatternLayout` 字符串。跟踪 ID 在线程名称 (`%t`) 之后和日志级别 (`%-5p`) 之前输出。

**Example `PatternLayout`（带 ID 注入）**  

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

Amazon X-Ray 自动在日志语句中打印密钥和跟踪 ID，便于解析。下面显示了使用已修改的 `PatternLayout` 的日志语句。

**Example 带 ID 注入的日志语句**  

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

 日志记录消息本身保存在模式 `%m` 中，并在调用记录器时设置。

## 分段侦听器


分段侦听器是一个用于拦截生命周期事件（例如，由 `AWSXRayRecorder` 生成的分段的开始和结束）的接口。分段侦听器事件函数的实现方式可能包括：在使用 [https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#onBeginSubsegment-com.amazonaws.xray.entities.Subsegment-](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#onBeginSubsegment-com.amazonaws.xray.entities.Subsegment-) 创建所有子分段时，为它们添加相同的注释；使用 [https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#afterEndSegment-com.amazonaws.xray.entities.Segment-](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#afterEndSegment-com.amazonaws.xray.entities.Segment-) 在将每个分段发送到进程守护程序后记录一条消息；或者使用 [https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#beforeEndSubsegment-com.amazonaws.xray.entities.Subsegment-](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#beforeEndSubsegment-com.amazonaws.xray.entities.Subsegment-) 记录由 SQL 拦截程序发送的查询，以验证子分段是否代表 SQL 查询，如果是，则添加其他元数据。

要查看 `SegmentListener` 函数的完整列表，请访问 [Amazon X-Ray Recorder SDK for Java API](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html) 相关文档。

以下示例说明如何在使用 [https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#onBeginSubsegment-com.amazonaws.xray.entities.Subsegment-](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#onBeginSubsegment-com.amazonaws.xray.entities.Subsegment-) 创建所有子分段时向所有子分段添加一致的注释，以及如何使用 [https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/listeners/SegmentListener.html#afterEndSegment-com.amazonaws.xray.entities.Segment-](https://docs.amazonaws.cn/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());
    }
}
```

然后，在构建 `AWSXRayRecorder` 时引用此自定义分段侦听器。

**Example AWSXRayRecorderBuilder 声明**  

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

## 环境变量


您可以使用环境变量来配置 X-Ray SDK for Java。SDK 支持以下变量。
+ `AWS_XRAY_CONTEXT_MISSING` - 设置为 `RUNTIME_ERROR` 在您的已检测代码尝试在分段未打开的情况下记录数据时引发异常。

**有效值**
  + `RUNTIME_ERROR`— 引发运行时异常。
  + `LOG_ERROR`— 记录错误并继续（默认）。
  + `IGNORE_ERROR`— 忽略错误并继续。

  对于在未打开任何请求时运行的启动代码或者会生成新线程的代码，如果您尝试在其中使用检测过的客户端，则可能发生与缺失分段或子分段相关的错误。
+ `AWS_XRAY_DAEMON_ADDRESS` - 设置 X-Ray 进程守护程序侦听器的主机和端口。默认情况下，SDK 使用用于跟踪数据（UDP）和采样（TCP）的 `127.0.0.1:2000`。如果您已将进程守护程序配置为[侦听不同端口](xray-daemon-configuration.md)或者进程守护程序在另一台主机上运行，则使用此变量。

**Format**
  + **同一个端口** — `address:port`
  + **不同的端口** — `tcp:address:port udp:address:port`
+ `AWS_LOG_GROUP` - 将日志组的名称设置为与您的应用程序关联的日志组。如果您的日志组使用与您的应用程序相同的 Amazon 账户和区域，X-Ray 将使用此指定的日志组自动搜索应用程序的区段数据。有关日志组的更多信息，请参阅[使用日志组和日志流](https://docs.amazonaws.cn/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html)。
+ `AWS_XRAY_TRACING_NAME` - 设置 SDK 用于进行分段的服务名称。覆盖您根据 servlet 筛选器的[分段命名策略](xray-sdk-java-filters.md#xray-sdk-java-filters-naming)设置的服务名称。

环境变量覆盖在代码中设置的等效[系统属性](#xray-sdk-java-configuration-sysprops)和值。

## 系统属性


您可以将系统属性用作[环境变量](#xray-sdk-java-configuration-envvars)的 JVM 特定替代项。SDK 支持以下属性：
+ `com.amazonaws.xray.strategy.tracingName` - 等效于 `AWS_XRAY_TRACING_NAME`。
+ `com.amazonaws.xray.emitters.daemonAddress` - 等效于 `AWS_XRAY_DAEMON_ADDRESS`。
+ `com.amazonaws.xray.strategy.contextMissingStrategy` - 等效于 `AWS_XRAY_CONTEXT_MISSING`。

如果同时设置系统属性和等效的环境变量，则使用环境变量值。每种方法都会覆盖在代码中设置的值。