亚马逊AWS官方博客

利用 Cloudformation 快速部署简单易用的 CDN/WAF 日志服务

前言

在使用 AWS CloudFront 进行前端加速的场景中,运维人员经常需要查询日志历史,以分析特定资源的状态是否正常。一个具体的案例是查询某张图片在一定时间内返回 200 或 304 状态码的次数。常规做法是在 Athena 中手动创建表格和分区,并根据需求编写相应的查询语句。这种做法本身没有问题,但后续的流程却面临几个挑战:

  1. 查询都是单次执行的,无法根据业务需求实现自动化。
  2. 缺乏可视化手段,难以直观展示查询结果。
  3. 当结果异常时,如何快速通知相关人员?
  4. 常用查询语句需要一个统一管理的地方。

当然,运维人员可以基于 AWS 控制台或 CLI 构建满足上述需求的服务。然而,如何将这些服务进行封装以实现重复使用的目的,是成熟运维体系必须考虑的重要问题。

针对上述问题,本文介绍了利用 CloudFormation Infrastructure as Code 能力来封装 AWS 相关服务,并在部署时只需输入相应参数,即可快速搭建满足需求的服务架构。

架构图

架构图中 Cloudformation 负责拉起的部分有:

  • EventBridge:负责定时触发 Lambda Function
  • Lambda:负责主要逻辑,创建 CloudWatch Dashboard,Alarms,以及发送消息给 SNS
  • SNS:负责接收消息,发送给相关人员的邮箱

操作步骤

获取项目

目前项目已经开源在:https://github.com/xiwan/AWSTools/tree/master/CDNLogAnalyzer

建议大家使用 S3 版本的 Cloudformation 配置文件。可以看到里面有个 MyBundledLambdaFunction.zip 文件。它的内容就是将 index.js config.json 两个文件放在根目录下压缩了而已。

编辑配置文件

打包前,按照业务需求自定的配置参数如下

{
  "region": "us-east-1", // 区域
  "cloudWatch": {
    "dashboardName": "Test0704", // cw的dashboardName
    "alarm": { // cw 的告警
      "name": "Test0704", // 告警名字
      "description": "1000 as threshold", // 告警描述
      "threshold": 1000, // 告警门限
      "period": 300,  // 告警累计时间
      "datapointsToAlarm": 1, // 告警需要数据数目
      "evaluationPeriods": 1, // 告警评估时间
      "comparisonOperator": "GreaterThanThreshold" // 告警比较符
    },
    "namespace": "Test0704", //
    "dimension": {
      "name": "TestApp", //
      "value": "CDNCount" //
    }
  },
  "sns": {
    "subject": "Test0704", // 邮件标题
    "arn": "arn:aws:sns:{region}:{accountid}:xxxxx-0714-001-MySNSTopic-yZDTxNFJ9eaz", // 邮件订阅
    "threshold": 1000 // 邮件门限
  },
  "database": "default", // anthena 创建的默认库
  "sqls": [ // 可以放多个 sql 语句
    {
      "statement": "select count (uri) FROM cloudfront_logs WHERE status = 200 or status = 304"
    }
  ]
}

上传 S3

然后需要创建一个 S3 的桶, 将上面的 MyBundledLambdaFunction.zip 上传即可。

到这里为止,我们需要记录两个值:

  1. S3BucketName:my-lambda-function-code
  2. S3KeyName:MyBundledLambdaFunction.zip

创建 Cloudformation

将代码库中的 cw_sns_athena_lambda_s3.yaml 上传到 Cloudformation。需要填写的参数参考如下:

  • DoCreateExampleDashboard:会创建一个测试用的 Dashboard,里面包含简单的查询语句
  • EventBridgeCron:触发器规则
  • S3BacketName:上面步骤中的 S3BacketName
  • S3KeyName:上面步骤中的 S3KeyName
  • SNSEmailAddress:接受邮件地址

后面只需要点击下一步则会开始创建整个服务。

堆栈创建完毕后,会在你注册邮箱中发送一个订阅邮件,需要点击确认。

测试

当堆栈创建完毕后,内部自带了直接可以测试的场景:检测 200 或 304 的请求是否超过了 1000

注意:这个可以在配置文件中修改。

手动测试

找到生成的 lambda 程序,直接执行即可

自动测试

由于我们在 Cloudformation 配置的 EventBridge 间隔,比如每天 20 点自动跑一次, 可以找到对应的 EventBridge:

CloudWatch

在 CloudWatch 的 dashboard 界面,可以找到自定义面板,其内容包括了具体的 athena 语句,执行结果,以及 metricData 的图标。

在告警界面,可以看到 5 分钟内监控的数据值超过了 1000。

最后我们可以去注册的邮箱看下是否有收到告警邮件即可。

成本预估

举例:1 个 CDN,1 个指标,1GB 日志量,每 5分 钟监控一次,成本计算如下:

Cloudwatch Metrics:0.3$/月

  • 1 个指标,每月单价 3$

Cloudwatch API:12 * 24 * 30 * 2 * 0.01 / 1000 = 0.173

  • API 单价为每 1000 次 0.01$,两个 API PutMetricData 和 ListDashboards
  • 每月 API 次数:12 * 24 * 30 * 2

Cloudwatch Alarm:0.1$/月

  • 1 个告警,每月单价 1$

Cloudwatch 每月费用合计:0.3+0.173+0.1 = 0.573

Athena 每月费用:1 * 12 * 24 * 30 * 5/1024 = 42.1875

  • 扫描数据,每 TB 费用为 5.00$

成本总计:0.573 + 42.1875 = 42.76$/每月

整套方案的成本主要集中在 Athena 扫描数据。为了控制每次查询的扫描数据量,可以使用 S3 的生命周期策略,对历史日志进行过期操作,确保 Athena 只扫描当天或者最近几天的数据,这样可以进一步控制 Athena 的成本。

总结

目前该项目处于“脚手架”阶段,并与成熟的日志分析解决方案相比存在一些局限性。例如,目前仅支持指标的统计查询,而实际环境中的统计需求可能更加复杂。此外,它也依赖于在 Athena 中建立的日志表格。

该项目具备以下能力:

  • 提供 CloudWatch 的图表功能,可以进行数据可视化展示。
  • 具备告警和通知功能,能够及时通知相关人员。
  • 支持配置文件集中管理多个查询语句,方便进行日志分析。

除了以上特点之外,该方案适用于 CDN 日志、WAF 日志或其他类型的日志,只要日志具有固定格式且可以放置在 S3 存储桶中,即可建立相应的日志分析流程。此外,方案提供了配置文件,使客户能够自定义所需的查询场景。如果某些功能不需要开启,开发者们还可以对项目进行改造。最后,在通知方面,尽管展示了邮件通知的部分,开发者们也可以将其扩展到常用的即时通讯工具。

参考

本篇作者

万曦

亚马逊云科技解决方案架构师,负责基于亚马逊云科技的云计算方案的咨询和架构设计。坚实的 AWS Builder 文化拥抱者。拥有超过 12 年的游戏研发经验,参与过数个游戏项目的管理和开发,对于游戏行业有深度理解和见解。

付小飞

AWS 资深解决方案架构师,负责基于 AWS 的云计算方案的咨询与架构设计。专注于游戏行业,帮助客户利用 AWS 全球基础设施与强大的技术能力打造爆款游戏,降低游戏运行成本。