Use Cases

Claude Code × AWS CloudWatch 完整指南 | 日志分析·告警设置·仪表盘自动构建

用 Claude Code 提升 AWS CloudWatch 效率。包含日志模式分析、自动告警配置、指标仪表盘构建及故障排查的实战代码解析。

“生产环境报错了!但日志太多,根本不知道从哪里开始看。” —— 这是故障响应中最常见的慌乱时刻。

CloudWatch 是 AWS 的标准监控服务,但海量日志往往让关键信息被淹没,告警配置也容易被一拖再拖。我在工作中监控 ECS + Lambda 系统,通过让 Claude Code 读取日志来定位原因,将平均故障响应时间缩短了 40%。

本文将详细介绍如何用 Claude Code 自动化 CloudWatch 的日志分析、告警设计和仪表盘构建。


CloudWatch 核心组件

CloudWatch Logs      : 存储和搜索应用及 AWS 服务的日志
CloudWatch Metrics   : CPU 使用率、请求数等数值数据
CloudWatch Alarms    : 检测指标阈值超限并通知 SNS 等
CloudWatch Dashboards: 可视化指标和日志的自定义界面
Log Insights         : 类 SQL 的日志分析查询引擎

Step 1:让 Claude Code 负责日志模式分析

故障发生时,首先要掌握”错误日志的规律”。

# 获取最近 1 小时的错误日志
aws logs filter-log-events \
  --log-group-name "/ecs/myapp" \
  --start-time $(date -d "1 hour ago" +%s000) \
  --filter-pattern "ERROR" \
  --output json > error-logs.json

claude -p "
分析以下 CloudWatch 错误日志:

1. 按类型分类错误(5xx、4xx、DB 连接错误、超时等)
2. 找出频率最高的错误
3. 定位错误急剧增加的时间点
4. 提出根本原因假设
5. 建议下一步排查行动

$(cat error-logs.json | head -500)
"

自动生成 Log Insights 查询

claude -p "
为以下目的生成 CloudWatch Log Insights 查询:

1. 过去 1 小时各端点的错误率(前 10 名)
2. 延迟超过 500ms 的请求详情
3. 特定用户(user_id: 12345)的所有操作日志
4. 部署后 30 分钟内首次出现的错误

日志格式:JSON(timestamp, level, message, user_id, endpoint, duration_ms, status_code)
"

生成的 Log Insights 查询示例:

-- 各端点错误率
fields @timestamp, endpoint, status_code
| filter status_code >= 400
| stats count() as error_count by endpoint
| sort error_count desc
| limit 10

-- 延迟超过 500ms 的请求
fields @timestamp, endpoint, duration_ms, user_id
| filter duration_ms > 500
| sort duration_ms desc
| limit 50

-- 特定用户的操作日志
fields @timestamp, level, message, endpoint
| filter user_id = "12345"
| sort @timestamp desc
| limit 100

Step 2:自动生成告警配置

claude -p "
为以下系统设计全套 CloudWatch 告警。
用 CDK TypeScript 实现。

【系统架构】
- ECS Fargate(API 服务器,2~10 台)
- RDS PostgreSQL
- ALB(Application Load Balancer)
- Lambda(批处理)

【告警要求】
- 生产环境:5 分钟内触发的告警
- 通知目标:SNS → Slack 和 PagerDuty
- 分级告警(Warning/Critical 两级)
- 非业务时间仅通知 Critical
"
// lib/monitoring-stack.ts
import * as cdk from "aws-cdk-lib";
import * as cloudwatch from "aws-cdk-lib/aws-cloudwatch";
import * as actions from "aws-cdk-lib/aws-cloudwatch-actions";
import * as sns from "aws-cdk-lib/aws-sns";

export class MonitoringStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const alertTopic = sns.Topic.fromTopicArn(
      this, "AlertTopic",
      `arn:aws:sns:${this.region}:${this.account}:prod-alerts`
    );
    const warnTopic = sns.Topic.fromTopicArn(
      this, "WarnTopic",
      `arn:aws:sns:${this.region}:${this.account}:prod-warnings`
    );

    // ALB 5xx 错误率告警
    const alb5xxAlarm = new cloudwatch.Alarm(this, "Alb5xxAlarm", {
      alarmName: "prod-alb-5xx-critical",
      alarmDescription: "ALB 5xx 错误率超过 5%",
      metric: new cloudwatch.Metric({
        namespace: "AWS/ApplicationELB",
        metricName: "HTTPCode_Target_5XX_Count",
        dimensionsMap: { LoadBalancer: "app/myapp/xxx" },
        statistic: "Sum",
        period: cdk.Duration.minutes(5),
      }),
      threshold: 10,
      evaluationPeriods: 2,
      comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
      treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
    });
    alb5xxAlarm.addAlarmAction(new actions.SnsAction(alertTopic));

    // ECS CPU 使用率告警(Warning/Critical)
    const ecsCpuWarning = new cloudwatch.Alarm(this, "EcsCpuWarning", {
      alarmName: "prod-ecs-cpu-warning",
      metric: new cloudwatch.Metric({
        namespace: "AWS/ECS",
        metricName: "CPUUtilization",
        dimensionsMap: { ClusterName: "myapp-cluster", ServiceName: "myapp-service" },
        statistic: "Average",
        period: cdk.Duration.minutes(5),
      }),
      threshold: 70,
      evaluationPeriods: 3,
    });
    ecsCpuWarning.addAlarmAction(new actions.SnsAction(warnTopic));

    const ecsCpuCritical = new cloudwatch.Alarm(this, "EcsCpuCritical", {
      alarmName: "prod-ecs-cpu-critical",
      metric: new cloudwatch.Metric({
        namespace: "AWS/ECS",
        metricName: "CPUUtilization",
        dimensionsMap: { ClusterName: "myapp-cluster", ServiceName: "myapp-service" },
        statistic: "Average",
        period: cdk.Duration.minutes(5),
      }),
      threshold: 90,
      evaluationPeriods: 2,
    });
    ecsCpuCritical.addAlarmAction(new actions.SnsAction(alertTopic));

    // RDS 连接数告警
    const rdsConnectionAlarm = new cloudwatch.Alarm(this, "RdsConnectionAlarm", {
      alarmName: "prod-rds-connections-critical",
      metric: new cloudwatch.Metric({
        namespace: "AWS/RDS",
        metricName: "DatabaseConnections",
        dimensionsMap: { DBInstanceIdentifier: "myapp-db" },
        statistic: "Maximum",
        period: cdk.Duration.minutes(5),
      }),
      threshold: 80,  // db.t3.micro 最大连接数的 80%
      evaluationPeriods: 2,
    });
    rdsConnectionAlarm.addAlarmAction(new actions.SnsAction(alertTopic));

    // Lambda 错误率告警
    const lambdaErrorAlarm = new cloudwatch.Alarm(this, "LambdaErrorAlarm", {
      alarmName: "prod-lambda-errors-critical",
      metric: new cloudwatch.Metric({
        namespace: "AWS/Lambda",
        metricName: "Errors",
        dimensionsMap: { FunctionName: "myapp-batch" },
        statistic: "Sum",
        period: cdk.Duration.minutes(15),
      }),
      threshold: 5,
      evaluationPeriods: 1,
    });
    lambdaErrorAlarm.addAlarmAction(new actions.SnsAction(alertTopic));
  }
}

Step 3:自动生成自定义仪表盘

claude -p "
用 CDK 生成展示以下信息的 CloudWatch 仪表盘。

【仪表盘结构】
第 1 行:系统整体健康(ALB 请求数、5xx 率、延迟 P50/P95/P99)
第 2 行:ECS 服务(CPU、内存、运行任务数)
第 3 行:RDS(连接数、延迟、CPU 使用率)
第 4 行:Lambda(执行次数、错误数、执行时间)
第 5 行:业务指标(新注册数、支付成功率)← 自定义指标
"
// 仪表盘定义(节选)
const dashboard = new cloudwatch.Dashboard(this, "AppDashboard", {
  dashboardName: "myapp-production",
});

dashboard.addWidgets(
  new cloudwatch.Row(
    new cloudwatch.GraphWidget({
      title: "ALB 请求数",
      left: [new cloudwatch.Metric({
        namespace: "AWS/ApplicationELB",
        metricName: "RequestCount",
        statistic: "Sum",
        period: cdk.Duration.minutes(1),
      })],
      width: 8,
    }),
    new cloudwatch.GraphWidget({
      title: "ALB 5xx 错误率 (%)",
      left: [new cloudwatch.MathExpression({
        expression: "5xx / (2xx + 3xx + 4xx + 5xx) * 100",
        usingMetrics: {
          "5xx": new cloudwatch.Metric({ metricName: "HTTPCode_Target_5XX_Count", namespace: "AWS/ApplicationELB", statistic: "Sum" }),
          "2xx": new cloudwatch.Metric({ metricName: "HTTPCode_Target_2XX_Count", namespace: "AWS/ApplicationELB", statistic: "Sum" }),
          "3xx": new cloudwatch.Metric({ metricName: "HTTPCode_Target_3XX_Count", namespace: "AWS/ApplicationELB", statistic: "Sum" }),
          "4xx": new cloudwatch.Metric({ metricName: "HTTPCode_Target_4XX_Count", namespace: "AWS/ApplicationELB", statistic: "Sum" }),
        },
        period: cdk.Duration.minutes(1),
      })],
      width: 8,
    }),
  )
);

Step 4:让 Claude Code 负责故障排查

claude -p "
我想排查一个生产故障。请执行以下命令并分析结果:

1. aws logs filter-log-events --log-group-name '/ecs/myapp' \
   --start-time \$(date -d '2 hours ago' +%s000) \
   --filter-pattern 'ERROR' --limit 100

2. aws cloudwatch get-metric-statistics \
   --namespace AWS/ApplicationELB \
   --metric-name HTTPCode_Target_5XX_Count \
   --start-time \$(date -d '2 hours ago' -u +%Y-%m-%dT%H:%M:%SZ) \
   --end-time \$(date -u +%Y-%m-%dT%H:%M:%SZ) \
   --period 300 --statistics Sum

根据以上结果,请总结:
- 故障开始时间
- 受影响用户数(估算)
- 根本原因假设(TOP3)
- 立即响应措施
"

Step 5:自动设计自定义指标

claude -p "
用 Node.js(AWS SDK v3)生成将以下电商业务 KPI 作为 CloudWatch 自定义指标进行采集的代码。

采集指标:
- 支付成功数·失败数(每 1 分钟)
- 购物车放弃率(每 5 分钟)
- 新会员注册数(每 1 小时)

命名空间:MyApp/Business
为每个指标添加环境标签(Production/Staging)
"
// src/monitoring/business-metrics.ts
import { CloudWatchClient, PutMetricDataCommand } from "@aws-sdk/client-cloudwatch";

const cw = new CloudWatchClient({ region: process.env.AWS_REGION });
const NAMESPACE = "MyApp/Business";
const ENV = process.env.NODE_ENV ?? "development";

export async function recordPaymentSuccess() {
  await cw.send(new PutMetricDataCommand({
    Namespace: NAMESPACE,
    MetricData: [{
      MetricName: "PaymentSuccess",
      Value: 1,
      Unit: "Count",
      Dimensions: [{ Name: "Environment", Value: ENV }],
    }],
  }));
}

export async function recordPaymentFailure(reason: string) {
  await cw.send(new PutMetricDataCommand({
    Namespace: NAMESPACE,
    MetricData: [{
      MetricName: "PaymentFailure",
      Value: 1,
      Unit: "Count",
      Dimensions: [
        { Name: "Environment", Value: ENV },
        { Name: "Reason", Value: reason },
      ],
    }],
  }));
}

四大常见陷阱

1. 告警的 evaluationPeriods 设置过短

// ❌ 瞬间波峰也会立即触发告警
evaluationPeriods: 1,
threshold: 10,

// ✅ 连续 3 个周期超限才触发告警(减少误报)
evaluationPeriods: 3,
threshold: 10,
datapointsToAlarm: 2,  // 3 个周期中有 2 次超限时触发告警

2. 忽视 Log Insights 的费用

Log Insights 按扫描数据量计费。不限定时间范围运行查询可能产生意外费用。务必指定 --start-time--end-time

3. 自定义高分辨率指标成本高

标准指标(60 秒)免费,但高分辨率指标(1 秒)费用约为 10 倍。业务指标用 1 分钟聚合通常已足够。

4. 未为 Lambda 设置日志保留期

默认为”永不过期”,导致存储成本持续增加。请务必为日志组设置保留期。

new logs.LogGroup(this, "AppLogGroup", {
  logGroupName: "/ecs/myapp",
  retention: logs.RetentionDays.ONE_MONTH,  // 30 天后自动删除
});

总结

任务Claude Code 的贡献
日志分析读取错误日志,提出根本原因假设和应对措施
Log Insights 查询只需描述分析目的即可生成查询
告警设置描述系统架构即可批量生成 CDK 代码
仪表盘描述展示需求即可生成组件定义
故障排查执行 AWS CLI 命令并分析结果

“监控等会儿再配置吧” —— 结果故障来临时一片黑暗。使用 Claude Code,30 分钟内即可搭建生产级别的告警和仪表盘

相关文章

参考资料

#claude-code #aws #cloudwatch #monitoring #observability #devops

让你的 Claude Code 工作流更上一层楼

50 个经过实战检验的提示词模板,现在就能复制粘贴到 Claude Code 中使用。

免费

免费 PDF:5 分钟看懂 Claude Code 速查表

只需留下邮箱,我们就会立即把这份 A4 一页速查表 PDF 发送给你。

我们会严格保护你的个人信息,绝不发送垃圾邮件。

Masa

本文作者

Masa

深度使用 Claude Code 的工程师。运营 claudecode-lab.com——一个涵盖 10 种语言、超过 2,000 页内容的科技媒体。