4. CloudWatch Logs深度使用
CloudWatch Logs 是 AWS 上最常用的日志汇聚与检索服务,但很多团队只把它当作“看日志的地方”,忽略了它真正的数据模型与处理链路。要把它用好,先要理解四个核心对象:日志组(Log Group)、日志流(Log Stream)、订阅过滤器(Subscription Filter)和指标过滤器(Metric Filter)。它们共同构成一条从“日志产生”到“检索、告警、外送”的完整链路。
一、日志组与日志流:数据模型与保留策略
日志组是日志的顶层容器,通常按“应用 + 环境”划分,例如 /aws/lambda/order-service-prod、/app/payment/prod。日志组上最重要的两个属性是保留策略(Retention)和加密。保留策略默认是“永不过期”,这在生产环境会持续累积成本,建议按合规要求设置为 7、30、90 或 365 天。日志流是日志组内的子容器,一般对应一个具体的实例、容器或执行环境,例如 Lambda 的每次执行环境、EC2 上的某个进程实例。日志流名称常包含实例 ID 或时间戳,便于定位来源。
一个常见的排障误区是:只按日志组搜索,忽略了日志流的时间边界。日志流一旦关闭(例如容器重启),新日志会写入新的日志流。因此排查“某次请求失败”时,应先用时间范围过滤,再在多个日志流中交叉检索。
二、订阅过滤器:把日志实时外送
订阅过滤器解决的是“日志不只留在 CloudWatch”的问题。它可以把匹配到的日志以实时流方式推送到 Kinesis Data Streams、Kinesis Data Firehose 或 Lambda。典型用途包括:把日志送到 OpenSearch 做全文检索、送到 S3 做长期归档、或送到第三方 SIEM 做安全分析。
订阅过滤器使用过滤模式(Filter Pattern)决定哪些日志被外送。例如只外送 ERROR 级别日志:
{ $.level = "ERROR" }
需要注意:一个日志组最多只能有两个订阅过滤器,且每个过滤器只能有一个目标。如果同时需要归档和告警,通常用 Firehose 分发到多个目的地,而不是叠加多个订阅过滤器。
三、指标过滤器:从日志中提取数值并告警
指标过滤器把日志中的文本或 JSON 字段转换成 CloudWatch 指标,从而可以配置告警。它的核心是“过滤模式 + 指标值”。例如从 JSON 日志中提取响应时间:
{ $.latency = * }
指标名称:Latency
指标值:$.latency
单位:Milliseconds
再比如统计 ERROR 出现次数,用过滤模式 { $.level = "ERROR" },指标值设为 1,即可得到“错误计数”指标。指标过滤器支持默认值和维度,维度可以从日志字段中提取,例如按 $.service 分组,这样就能对每个服务单独告警。
一个实用技巧:指标过滤器只对新写入的日志生效,不会回溯历史日志。因此上线新的指标过滤器后,需要等待一段时间才能看到数据。
四、Logs Insights 查询语法
Logs Insights 是 CloudWatch 的交互式查询引擎,语法接近 SQL 但更偏向日志场景。基本结构是:
fields @timestamp, @message
| filter @message like /ERROR/
| sort @timestamp desc
| limit 20
常用命令包括:fields 选择字段、filter 过滤、stats 聚合、sort 排序、limit 限制条数、parse 解析非结构化文本。例如统计每个接口的 P99 延迟:
fields @timestamp, endpoint, latency
| filter ispresent(latency)
| stats pct(latency, 99) as p99 by endpoint
| sort p99 desc
对于 JSON 日志,可以直接用 $.field 引用字段;对于纯文本日志,用 parse 提取,例如:
parse @message "status=* duration=*" as status, duration
| filter status >= 500
| stats count() by bin(5m)
查询时要注意时间范围和扫描量。Logs Insights 按扫描的数据量计费,范围越大、日志越多,成本越高。生产排障时建议先用窄时间窗口定位,再逐步扩大。
五、生产排障案例:一次订单超时排查
假设订单服务在 14:00 左右出现大量超时告警。排查步骤如下:
- 打开日志组
/app/order/prod,时间范围设为 13:55–14:10。 - 用 Logs Insights 查询超时请求:
fields @timestamp, orderId, latency | filter latency > 3000 | sort @timestamp asc。 - 发现超时集中在某个下游依赖,进一步用
stats count() by bin(1m)看趋势。 - 检查该依赖的日志组,确认是否有连接池耗尽或限流错误。
- 如果已配置指标过滤器,可直接查看
Latency指标的突增点,与告警时间对齐。
这个案例的关键在于:日志组定位范围、日志流确认实例、Logs Insights 聚合趋势、指标过滤器验证告警,四者配合才能快速收敛问题。