本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
配置 Java 的 X-Ray 开发工具包
适用于 Java 的 X-Ray SDK 包含一个名为的类AWSXRay
,用于提供全局记录器。你可以用TracingHandler
它来分析你的代码。您可以配置全局记录器以自定义为传入 HTTP 调用创建分段的 AWSXRayServletFilter
。
服务插件
plugins
用于记录有关托管您的应用程序的服务的信息。
插件
Amazon EC2 —
EC2Plugin
添加实例 ID、可用区和 CloudWatch 日志组。Elastic Beanstalk —
ElasticBeanstalkPlugin
添加环境名称、版本标签和部署 ID。亚马逊 ECS —
ECSPlugin
添加容器 ID。Amazon EKS —
EKSPlugin
添加容器 ID、集群名称、容器 ID 和 CloudWatch 日志组。

要使用插件,请在 AWSXRayRecorderBuilder
上调用 withPlugin
。
例 src/main/java/scorekeep/WebConfig .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());
URL ruleFile = WebConfig.class.getResource("/sampling-rules.json");
builder.withSamplingStrategy(new LocalizedSamplingStrategy(ruleFile));
AWSXRay.setGlobalRecorder(builder.build());
}
}
SDK 还使用插件设置来设置区段上的origin
字段。这表示运行您的应用程序的Amazon资源类型。当您使用多个插件时,SDK 使用以下解析顺序来确定来源: ElasticBeanstalk > EKS > ECS > EC2。
采样规则
SDK 使用您在 X-Ray 控制台中定义的采样规则来确定要记录哪些请求。默认规则每秒跟踪第一个请求,以及向 X-Ray 发送跟踪的所有服务中任何额外请求的百分之五。在 X-Ray 控制台中创建其他规则,自定义每个应用程序记录的数据量。
SDK 将按其定义的应用自定义规则的应用自定义规则。如果请求匹配多个自定义规则,则 SDK 仅应用第一条规则。
注意
如果 SDK 无法访问 X-Ray 获取采样规则,它将恢复为每秒第一个请求的默认本地规则,以及每台主机任何额外请求的百分之五。如果主机没有权限调用采样 API,或者无法连接到 X-Ray 守护程序,后者充当 SDK 发出的 API 调用的 TCP 代理,就会发生这种情况。
您也可以将 SDK 配置为从 JSON 文档加载采样规则。在无法使用 X-Ray 采样的情况下,SDK 可以使用本地规则作为备份,也可以仅使用本地规则。
例 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/
。默认规则是每秒 1 个请求和 5% 的其他请求。
在本地定义规则的缺点是,固定目标由记录器的每个实例独立应用,而不是由 X-Ray 服务管理。随着部署更多主机,固定速率会成倍增加,这使得控制记录的数据量变得更加困难。
启Amazon Lambda用,您无法修改采样率。如果您的函数由仪器化服务调用,则生成由该服务采样的请求的调用将由 Lambda 记录。如果启用了主动跟踪且不存在跟踪标头,则 Lambda 会做出采样决定。
要在 Spring 中提供备份规则,请使用配置类中的 CentralizedSamplingStrategy
配置全局记录器。
例 src/main/java/myapp/WebConfig .java-录像机配置
import com.amazonaws.xray.AWSXRay;
import com.amazonaws.xray.AWSXRayRecorderBuilder;
import com.amazonaws.xray.javax.servlet.AWSXRayServletFilter;
import com.amazonaws.xray.plugins.EC2Plugin;
import com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy;
@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
的侦听器,并在部署描述符中注册该侦听器。
例 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.strategy.sampling.LocalizedSamplingStrategy;
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) { }
}
例 WEB-INF/web.xml
...
<listener>
<listener-class>com.myapp.web.Startup</listener-class>
</listener>
要仅使用本地规则,请将CentralizedSamplingStrategy
替换为 aLocalizedSamplingStrategy
。
builder.withSamplingStrategy(new
LocalizedSamplingStrategy
(ruleFile));
日志记录
默认情况下,SDK 将ERROR
级别消息输出到您的应用程序日志。您可以在 SDK 上启用调试级日志记录,将更详细的日志输出到应用程序日志文件中。有效的日志级别为DEBUG
INFO
、WARN
、ERROR
、和FATAL
。 FATAL
日志级别会使所有日志消息静音,因为 SDK 不会记录严重级别。
例 application.properties
使用 logging.level.com.amazonaws.xray
属性设置日志记录级别。
logging.level.com.amazonaws.xray = DEBUG
当您手动生成子分段时,使用调试日志来识别诸如未结束子分段之类的问题。
将跟踪 ID 注入日志
要将当前完全限定的跟踪 ID 公开到日志语句,您可以将此 ID 注入到映射的诊断上下文 (MDC)。使用该SegmentListener
接口,在分段生命周期事件期间从 X-Ray ecorder 调用方法。当分段或子分段开始时,使用密钥 AWS-XRAY-TRACE-ID
将限定的跟踪 ID 注入到 MDC 中。当该分段结束时,该密钥将从 MDC 中删除。这会将跟踪 ID 暴露给正在使用的日志库。当子分段结束时,其父级 ID 将注入到 MDC 中。
例 完全限定的跟踪 ID
完全限定的 ID 表示为 TraceID@EntityID
1-5df42873-011e96598b447dfca814c156@541b3365be3dafc3
此功能适用于使用适用于 Java 的Amazon X-Ray SDK for Java 应用程序,并支持以下日志配置:
-
带日志回传后端的 SLF4J 前端 API
-
带有 Log4J2 后端的 SLF4J 前端 API
-
带有 Log4J2 后端的 Log4J2 前端 API
有关每个前端和每个后端的需求,请参阅以下选项卡。
追踪 ID 注入示例
以下显示了修改为包含跟踪 ID 的PatternLayout
字符串。跟踪 ID 在线程名称 (%t
) 之后和日志级别 (%-5p
) 之前输出。
例 PatternLayout
使用身份证注入
%d{HH:mm:ss.SSS} [%t]
%X{AWS-XRAY-TRACE-ID}
%-5p %m%n
Amazon X-Ray 自动在日志语句中输出密钥和跟踪 ID 以便于解析。下面显示了使用已修改的 PatternLayout
的日志语句。
例 带有 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
生成的分段的开始和结束)的接口。分段侦听器事件函数的实现可能是在使用 onBeginSubsegment
创建所有子分段时向所有子分段添加相同的注释,使用 afterEndSegment
将每个分段发送到守护程序后记录一条消息,或者使用 beforeEndSubsegment
记录由 SQL 拦截程序发送的查询,以验证子分段是否代表 SQL 查询,如果是,则添加其他元数据。
要查看完整的SegmentListener
函数列表,请访问适用于 Java 的Amazon X-Ray Recorder SDK API 的文档。
以下示例说明如何在使用 onBeginSubsegment
创建所有子分段时向所有子分段添加一致的注释,以及如何使用 afterEndSegment
在每个分段末尾打印日志消息。
例 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
时引用此自定义分段侦听器。
例 AWSXRayRecorderBuilder 声明
AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder
.standard().withSegmentListener(new MySegmentListener()
);
环境变量
您可以使用环境变量来配置适用于 Java 的 X-Ray 开发工具包。开发工具包支持以下变量。
-
AWS_XRAY_TRACING_NAME
— 设置 SDK 用于分段的服务名称。覆盖您根据 servlet 筛选器的分段命名策略设置的服务名称。 AWS_XRAY_DAEMON_ADDRESS
— 设置 X-Ray 守护程序侦听器的主机和端口。默认情况下,SDK 同时使用127.0.0.1:2000
跟踪数据 (UDP) 和采样 (TCP)。如果您已将守护程序配置为监听其他端口,或者它在其他主机上运行,请使用此变量。格式
-
同一个端口 —
address
:port
-
不同的端口 —
tcp:
address
:port
udp:address
:port
-
AWS_XRAY_CONTEXT_MISSING
— 设置为RUNTIME_ERROR
,当您的仪器化代码在未打开任何区段时尝试记录数据时抛出异常。有效值
-
RUNTIME_ERROR
— 抛出运行时异常。 -
LOG_ERROR
— 记录错误并继续(默认)。 -
IGNORE_ERROR
— 忽略错误并继续。
当您尝试在未打开请求时运行的启动代码中或在生成新线程的代码中使用仪器化客户端时,可能会发生与缺失分段或子分段相关的错误。
-
环境变量覆盖在代码中设置的等效系统属性和值。
系统属性
您可以将系统属性用作环境变量的 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
。
如果同时设置了系统属性和等效的环境变量,则使用环境变量值。每种方法都会覆盖在代码中设置的值。