

# 通过动态检测调试应用程序
<a name="CloudWatch-Application-Signals-DynamicInstrumentation"></a>

借助动态检测，您无需重启或重新部署即可从活动应用程序捕获运行时状态。运行时状态包括变量值、方法参数、返回值和堆栈跟踪。您可以定义检测配置，指定在代码中的哪些位置捕获数据，运行中的代理会在运行时对应用程序进行检测。

## 概念
<a name="Application-Signals-DI-Concepts"></a>

断点  
会自动过期的临时检测。默认过期时间为 24 小时，可配置为 5 分钟到 24 小时。请使用断点进行调试和调查。

探针  
明确删除之前一直存在的永久检测。使用探针可实现持续可观测性。

快照  
程序状态的时间点捕获，包括局部变量、参数、返回值、异常和堆栈跟踪。动态检测会将快照作为日志记录发送至 CloudWatch Logs。

位置  
应用检测的代码位置。不同语言的必填字段有所不同。

## 支持的语言
<a name="Application-Signals-DI-Languages"></a>
+ Java
+ Python
+ JavaScript 或 TypeScript

## 先决条件
<a name="Application-Signals-DI-Prerequisites"></a>

要使用动态检测，请根据部署类型将检测组件更新到最新版本：
+ **Amazon EKS 客户**：将 Amazon CloudWatch Observability EKS 附加组件更新到最新版本。该附加组件包括 ADOT SDK 和 CloudWatch 代理。有关更多信息，请参阅[安装 CloudWatch Observability EKS 附加组件](https://docs.amazonaws.cn/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Observability-EKS-addon.html)。
+ **所有其他客户**：更新下面两个组件：
  + 适用于您的语言（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={{my_deployment_env_name}}` 环境变量。对于现有的 Application Signals 用户，该值必须与 Application Signals 控制台中显示的您的服务的环境名称相匹配。
+ CloudWatch 代理必须使用 Application Signals 配置运行。
+ Lambda 环境中不支持动态检测。

## 向应用程序添加动态检测
<a name="Application-Signals-DI-Add"></a>

在对应用程序进行检测后（请参阅[先决条件](#Application-Signals-DI-Prerequisites)），您可以创建一个检测*配置*，指定要将动态遥测引入代码的哪个部分。每种配置都定义了两项内容：

1. **代码中要监视的位置**：应用断点或探针的代码位置。

1. **要捕获的数据**：执行断点或探针时捕获的运行时状态。

**注意**  
默认情况下，动态检测仅捕获有限的数据。要最大限度地发挥此功能的价值，请考虑使用[捕获限制](#Application-Signals-DI-Limits)中所述的选项扩展捕获配置。

您可以使用 Amazon CLI 或 SDK 来创建配置，也可以在 IDE 中使用带人工智能编码助手的模型上下文协议（MCP）服务器来创建配置。

### 使用 CLI 或 SDK 创建配置
<a name="Application-Signals-DI-Create"></a>

使用 Amazon CLI 或 Amazon SDK 来以编程方式创建检测配置。

#### 指定代码位置
<a name="Application-Signals-DI-Create-Location"></a>

该位置定义代码中应用检测的位置。不同语言的必填字段有所不同：


| 语言 | 必填字段 | 可选字段 | 
| --- | --- | --- | 
| Java | CodeUnit（程序包）、ClassName、MethodName、FilePath | LineNumber | 
| Python | CodeUnit（模块）、MethodName、FilePath | LineNumber, ClassName | 
| JavaScript 或 TypeScript | FilePath, LineNumber | 无。仅支持行级断点。不支持探针和函数级断点。当您提供源映射时，将支持 TypeScript。 | 

#### 配置要捕获的数据
<a name="Application-Signals-DI-Create-Capture"></a>

捕获配置控制着在检测触发时收集哪些运行时状态。可用选项：
+ `CaptureArguments`：要捕获的方法参数名称列表。
+ `CaptureReturn`：捕获返回值（布尔值）。
+ `CaptureStackTrace`：捕获堆栈跟踪（布尔值）。
+ `CaptureLocals`：要捕获的局部变量名称列表。
+ `CaptureLimits`：控制捕获深度和大小（请参阅[捕获限制](#Application-Signals-DI-Limits)）。

#### 配置参数
<a name="Application-Signals-DI-Create-Params"></a>

创建配置时的关键参数：
+ `instrumentation-type`：`BREAKPOINT` 或 `PROBE`
+ `service`：Application Signals 报告的服务名称
+ `environment`：环境名称
+ `signal-type` — `SNAPSHOT`
+ `location`：代码位置字段（见上文）
+ `capture-configuration`：捕获选项（见上文）

#### 示例
<a name="Application-Signals-DI-Create-Example"></a>

以下示例会在 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 服务器创建配置
<a name="Application-Signals-DI-MCP"></a>

使用动态检测的推荐方法是通过 CloudWatch Application Signals MCP（模型上下文协议）服务器。MCP 使 IDE 中的人工智能编码助手和代理能够直接从开发环境创建、管理和查询动态检测配置。

使用 MCP，人工智能助手可以：
+ 在特定代码位置创建断点和探针，而无需离开编辑器。
+ 查询捕获的快照，以检查运行时变量值和调用路径。
+ 自动将快照数据与正在处理的代码相关联，以提出修复建议。
+ 管理检测配置的生命周期（查看状态，删除过期的断点）。

有关设置和使用说明，请参阅 GitHub 网站上的 [Application Signals MCP 服务器](https://awslabs.github.io/mcp/servers/cloudwatch-applicationsignals-mcp-server)。

## 数据存储
<a name="Application-Signals-DI-DataStorage"></a>

当断点或探针触发时，动态检测会在 CloudWatch Logs 中创建一个以 `/aws/application-signals/{{service-name}}` 为前缀的日志组（其中 {{service-name}} 是您的 `OTEL_SERVICE_NAME` 环境变量的值），并将捕获的快照作为日志记录写入该日志组。

如果日志组尚不存在，则动态检测会在首次发出快照时自动创建它。日志摄取和存储费用按标准 CloudWatch Logs 费率收取。

## 查看和管理配置
<a name="Application-Signals-DI-Manage"></a>

在 CloudWatch 控制台中，导航到服务详细信息页面，然后选择**检测**选项卡。
+ 在**断点**和**探针**之间切换，以便按类型查看配置。
+ 查看配置详细信息，包括描述、捕获配置、位置、ARN 和过期时间。
+ 查看状态历史记录以跟踪转换：“就绪”到“活动”到“错误/已禁用”。
+ 删除不再需要的配置。

## 了解状态
<a name="Application-Signals-DI-Status"></a>

每个检测配置都有一个状态，指示其当前状态。


| Status | 说明 | 
| --- | --- | 
| 就绪 | 代理已收到配置。 | 
| ACTIVE | 代理已将检测应用于正在运行的应用程序。 | 
| ERROR | 未能应用检测。有关详细信息，请参阅错误原因。 | 
| DISABLED | 检测已过期，或者您已将其移除。 | 

当检测进入 ERROR 状态时，可能会报告如下原因：


| 错误原因 | 说明 | 
| --- | --- | 
| FILE\_NOT\_FOUND | 应用程序中不存在指定的文件路径。 | 
| METHOD\_NOT\_FOUND | 指定的方法在目标类或模块中不存在。 | 
| LINE\_NOT\_EXECUTABLE | 指定的行号与可执行语句不对应。 | 
| OVERLOADED\_METHODS | 多个方法与指定名称匹配。请提供其他位置详细信息以确定正确的方法。 | 
| LANGUAGE\_MISMATCH | 位置字段与正在运行的应用程序的语言不匹配。 | 
| RUNTIME\_ERROR | 应用检测时发生意外错误。 | 

## 捕获限制
<a name="Application-Signals-DI-Limits"></a>

捕获限制控制着所捕获数据的大小和深度。请在捕获配置的 `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 次捕获。