

# 启用 JavaScript 错误堆栈跟踪的取消压缩功能
<a name="CloudWatch-RUM-JavaScriptStackTraceSourceMaps"></a>

当您的 Web 应用程序 JavaScript 源代码压缩后，错误堆栈跟踪可能很难读取。您可以将源映射上传到 Amazon S3，以启用堆栈跟踪的取消压缩功能。CloudWatch RUM 会检索源映射，将压缩后的源代码中的行号和列号映射回未压缩的原始源代码。这将提高错误堆栈跟踪的可读性，并有助于确定原始源代码中的错误位置。

## 要求和语法
<a name="CloudWatch-RUM-RequirementsJavaScriptStackTraceSourceMaps"></a>

源映射对于调试和跟踪不同版本的 Web 应用程序中的问题至关重要。确保每个 Web 应用程序版本都有唯一的源映射。每个版本都应有自己唯一的 releaseId。releaseId 必须是长度在 1 到 200 个字符之间的字符串，并且只能包含字母、数字、下划线、连字符、冒号、正斜杠和句点。要将 `releaseId` 作为元数据添加到 RUM 事件，请配置 CloudWatch RUM Web 客户端。

源映射应是纯 JSON 文件，遵循[源映射 V3 规范](https://sourcemaps.info/spec.html)定义的结构。必填字段包括：`version`、`file`、`sources`、`names` 和 `mappings`。

确保每个源映射的大小不超过 50MB 的限制。此外，RUM 服务对每个堆栈跟踪最多只能检索 50MB 的源映射。如果需要，可将源代码分成多个小块。有关更多信息，请参阅使用 [WebpackJS 拆分代码](https://webpack.js.org/guides/code-splitting/)。

**Topics**
+ [要求和语法](#CloudWatch-RUM-RequirementsJavaScriptStackTraceSourceMaps)
+ [配置 Amazon S3 存储桶资源策略以允许 RUM 服务访问](#CloudWatch-RUM-ConfigureS3)
+ [上传源映射](#CloudWatch-RUM-UploadSourceMaps)
+ [在 CloudWatch RUM Web 客户端中配置 releaseId](#CloudWatch-RUM-ConfigureRumID)
+ [启用 CloudWatch RUM 应用程序监测仪以取消压缩 JavaScript 堆栈跟踪](#CloudWatch-RUM-unminifyjavascript)
+ [在 RUM 控制台中查看未压缩的堆栈跟踪](#CloudWatch-RUM-viewunminifiedstacktraces)
+ [在 CloudWatch Logs 中查看未压缩的堆栈跟踪](#CloudWatch-RUM-viewunminifiedstacktracesCWL)
+ [排查源映射问题](#CloudWatch-RUM-troubleshootsourcemaps)

## 配置 Amazon S3 存储桶资源策略以允许 RUM 服务访问
<a name="CloudWatch-RUM-ConfigureS3"></a>

确保 Amazon S3 存储桶与 RUM appMonitor 位于同一区域。配置 Amazon S3 存储桶，允许 RUM 服务访问以检索源映射文件。包含 `aws:SourceArn` 和 `aws:SourceAccount` 全局条件上下文键，以限制服务对资源的权限。这是防范[混淆代理问题](https://docs.amazonaws.cn/IAM/latest/UserGuide/confused-deputy.html)最有效的方法。

以下示例演示如何使用 Amazon S3 中的 `aws:SourceArn` 和 `aws:SourceAccount` 全局条件上下文键来防范混淆代理问题。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "RUM Service S3 Read Permissions",
            "Effect": "Allow",
            "Principal": {
                "Service": "rum.amazonaws.com"
            },
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::BUCKET_NAME",
                "arn:aws:s3:::BUCKET_NAME/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "ACCOUNT_ID",
                    "aws:SourceArn": "arn:aws:rum:REGION:ACCOUNT_ID:appmonitor/APP_MONITOR_NAME"
                }
            }
        }
    ]
}
```

------

如果您使用 Amazon KMS 密钥来加密数据，请确保密钥的资源策略配置为包含 `aws:SourceArn` 和 `aws:SourceAccount` 全局条件上下文键，授予 RUM 服务使用密钥检索源映射文件的访问权限。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "RUM Service KMS Read Permissions",
            "Effect": "Allow",
            "Principal": {
                "Service": "rum.amazonaws.com"
            },
            "Action": "kms:Decrypt",
            "Resource": "arn:aws:kms:us-east-1:123456789012:key/KEY_ID",
            "Condition": {
                "StringEquals": {
                "aws:SourceAccount": "123456789012",
    "aws:SourceArn": "arn:aws:rum:us-east-1:123456789012/APP_MONITOR_NAME"
                }
            }
        }
    ]
}
```

------

## 上传源映射
<a name="CloudWatch-RUM-UploadSourceMaps"></a>

配置 JavaScript 捆绑包以在压缩期间生成源映射。当您构建应用程序时，捆绑包将创建一个目录（例如 dist），其中包含压缩的 JavaScript 文件及其相应的源映射。有关示例，请参阅以下内容。

```
./dist
    |-index.d5a07c87.js
    |-index.d5a07c87.js.map
```

将源映射文件上传到您的 Amazon S3 存储桶。文件位于名为 `releaseId` 的文件夹中。例如，如果我的存储桶名称为 `my-application-source-maps`，且 `releaseId` 为 2.0.0，则源映射文件位于以下位置：

```
my-application-source-maps
    |-2.0.0
        |-index.d5a07c87.js.map
```

要自动上传源映射，可以创建以下 bash 脚本，并在构建过程中执行。

```
#!/bin/bash
# Ensure the script is called with required arguments
if [ "$#" -ne 2 ]; then
 echo "Usage: $0 S3_BUCKET_NAME RELEASE_ID"
 exit 1
fi

# Read arguments
S3_BUCKET="$1"
RELEASE_ID="$2"

# Set the path to your build directory
BUILD_DIR="./dist"


# Upload all .map files recursively
 if aws s3 cp "$BUILD_DIR" "s3://$S3_BUCKET/$RELEASE_ID/" --recursive --exclude "*" --include "*.map"; then
    echo "Successfully uploaded all source map files"
else
    echo "Failed to upload source map files"
fi
```

## 在 CloudWatch RUM Web 客户端中配置 releaseId
<a name="CloudWatch-RUM-ConfigureRumID"></a>

CloudWatch RUM 使用配置的 `releaseId` 来确定用于检索源映射文件的文件夹。将 `releaseId` 命名为与源映射文件的文件夹相同的名称。如果您使用上面提供的 bash 脚本或类似的脚本，则脚本中配置的 `releaseId` 应与 CloudWatch RUM Web 客户端中配置的相同。必须使用 1.21.0 或更高版本的 CloudWatch RUM Web 客户端。

```
import { AwsRum, AwsRumConfig } from "aws-rum-web";

try {
    const config: AwsRumConfig = {
        sessionSampleRate: 1,
        endpoint: "https://dataplane.rum.us-west-2.amazonaws.com",
        telemetries: ["performance", "errors", "http"],
        allowCookies: true,
        releaseId: "RELEASE_ID", //Add this
    };

    const APPLICATION_ID: string = "APP_MONITOR_ID";
    const APPLICATION_VERSION: string = "1.0.0";
    const APPLICATION_REGION: string = "us-west-2";

    new AwsRum(APPLICATION_ID, APPLICATION_VERSION, APPLICATION_REGION, config);
} catch (error: any) {
    // Ignore errors thrown during CloudWatch RUM web client initialization
}
```

## 启用 CloudWatch RUM 应用程序监测仪以取消压缩 JavaScript 堆栈跟踪
<a name="CloudWatch-RUM-unminifyjavascript"></a>

要取消压缩 JavaScript 堆栈跟踪记录，请将应用程序监测仪的 SourceMap 状态设置为 `ENABLED`。为包含应用程序监测仪所有源映射的存储桶或文件夹提供 Amazon S3 URI。

如果将源映射直接存储在主存储桶中（而不是子文件夹中），则 Amazon S3 URI 的格式应为 `Amazon S3://BUCKET_NAME`。在此情况下，源映射文件应位于以下位置。

```
BUCKET_NAME
    |- RELEASE_ID
        |-index.d5a07c87.js.map
```

当子目录为根目录时，Amazon S3 URI 的格式应为 `Amazon S3://BUCKET_NAME/DIRECTORY`。在此情况下，源映射文件应位于以下位置。

```
BUCKET_NAME
    |- DIRECTORY
        |-RELEASE_ID
            |-index.d5a07c87.js.map
```

## 在 RUM 控制台中查看未压缩的堆栈跟踪
<a name="CloudWatch-RUM-viewunminifiedstacktraces"></a>

将源映射上传到 Amazon S3，在 RUM 应用程序监测仪上启用源映射，并使用在 CloudWatch RUM Web 客户端中配置的 `releaseId` 部署 Web 应用程序后，在 RUM 控制台中选择**事件**。此选项卡显示原始 RUM 事件数据。按 JS 错误事件类型筛选，查看最新的 JS 错误事件。对于启用该功能后摄取的事件，您将在新的 `event_details.unminifiedStack` 字段中看到未压缩的堆栈跟踪。

## 在 CloudWatch Logs 中查看未压缩的堆栈跟踪
<a name="CloudWatch-RUM-viewunminifiedstacktracesCWL"></a>

打开**数据存储**，在 CloudWatch Logs 中启用 RUM 事件存储。启用后，您可以搜索新的 **event\$1details.unminifiedStack** 字段。这使您可以使用 CloudWatch Logs 查询分析趋势并关联多个会话中的问题。

## 排查源映射问题
<a name="CloudWatch-RUM-troubleshootsourcemaps"></a>

CloudWatch RUM 提供了现成的指标来排查源映射设置的问题。这些指标在名为 `AWS/RUM` 的指标命名空间中发布。以下指标通过 application\$1name 维度发布。此维度的值为应用程序监控的名称。这些指标还通过 `aws:releaseId` 维度发布。该维度的值是与 JavaScript 错误事件关联的 `releaseId`。


| MetricName | 单位 | 说明 | 
| --- | --- | --- | 
|  UnminifyLineFailureCount  |  计数  |  JS 错误事件中未能取消压缩的堆栈跟踪行数。有关失败的其他详细信息将添加到 event\$1details.unminifiedStack 字段中失败的特定行中。  | 
|  UnminifyLineSuccessCount  |  计数  | JS 错误事件中成功取消压缩的堆栈跟踪行数。 | 
| UnminifyEventFailureCount | 计数 | 未能取消压缩任何行的 JS 错误事件数。有关失败的其他详细信息将添加到 event\$1details.unminifiedStack 字段中。 | 
| UnminifyEventSuccessCount | 计数 | 成功取消压缩至少一个堆栈跟踪行的 JS 错误事件数。 | 

CloudWatch RUM 可能由于各种原因无法取消压缩堆栈跟踪中的某一行，包括但不限于：
+ 由于权限问题，无法检索对应的源映射文件。确保存储桶资源策略配置正确。
+ 对应的源映射文件不存在。确保源映射文件已上传到正确的存储桶或文件夹，其名称与 CloudWatch RUM Web 客户端中配置的 releaseId 相同。
+ 对应的源映射文件太大。将源代码拆分成小块。
+ 为堆栈跟踪检索到的源映射文件已达 50MB。减少堆栈跟踪长度，因为 50MB 是服务端限制。
+ 源映射无效，无法建立索引。确保源映射是遵循源映射 V3 规范定义的结构的纯 JSON，并包含以下字段：版本、文件、来源、名称、映射。
+ 源映射无法将压缩的源代码映射回未压缩的堆栈跟踪。确保源映射是给定 releaseId 的正确源映射。