4. CloudTrail 日志存储目标:S3、CloudWatch Logs、Metrics

CloudTrail 把日志吐出来之后,你总得找个地方放。放哪?怎么放?这直接决定你能拿日志干什么、花多少钱。我过去在几个项目里踩过不少坑,今天把三个主流存储目标说透。

一句话定位:S3 是“数据粮仓”,适合长期存、批量分析;CloudWatch Logs 是“实时看板”,适合排查、告警;CloudWatch Metrics 是“量化指标”,适合监控趋势、触发自动伸缩。
CloudTrail 日志存储目标选择架构 CloudTrail S3 桶存储 CloudWatch Logs CloudWatch Metrics 数据湖 / 归档 实时分析 / 告警 仪表盘 / 自动伸缩 生命周期策略 + 跨区域复制 订阅到 Lambda / Kinesis 5分钟粒度,可转为1分钟 三个目标可同时使用,互不冲突

4.1 S3 桶存储:最稳的底仓

我个人最常用的方案就是 S3。CloudTrail 默认就能直接写 S3,不需要额外配置什么订阅。嗯,这里要注意:默认的日志前缀是 AWSLogs/<account-id>/CloudTrail/<region>/,这个结构已经够用了,但如果你有多个账号,最好统一组织一下。

我建议的 S3 桶结构:
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 做后期分析。

小技巧:在 S3 桶上开启清单(Inventory)和对象级日志(Server Access Log),方便核对审计完整性。我曾经遇到过 S3 桶被意外删除的情况,后来强制加了 MFA Delete 和桶策略只允许 CloudTrail 服务写入。

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 里塞所有事件,结果一个月日志量翻了三倍,账单吓人。后来只把关键事件(如 EC2 RunInstances, IAM CreateUser)路由过去,其他事件走 S3。

如何配置?在 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 LogsCloudWatch Metrics
实时性分钟级秒级分钟级(1~5 min)
查询能力Athena / PrestoLogs 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。
我现在的通用方案:所有事件写 S3(成本基线),同时挑出 5~10 个高敏感事件走 CloudWatch Logs(比如 AuthorizeSecurityGroupIngress、PutBucketPolicy),再用 Metric Filter 把失败事件数做成指标,挂到 Dashboard 上。三个目标各司其职,互不冲突。

至于配置顺序?我习惯先建 S3 桶并配置生命周期,再建 Log Group 并设好保留天数(防止日志无限增长),最后通过 CloudTrail 控制台或 CLI 一次性指定这两个目标。Metrics 是在 Log Group 创建后才加的公制过滤器,因为需要先有日志流。

注意跨账号场景:如果日志要统一存到审计账号的 S3 桶,别忘了在目标桶上添加 CloudTrail 服务角色的写入权限,并启用 Bucket Policy 允许跨账号访问。我曾经在多个账号之间折腾权限半天,最后发现忘了加 Condition: StringEquals aws:SourceArn,所有人都能往桶里写,差点出安全问题。

好了,三个目标讲完了。你选哪个取决于你的场景,但建议至少留一个 S3 做“底仓”。CloudWatch Logs 和 Metrics 做“快仓”,两者结合,审计监控才算完整。