通过动态检测调试应用程序
借助动态检测,您无需重启或重新部署即可从活动应用程序捕获运行时状态。运行时状态包括变量值、方法参数、返回值和堆栈跟踪。您可以定义检测配置,指定在代码中的哪些位置捕获数据,运行中的代理会在运行时对应用程序进行检测。
概念
- 断点
会自动过期的临时检测。默认过期时间为 24 小时,可配置为 5 分钟到 24 小时。请使用断点进行调试和调查。
- 探针
明确删除之前一直存在的永久检测。使用探针可实现持续可观测性。
- 快照
程序状态的时间点捕获,包括局部变量、参数、返回值、异常和堆栈跟踪。动态检测会将快照作为日志记录发送至 CloudWatch Logs。
- 位置
应用检测的代码位置。不同语言的必填字段有所不同。
支持的语言
Java
Python
JavaScript 或 TypeScript
先决条件
要使用动态检测,请根据部署类型将检测组件更新到最新版本:
-
Amazon EKS 客户:将 Amazon CloudWatch Observability EKS 附加组件更新到最新版本。该附加组件包括 ADOT SDK 和 CloudWatch 代理。有关更多信息,请参阅安装 CloudWatch Observability EKS 附加组件。
-
所有其他客户:更新下面两个组件:
适用于您的语言(Java、Python 或 Node.js)的 Amazon Distro for OpenTelemetry(ADOT)检测 SDK。
将 CloudWatch Agent 更新到最新版本。
还必须满足以下条件:
必须为应用程序启用 CloudWatch Application Signals。
对应用程序设置环境变量
OTEL_AWS_DYNAMIC_INSTRUMENTATION_ENABLED=true。对服务名称设置环境变量
OTEL_SERVICE_NAME。设置
OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=环境变量。对于现有的 Application Signals 用户,该值必须与 Application Signals 控制台中显示的您的服务的环境名称相匹配。my_deployment_env_nameCloudWatch 代理必须使用 Application Signals 配置运行。
Lambda 环境中不支持动态检测。
向应用程序添加动态检测
在对应用程序进行检测后(请参阅先决条件),您可以创建一个检测配置,指定要将动态遥测引入代码的哪个部分。每种配置都定义了两项内容:
代码中要监视的位置:应用断点或探针的代码位置。
要捕获的数据:执行断点或探针时捕获的运行时状态。
注意
默认情况下,动态检测仅捕获有限的数据。要最大限度地发挥此功能的价值,请考虑使用捕获限制中所述的选项扩展捕获配置。
您可以使用 Amazon CLI 或 SDK 来创建配置,也可以在 IDE 中使用带人工智能编码助手的模型上下文协议(MCP)服务器来创建配置。
使用 CLI 或 SDK 创建配置
使用 Amazon CLI 或 Amazon SDK 来以编程方式创建检测配置。
指定代码位置
该位置定义代码中应用检测的位置。不同语言的必填字段有所不同:
| 语言 | 必填字段 | 可选字段 |
|---|---|---|
| Java | CodeUnit(程序包)、ClassName、MethodName、FilePath |
LineNumber |
| Python | CodeUnit(模块)、MethodName、FilePath |
LineNumber, ClassName |
| JavaScript 或 TypeScript | FilePath, LineNumber |
无。仅支持行级断点。不支持探针和函数级断点。当您提供源映射时,将支持 TypeScript。 |
配置要捕获的数据
捕获配置控制着在检测触发时收集哪些运行时状态。可用选项:
CaptureArguments:要捕获的方法参数名称列表。CaptureReturn:捕获返回值(布尔值)。CaptureStackTrace:捕获堆栈跟踪(布尔值)。CaptureLocals:要捕获的局部变量名称列表。CaptureLimits:控制捕获深度和大小(请参阅捕获限制)。
配置参数
创建配置时的关键参数:
instrumentation-type:BREAKPOINT或PROBEservice:Application Signals 报告的服务名称environment:环境名称signal-type—SNAPSHOTlocation:代码位置字段(见上文)capture-configuration:捕获选项(见上文)
示例
以下示例会在 Java 方法上创建断点:
aws application-signals create-instrumentation-configuration \ --instrumentation-type BREAKPOINT \ --service "my-service" \ --environment "production" \ --signal-type SNAPSHOT \ --location '{ "CodeLocation": { "Language": "Java", "CodeUnit": "com.example.service", "ClassName": "OrderController", "MethodName": "processOrder", "FilePath": "OrderController.java" } }' \ --capture-configuration '{ "CodeCapture": { "CaptureArguments": ["orderId", "user"], "CaptureReturn": true, "CaptureStackTrace": true, "CaptureLimits": { "MaxHits": 100, "MaxStringLength": 255, "MaxCollectionWidth": 20, "MaxObjectDepth": 3, "MaxFieldsPerObject": 20, "MaxStackFrames": 20 } } }'
使用 MCP 服务器创建配置
使用动态检测的推荐方法是通过 CloudWatch Application Signals MCP(模型上下文协议)服务器。MCP 使 IDE 中的人工智能编码助手和代理能够直接从开发环境创建、管理和查询动态检测配置。
使用 MCP,人工智能助手可以:
在特定代码位置创建断点和探针,而无需离开编辑器。
查询捕获的快照,以检查运行时变量值和调用路径。
自动将快照数据与正在处理的代码相关联,以提出修复建议。
管理检测配置的生命周期(查看状态,删除过期的断点)。
有关设置和使用说明,请参阅 GitHub 网站上的 Application Signals MCP 服务器
数据存储
当断点或探针触发时,动态检测会在 CloudWatch Logs 中创建一个以 /aws/application-signals/ 为前缀的日志组(其中 service-nameservice-name 是您的 OTEL_SERVICE_NAME 环境变量的值),并将捕获的快照作为日志记录写入该日志组。
如果日志组尚不存在,则动态检测会在首次发出快照时自动创建它。日志摄取和存储费用按标准 CloudWatch Logs 费率收取。
查看和管理配置
在 CloudWatch 控制台中,导航到服务详细信息页面,然后选择检测选项卡。
在断点和探针之间切换,以便按类型查看配置。
查看配置详细信息,包括描述、捕获配置、位置、ARN 和过期时间。
查看状态历史记录以跟踪转换:“就绪”到“活动”到“错误/已禁用”。
删除不再需要的配置。
了解状态
每个检测配置都有一个状态,指示其当前状态。
| Status | 说明 |
|---|---|
| 就绪 | 代理已收到配置。 |
| ACTIVE | 代理已将检测应用于正在运行的应用程序。 |
| ERROR | 未能应用检测。有关详细信息,请参阅错误原因。 |
| DISABLED | 检测已过期,或者您已将其移除。 |
当检测进入 ERROR 状态时,可能会报告如下原因:
| 错误原因 | 说明 |
|---|---|
| FILE_NOT_FOUND | 应用程序中不存在指定的文件路径。 |
| METHOD_NOT_FOUND | 指定的方法在目标类或模块中不存在。 |
| LINE_NOT_EXECUTABLE | 指定的行号与可执行语句不对应。 |
| OVERLOADED_METHODS | 多个方法与指定名称匹配。请提供其他位置详细信息以确定正确的方法。 |
| LANGUAGE_MISMATCH | 位置字段与正在运行的应用程序的语言不匹配。 |
| RUNTIME_ERROR | 应用检测时发生意外错误。 |
捕获限制
捕获限制控制着所捕获数据的大小和深度。请在捕获配置的 capture-limits 字段中配置这些值。
| 限制 | 默认 | Range | 说明 |
|---|---|---|---|
| maxStringLength | 255 | 1–255 | 每个字符串值捕获的最大字符数。 |
| maxCollectionWidth | 20 | 1–20 | 每个集合或数组捕获的最大元素数量。 |
| maxObjectDepth | 3 | 1–5 | 嵌套对象遍历的最大深度。 |
| maxFieldsPerObject | 20 | 1–20 | 每个对象捕获的最大字段数。 |
| maxStackFrames | 20 | 1–20 | 捕获的最大堆栈帧数。 |
| maxHits | 100 | 1–1000 | 自动禁用前的最大捕获次数。仅限断点。 |
每个检测点的速率限制为每秒 5 次捕获。