4. CloudTrail 日志存储目标:S3、CloudWatch Logs、Metrics
CloudTrail 把日志吐出来之后,你总得找个地方放。放哪?怎么放?这直接决定你能拿日志干什么、花多少钱。我过去在几个项目里踩过不少坑,今天把三个主流存储目标说透。
4.1 S3 桶存储:最稳的底仓
我个人最常用的方案就是 S3。CloudTrail 默认就能直接写 S3,不需要额外配置什么订阅。嗯,这里要注意:默认的日志前缀是 AWSLogs/<account-id>/CloudTrail/<region>/,这个结构已经够用了,但如果你有多个账号,最好统一组织一下。
my-org-cloudtrail-<env>/AWSLogs/<account-id>/CloudTrail/<region>/<YYYY/MM/DD>这样 Athena 直接分区就能查,省去大量 ETL 时间。
为什么选 S3 做第一目标?说白了,成本低、存得久。S3 标准存储一 GB 不到 0.023 美元,而且你可以加生命周期规则——比如 90 天后自动转成 Glacier 归档,存个十年也没问题。我在一个金融项目里,审计要求保留日志 7 年,靠 S3 + Glacier 每年只花几百刀。
但 S3 有个短板:查日志不够快。想实时看某个 API 调用?不行,S3 延迟通常几分钟甚至更久(最终一致性有时十几分钟)。所以需要配合 Athena 或者 Amazon OpenSearch 做后期分析。
4.2 CloudWatch Logs:实时排障的利器
如果你想在日志产生后几秒内就看到,那必须走 CloudWatch Logs。CloudTrail 支持直接把事件发到 Log Group,然后你就能用 CloudWatch Logs Insight 查询——比如搜出所有来自非中国区的 ConsoleLogin 事件。我用这个在安全事件应急中快速定位过异常登录。
CloudWatch Logs 的优势是 实时性和 集成性。你可以给 Log Group 设置订阅过滤器,把匹配的日志实时推给 Lambda 函数或者 Kinesis Data Firehose,再做定制处理。你想想看,当检测到 CreateNetworkAclEntry 这类高风险操作时,直接触发 Webhook 通知团队,反应时间从小时级降到秒级。
不过 CloudWatch Logs 也有坑——存储成本偏高。我统计过一个中型项目:每天产生约 2 GB 日志,在 CloudWatch Logs 里存 30 天,每个月费用大概是 300 美元左右。如果长期保留,建议设置导出到 S3(Log Group 有个 Export 功能,或者用 Subscription 实时转存)。
如何配置?在 CloudTrail 创建或编辑事件记录器时,勾选“CloudWatch Logs”,选择 Log Group 名称,再指定角色——CloudTrail 会扮演这个角色把日志推送到 CloudWatch。你要注意的是角色必须要有 logs:PutLogEvents 权限。
// 示例:只记录管理事件到 CloudWatch Logs
Trail:
Name: management-trail
S3BucketName: my-org-cloudtrail-prod
CloudWatchLogsLogGroupArn: arn:aws:logs:us-east-1:123456789012:log-group:CloudTrail/ManagementEvents:*
CloudWatchLogsRoleArn: arn:aws:iam::123456789012:role/CloudTrailRole
IncludeGlobalServiceEvents: true
IsMultiRegionTrail: true
EnableLogFileValidation: true
4.3 CloudWatch Metrics:从事件到指标的转换
CloudTrail 本身不直接写 Metrics,但你可以通过 CloudTrail Insights 把异常事件转为指标。更普遍的做法是:把 CloudWatch Logs 的事件通过公制过滤器(Metric Filter)转换成自定义指标。举个例子,监控 ConsoleLogin 失败次数,然后设告警——当 5 分钟内失败超过 10 次,触发 SNS 通知或自动调用 Lambda 封禁 IP。
这个方案适合做“量化监控”。比如你想知道每天触发了多少次 StopInstance,用 CloudWatch Metrics 设一个 Count 指标,放到 Dashboard 上,一目了然。我在负责运维一个电商平台时,就靠这个监控到了频繁的自动伸缩事件,及时发现了一个 ASG 配置失误。
但 Metrics 的粒度默认是 5 分钟,如果你需要更精细,可以开启高精度(1 分钟)存储,但要额外付费。而且指标值只保留最多 15 个月,不适合做长期审计。
| 维度 | S3 桶 | CloudWatch Logs | CloudWatch Metrics |
|---|---|---|---|
| 实时性 | 分钟级 | 秒级 | 分钟级(1~5 min) |
| 查询能力 | Athena / Presto | Logs Insight(类SQL) | 告警 / Dashboard |
| 长期存储成本 | 极低(0.023$/GB + Glacier) | 较高(0.5$/GB/月) | 中等(0.3$/指标/月) |
| 适合场景 | 数据湖、归档、批量分析 | 实时排障、安全告警 | 趋势监控、自动伸缩 |
| 保留期限 | 无限(用生命周期控制) | 默认永久,可设过期 | 15 个月 |
4.4 选型决策思路
- 先定保留时间:超过 30 天必须走 S3,CloudWatch Logs 和 Metrics 长期存就是烧钱。
- 再定访问频率:每天查几十次的用 CloudWatch Logs;每周查一次的用 S3 + Athena。
- 最后定告警需求:需要实时告警的,Logs 配合 Metric Filter;需要长期阈值监控的,用 Metrics。
AuthorizeSecurityGroupIngress、PutBucketPolicy),再用 Metric Filter 把失败事件数做成指标,挂到 Dashboard 上。三个目标各司其职,互不冲突。
至于配置顺序?我习惯先建 S3 桶并配置生命周期,再建 Log Group 并设好保留天数(防止日志无限增长),最后通过 CloudTrail 控制台或 CLI 一次性指定这两个目标。Metrics 是在 Log Group 创建后才加的公制过滤器,因为需要先有日志流。
Bucket Policy 允许跨账号访问。我曾经在多个账号之间折腾权限半天,最后发现忘了加 Condition: StringEquals aws:SourceArn,所有人都能往桶里写,差点出安全问题。
好了,三个目标讲完了。你选哪个取决于你的场景,但建议至少留一个 S3 做“底仓”。CloudWatch Logs 和 Metrics 做“快仓”,两者结合,审计监控才算完整。