

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

# 使用 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 开发工具包创建的分段或您创建的自定义子分段。

**注释**是带字符串、数字或布尔值的键值对。系统会对注释编制索引，以便与[筛选表达式](xray-console-filters.md)一起使用。使用注释记录要用于对控制台中的跟踪进行分组的数据或在调用 [https://docs.amazonaws.cn/xray/latest/api/API_GetTraceSummaries.html](https://docs.amazonaws.cn/xray/latest/api/API_GetTraceSummaries.html) API 时使用的数据。

**元数据**是可以具有任何类型值的键-值对，包括对象和列表，但没有编制索引，无法与筛选条件表达式一起使用。使用元数据记录要存储在跟踪中但不需要用于搜索跟踪的其他数据。

除了注释和元数据之外，您还可以在分段上[记录用户 ID 字符串](#xray-sdk-java-segment-userid)。用户 IDs 被记录在区段的单独字段中，并编制索引以供搜索使用。

**Topics**
+ [

## 使用 X-Ray SDK for Java 记录注释
](#xray-sdk-java-segment-annotations)
+ [

## 使用 X-Ray SDK for Java 记录元数据
](#xray-sdk-java-segment-metadata)
+ [

## 使用适用于 Java IDs 的 X-Ray SDK 录制用户
](#xray-sdk-java-segment-userid)

## 使用 X-Ray SDK for Java 记录注释


使用注释记录有关要为其编制索引以进行搜索的分段和子分段的信息。

**注释要求**
+ **键** - X-Ray 注释的键最多可以包含 500 个字母数字字符。除了点或句点（.）之外，不能使用空格或符号
+ **值** - X-Ray 注释的值最多可以包含 1,000 个 Unicode 字符。
+ **注释**的数量 - 每个跟踪最多可使用 50 条注释。

**记录注释**

1. 从 `AWSXRay` 获取对当前分段或子分段的引用。

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

   或者

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

1. 调用带有字符串键和布尔值、数字值或字符串值的 `putAnnotation`。

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

   以下示例说明如何使用包含点和布尔值、数字值或字符串值的字符串键调用 `putAnnotation`。

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

开发工具包将注释以键-值对的形式记录在分段文档的 `annotations` 对象中。使用相同键调用两次 `putAnnotation` 将覆盖同一分段或子分段上之前记录的值。

要查找具有带特定值的注释的跟踪，请在`annotation[key]`筛选表达式[中使用 ](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) - 注释和元数据**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
import [com.amazonaws.xray.entities.Segment](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Segment.html);
import [com.amazonaws.xray.entities.Subsegment](https://docs.amazonaws.cn/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();
    }
  }
```

## 使用 X-Ray SDK for Java 记录元数据


使用元数据记录有关您无需为其编制索引以进行搜索的分段或子分段的信息。元数据值可以是字符串、数字、布尔值或可序列化为 JSON 对象或数组的任何对象。

**记录元数据**

1. 从 `AWSXRay` 获取对当前分段或子分段的引用。

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

   或者

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

1. 调用带有字符串命名空间、字符串键和布尔值、数字值、字符串值或对象值的 `putMetadata`。

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

   或者

   调用仅带有键和值的 `putMetadata`。

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

如果您没有指定命名空间，则开发工具包将使用 `default`。使用相同键调用两次 `putMetadata` 将覆盖同一分段或子分段上之前记录的值。

**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) - 注释和元数据**  

```
import [com.amazonaws.xray.AWSXRay](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/AWSXRay.html);
import [com.amazonaws.xray.entities.Segment](https://docs.amazonaws.cn/xray-sdk-for-java/latest/javadoc/com/amazonaws/xray/entities/Segment.html);
import [com.amazonaws.xray.entities.Subsegment](https://docs.amazonaws.cn/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();
    }
  }
```

## 使用适用于 Java IDs 的 X-Ray SDK 录制用户


记录请求细分中的用户，以识别发送请求的用户。 IDs 

**要记录用户 IDs**

1. 从 `AWSXRay` 获取对当前分段的引用。

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

1. 使用发送请求的用户的字符串 ID 调用 `setUser`。

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

您可以在控制器中调用 `setUser` 以便在应用程序开始处理请求后立即记录用户 ID。如果您只打算使用分段来设置用户 ID，可以在单个行中链接这些调用。

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

```
import [com.amazonaws.xray.AWSXRay](https://docs.amazonaws.cn/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);
  }
```

要查找用户 ID 的跟踪，请在`user`筛选表达式[中使用 ](xray-console-filters.md) 关键字。