

# 日志警报
<a name="alarm-log"></a>

日志警报监控使用[计划查询](https://docs.amazonaws.cn/AmazonCloudWatch/latest/logs/ScheduledQueries.html)按计划运行的 CloudWatch Logs Insights 查询的结果。该警报将聚合表达式应用于查询结果以生成数值，当该聚合值违反配置的阈值时，警报将转换为 `ALARM` 状态并运行配置的操作。

与需要指标筛选条件作为中间步骤的指标警报不同，日志警报直接使用用于临时分析的相同 Logs Insights 查询语言对日志数据进行评估。

## 日志警报的工作原理
<a name="log-alarm-how-it-works"></a>

以下步骤介绍了日志警报的工作原理：

1. 您可以通过查询、聚合表达式、计划和阈值创建日志警报。

1. CloudWatch 会自动创建一个 Amazon 托管的计划查询，该查询会按照指定的计划运行查询。

1. 每次查询执行都会产生聚合结果（单个值或多个贡献值）。

1. CloudWatch 对最近的查询执行使用 M-out-of-N 评估来根据阈值评估聚合结果。

1. 如果违反阈值，警报将转换为 `ALARM` 状态并运行配置的操作（如 Amazon SNS 通知）。

**注意**  
日志警报会评估最近 N 次查询执行。当这 N 次执行中有 M 次违反阈值时，警报会转换为 `ALARM`。

要创建日志警报，请参阅[创建日志警报](Alarm-On-Logs.md#Create_Log_Alarm)。

## 托管的计划查询生命周期
<a name="log-alarm-managed-query"></a>

当您创建日志警报时，CloudWatch 会自动创建一个 Amazon 托管的计划查询，该查询会按照指定的计划运行查询。不需要单独创建计划查询

Amazon 托管的计划查询具有以下特征：
+ 它在 CloudWatch Logs 控制台的“计划查询”下可见。
+ 不能直接修改它。要更改查询或其配置，请更新日志警报。
+ 当您删除警报时，CloudWatch 会删除 Amazon 托管的计划查询。

## 日志报警配置
<a name="log-alarm-configuration"></a>

日志报警配置了以下参数：
+ **QueryString** 是要运行的 CloudWatch Logs Insights 查询。
+ **LogGroupIdentifiers** 是要查询的日志组。请指定日志组名称或日志组 ARN。
+ **ScheduledQueryRoleARN** 是 IAM 角色的 ARN，该角色允许 CloudWatch Logs 代表您运行计划查询。
+ **AggregationExpression** 定义如何将查询结果聚合为数值以进行阈值评估。
+ **ScheduleExpression** 定义查询的运行频率（如 `rate(5 minutes)`）。
+ **StartTimeOffset** 定义每次执行查询的回溯窗口（以秒为单位）。
+ **EndTimeOffset** 将查询时间范围的结束定义为与当前时间的偏移量（以秒为单位）。
+ **ComparisonOperator** 是将聚合结果与阈值进行比较的方式。有效值：`GreaterThanThreshold`、`GreaterThanOrEqualToThreshold`、`LessThanThreshold`、`LessThanOrEqualToThreshold`。
+ **Threshold** 是要比较的数值。
+ **QueryResultsToEvaluate** 是要评估的最近查询执行次数（M-out-of-N 中的 N）。
+ **QueryResultsToAlarm** 是触发 `ALARM` 所需的违规结果数（M-out-of-N 中的 M）。
+ **TreatMissingData** 定义评估期间如何处理缺失的查询结果。

有关参数和创建说明的完整列表，请参阅[创建日志警报](Alarm-On-Logs.md#Create_Log_Alarm)。

## 日志查询
<a name="log-alarm-query"></a>

日志警报查询是一个 CloudWatch Logs Insights 查询，其会选择和筛选要评估的日志数据。该查询在 `LogGroupIdentifiers` 中指定的日志组上运行，时间范围由 `StartTimeOffset` 和 `EndTimeOffset` 定义。

该查询使用 [CloudWatch Logs Insights 查询语法](https://docs.amazonaws.cn/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html)。有关为日志警报编写高效查询的指南，请参阅[最佳实践和故障排除](#log-alarm-best-practices)。

## 聚合表达式
<a name="log-alarm-aggregation"></a>

聚合表达式定义 CloudWatch 如何将查询结果汇总为数值以进行阈值评估。该表达式使用与 CloudWatch Logs Insights 中的 `stats` 命令相同的语法。

聚合表达式的语法如下：

```
statistic_func_expression [by field1, field2, ...] [| sort asc|desc]
```

只能指定一个聚合表达式。下表列出了支持的聚合函数。


**支持的聚合函数**  

| 函数 | 说明 | 示例 | 
| --- | --- | --- | 
| count(\*) | 所有匹配日志行的计数。 | count(\*) | 
| avg(field) | 指定字段的平均值。 | avg(duration) | 
| sum(field) | 指定字段的总和。 | sum(bytesSent) | 
| min(field) | 指定字段的最小值。 | min(latency) | 
| max(field) | 指定字段的最大值。 | max(latency) | 

`bin()` 函数在聚合表达式的 `by` 子句中不受支持。但是，您可以在查询字符串本身中使用 `bin()`。

## 多贡献者警报
<a name="log-alarm-multi-contributor"></a>

当您在聚合表达式中包含 `by` 子句时，警报会独立评估字段值的每个唯一组合（称为*贡献者*）。如果任何贡献者违反了阈值，警报将转换为 `ALARM` 状态。

例如，下面的表达式按服务名称对错误计数进行分组：

```
count(*) by serviceName
```

`serviceName` 的每个唯一值都会根据阈值独立进行评估。如果任何服务在 N 次查询执行中的 M 次超过阈值，则警报会进入 `ALARM` 状态。

下面的限制适用于多贡献者警报：
+ `by` 子句中最多 5 个字段。
+ 每次查询执行最多返回 500 个贡献者结果。
+ 最多同时跟踪 100 个处于 `ALARM` 状态的贡献者。

默认情况下，贡献者按字母顺序排序，每次查询执行仅返回前 500 个。要改为按聚合值对贡献者进行排序，请在聚合表达式中指定 `| sort asc` 或 `| sort desc`（如 `avg(latency) by serviceName | sort desc`）。当总数超过 500 时，基于值的排序可确保首先评估最重要的贡献者。

对于多贡献者警报，Amazon SNS 和 Lambda 操作在贡献者级别运行（每个违规贡献者一次）。Systems Manager OpsItem 操作在警报级别运行。

**注意**  
日志警报不支持 Systems Manager Incident Manager 和调查操作。

如果某个贡献者从查询结果中消失（例如，临时资源被终止），则无论缺失数据处理设置如何，该贡献者都会转换为 `OK` 状态。

## 缺失数据处理
<a name="log-alarm-missing-data"></a>

当计划的查询执行没有产生可以根据阈值进行评估的值时，就会发生数据丢失。这发生在以下情况下：

**不存在日志**：日志组在查询时间范围内不包含任何日志事件。

**查询未返回任何适用结果**：存在日志，但聚合表达式无法产生值。以下情况下会发生这种情形：
+ 根据查询筛选条件，不存在匹配的查询结果。
+ 聚合表达式中引用的字段在查询结果中不存在。例如 `count(error-codes)`，其中 `error-codes` 不存在于返回的日志事件中。

请注意，对空结果集执行 `count(*)` 会返回 0，这是一个有效的数据点，不会被视为缺失。

您可以使用 `TreatMissingData` 参数配置警报如何处理缺失数据。下表介绍了可用选项。


**缺失数据处理选项**  

| 值 | 行为 | 
| --- | --- | 
| missing | 将数据点视为缺失。这是默认值。 | 
| notBreaching | 将缺失的数据点视为未违反阈值。 | 
| breaching | 将缺失的数据点视为违反阈值。 | 
| ignore | 忽略缺失的数据点，仅评估可用数据。 | 

## 评估状态
<a name="log-alarm-evaluation-states"></a>

除了标准 `OK`、`ALARM` 和 `INSUFFICIENT_DATA` 状态外，日志警报还可以在 `EvaluationState` 字段中报告以下评估状态。这些状态提供有关警报为何处于当前状态的更多背景信息。


**日志警报评估状态**  

| 州 | 说明 | 
| --- | --- | 
| EVALUATION\_FAILURE | 暂时的 CloudWatch 服务问题导致无法进行评估。当服务因服务错误而在评估查询结果时遇到问题，或者当部分（但不是全部）查询结果失败时，就会发生这种情况。警报会转换为 INSUFFICIENT\_DATA。我们建议手动监控，直到问题得到解决。 | 
| EVALUATION\_ERROR | 客户端配置错误导致无法进行评估。这可能是由于权限不足、查询无效或所有查询结果均失败造成的。警报会立即转换为 INSUFFICIENT\_DATA。有关详细信息，请参阅 StateReason 字段。 | 
| PARTIAL\_DATA | 查询返回了最多 500 个贡献者组，但匹配的组更多。警报会评估可用的贡献者，但结果可能不完整。 | 

## 警报更新
<a name="log-alarm-update"></a>

当您更新日志警报的查询、聚合表达式、计划或日志组时，警报会转换为 `INSUFFICIENT_DATA`，直到收集到足够的新数据点。更改阈值或 M-out-of-N 值不会触发此重置。

## 操作和通知
<a name="log-alarm-notifications"></a>

日志警报支持以下操作：
+ Amazon SNS 通知
+ Lambda 函数调用
+ Systems Manager OpsItem 创建

有关完整的操作支持矩阵，请参阅[警报操作](alarm-actions.md)。

当日志警报转换状态时，操作通知包含下面的信息：
+ 标准警报配置更改信息（警报名称、描述、配置详细信息）。
+ 状态更改信息（新状态、状态原因、时间戳）。
+ Amazon SNS 电子邮件通知还包括指向 CloudWatch Logs Insights 控制台的深度链接，其中显示了完整的查询结果。

以下示例显示了单值日志警报（不含 `BY` 子句）的 Amazon SNS 电子邮件通知：

```
{
    "AlarmName": "HighErrorCount",
    "NewStateValue": "ALARM",
    "NewStateReason": "Threshold Crossed: 3 out of the last 5 query results [142.0 (10/06/26 12:15:00), 135.0 (10/06/26 12:10:00), 120.0 (10/06/26 12:05:00)] were greater than the threshold (100.0) (minimum 3 datapoints for OK -> ALARM transition).",
    "NewStateReasonData": {
        "version": "1.0",
        "queryDate": "2026-06-10T12:15:30.000+0000",
        "threshold": 100.0,
        "queryResultsToEvaluate": 5,
        "queryResultsToAlarm": 3,
        "results": [
            {
                "queryResultId": "scheduled-query-execution-id-3",
                "status": "COMPLETE",
                "timestamp": "2026-06-10T12:15:00.000+0000",
                "value": 142.0
            }
            // Additional results...
        ]
    },
    "StateChangeTime": "2026-06-10T12:15:30.000+0000",
    "OldStateValue": "OK"
    // Additional fields...
}
```

以下示例显示了多贡献者日志警报（含 `BY` 子句）的 Amazon SNS 电子邮件通知。每个违规贡献者都会生成一条单独的通知：

```
{
    "AlarmName": "EndpointLatency",
    "NewStateValue": "ALARM",
    "NewStateReason": "5 out of 10 contributors evaluated to ALARM",
    "StateChangeTime": "2026-06-10T12:20:15.000+0000",
    "OldStateValue": "OK",
    "AlarmContributorId": "a1b2c3d4e5f6g7h8",
    "AlarmContributorAttributes": {
        "endpoint": "/api/orders"
    }
    // Additional fields...
}
```

### 在通知中包括日志行
<a name="log-alarm-log-lines"></a>

您可以通过将 `ActionLogLineCount` 参数设置为 1 到 50 之间的值，选择性地将原始查询结果日志行包括在警报通知中。这些是用于评估聚合表达式的底层日志事件，而不是聚合值。默认值为 0，意味着不包括任何日志行。

**注意**  
日志行仅包括在 Amazon SNS 电子邮件通知中。Lambda 操作在其有效载荷中不包括日志行。

**重要**  
在通知中包括日志行可能会在 Amazon SNS 消息中暴露日志中的敏感数据。启用此功能之前，请先查看日志内容。

要包括日志行，日志行角色必须具有 `logs:GetQueryResults` 权限。通知中包括的日志行数受请求计数、可用结果总数和 Amazon SNS 有效载荷大小限制的约束。

## 最佳实践和故障排除
<a name="log-alarm-best-practices"></a>

### 最佳实践
<a name="log-alarm-bp"></a>

**查询优化**
+ 在将查询用于日志警报之前，请先在 CloudWatch Logs Insights 中手动测试查询，以验证其性能和预期结果。
+ 在查询的早期使用筛选命令以减少处理的数据量。
+ 限制查询时间范围（StartTimeOffset）以避免大量日志组超时。
+ 使用字段索引来优化查询性能。

**计划规划**
+ 选择一个允许查询在下次执行之前完成的计划频率。对于大量日志组，请使用更长的间隔（例如 10 分钟而不是 5 分钟）。
+ 设置 StartTimeOffset 时，请考虑日志摄取延迟。EndTimeOffset 和当前时间之间的小差距有助于避免评估不完整的数据。
+ 将日志警报计划分散到账户中，以避免达到计划查询并发限制。账户中的并发查询执行次数不能超过 100 次。在创建具有重叠计划的多个日志警报时，请考虑此配额。

**阈值调整**
+ 从较高的 QueryResultsToEvaluate（N）值开始，以减少瞬态峰值产生的警报噪音。
+ 对于稀疏事件（例如很少发生的错误），请将 TreatMissingData 设置为 `notBreaching`，以便在没有日志匹配时保持警报处于 OK 状态。
+ 对于连续信号（例如流量日志），请考虑将 TreatMissingData 设置为 `breaching`，以检测预期日志数据何时停止到达。

**多贡献者设计**
+ 为 BY 子句选择有意义的字段，这些字段代表要独立监控的不同资源或维度。
+ 请注意，每次查询执行仅返回前 500 个贡献者。如果希望返回更多贡献者，请缩小查询范围或使用更少的 BY 子句字段。
+ 当达到 500 个贡献者限制时，请在聚合表达式中使用 `| sort desc` 或 `| sort asc` 后缀，以根据比较运算符优先考虑最高值或最低值。

### 问题排查
<a name="log-alarm-troubleshooting"></a>

**警报停留在 INSUFFICIENT\_DATA**


| 可能的原因 | 解决方案 | 
| --- | --- | 
| 计划查询执行角色缺少权限 | 验证角色是否具有 logs:StartQuery、logs:StopQuery、logs:GetQueryResults 和 logs:DescribeLogGroups 权限，且范围限于正确的日志组。 | 
| 日志组不存在或已被删除 | 验证警报配置中的日志组 ARN 是否正确且可访问。 | 
| 最近创建或更新的警报 | 创建或配置更新后，警报将保持在 INSUFFICIENT\_DATA 状态，直到完成足够的查询执行以满足 M-out-of-N 评估窗口。 | 
| 计划查询未运行 | 在 CloudWatch Logs 控制台中检查 Amazon 托管的计划查询，以验证其是否按计划执行。 | 
| 查询结果中不存在聚合字段 | 聚合表达式中引用的字段必须存在于查询结果中。例如，如果聚合是 avg(latency)，请确保查询生成一个 latency 字段。如果该字段不存在，则结果会被视为缺失数据。 | 
| 日志摄取延迟 | 计划查询只能评估在其运行之前已摄取的日志事件。`StartTimeOffset` 和 `EndTimeOffset` 定义相对于执行时间 T（T - StartTimeOffset，T - EndTimeOffset）的查询窗口，但它们并未考虑摄取延迟。如果查询的窗口内仍有事件正在被摄取，则查询会在事件可用之前运行并跳过这些事件。<br />使用 `EndTimeOffset` 将窗口向后移动足够远，以便完成整个范围的摄取。<br />例如：假设事件发生后，日志最多需要 2 分钟才能可查询。+  `StartTimeOffset=60, EndTimeOffset=0`：窗口 [T−60s, T]。窗口在执行时结束，因此最近的事件尚未被摄取，因而被错过。 <br />+  `StartTimeOffset=180, EndTimeOffset=120`：窗口 [T−180s, T−120s]。窗口在过去 2 分钟结束，此时所有事件都已被摄取并且可评估。  | 

**警报显示 EVALUATION\_ERROR**

这表明客户端配置存在问题。请查看 StateReason 字段了解详情。常见原因：
+ 查询语法无效或格式错误。
+ 计划查询执行角色的权限不足。
+ 所有查询执行失败（例如，日志组权限已撤销）。

**警报显示 EVALUATION\_FAILURE**

这表明存在暂时性 CloudWatch 服务问题。问题解决后，警报会自动恢复。如果问题持续超过几分钟，请查看 CloudWatch 服务运行状况控制面板。

**警报显示 PARTIAL\_DATA**

查询返回了最多 500 个贡献者组，但匹配的组更多。警报会评估可用的贡献者，但结果可能不完整。请考虑缩小查询范围或减少 BY 子句字段的数量。

**通知中未显示日志行**
+ 验证 `ActionLogLineCount` 是否设置为 1 到 50 之间的值。
+ 验证日志行角色是否具有 `logs:GetQueryResults` 权限且范围限于正确的日志组。
+ 日志行仅包括在 Amazon SNS 电子邮件通知中。其他操作类型不包括日志行。
+ 使用 `unmask()` 的查询不能在通知中包括日志行（创建时被拒绝）。

有关查询优化、监控和授权的其他最佳实践，请参阅《Amazon CloudWatch Logs 用户指南》**中的 [Scheduled Queries best practices](https://docs.amazonaws.cn/AmazonCloudWatch/latest/logs/scheduled-queries-best-practices.html)。