mcpField
C
cloudwatch

cloudwatch

github.com/itsmostafa云与 DevOps1.2k243 次安装2 天前更新
代码仓库

关于 cloudwatch

AWS CloudWatch 技能资料为监控 AWS 资源和应用的开发者与运维人员提供操作参考,涵盖指标、日志、告警与仪表板。内容包含 AWS CLI 和 boto3 示例,以及配置建议和故障排查方法。

主要功能

  1. 01发布和查询指标
  2. 02搜索日志并运行 Insights 查询
  3. 03配置指标与日志告警
  4. 04创建仪表板和指标筛选器
  5. 05告警、日志及成本排查

适用场景

  1. 01监控 EC2 或 Lambda 指标
  2. 02查询应用日志中的错误
  3. 03为阈值或日志查询设置告警
  4. 04诊断缺失指标或告警状态异常

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/itsmostafa/aws-agent-skills --skill cloudwatch

安装后在 Claude Code 中输入/cloudwatch确认已加载。

附带文件alarms-metrics.md

详细介绍

AWS CloudWatch

Amazon CloudWatch 为 AWS 资源和应用程序提供监控和可观测性。它会收集指标、日志和事件,让你能够监控、排查问题并优化 AWS 环境。

目录

核心概念

指标

按时间排序并发布到 CloudWatch 的数据点。主要组成部分:

  • 命名空间:指标的容器(例如,AWS/Lambda)
  • 指标名称:测量项的名称(例如,Invocations)
  • 维度:用于筛选的名称-值对(例如,FunctionName=MyFunc)
  • 统计数据:聚合值(Sum、Average、Min、Max、SampleCount、pN)
日志

来自 AWS 服务和应用程序的日志数据:

  • 日志组:日志流的集合
  • 日志流:来自同一来源的一系列日志事件
  • 日志事件:包含时间戳和消息的单条日志记录
警报

根据指标阈值执行的自动化操作:

  • 状态:OK、ALARM、INSUFFICIENT_DATA
  • 操作:SNS 通知、Lambda 函数、Auto Scaling、EC2 操作、Systems Manager OpsItems
  • 类型:指标(包括指标数学、异常检测、Metrics Insights)、复合、日志(计划执行的 Logs Insights 查询,按查询结果进行 M-out-of-N 评估)
  • 静默规则:在计划时段内静默操作,同时警报仍会持续评估

常见模式

创建指标警报

AWS CLI:

# CPU utilization alarm for EC2
aws cloudwatch put-metric-alarm \
  --alarm-name "HighCPU-i-1234567890abcdef0" \
  --metric-name CPUUtilization \
  --namespace AWS/EC2 \
  --statistic Average \
  --period 300 \
  --threshold 80 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 2 \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:alerts \
  --ok-actions arn:aws:sns:us-east-1:123456789012:alerts

boto3:

import boto3

cloudwatch = boto3.client('cloudwatch')

cloudwatch.put_metric_alarm(
    AlarmName='HighCPU-i-1234567890abcdef0',
    MetricName='CPUUtilization',
    Namespace='AWS/EC2',
    Statistic='Average',
    Period=300,
    Threshold=80.0,
    ComparisonOperator='GreaterThanThreshold',
    EvaluationPeriods=2,
    Dimensions=[
        {'Name': 'InstanceId', 'Value': 'i-1234567890abcdef0'}
    ],
    AlarmActions=['arn:aws:sns:us-east-1:123456789012:alerts'],
    OKActions=['arn:aws:sns:us-east-1:123456789012:alerts']
)
Lambda 错误率警报
aws cloudwatch put-metric-alarm \
  --alarm-name "LambdaErrorRate-MyFunction" \
  --metrics '[
    {
      "Id": "errors",
      "MetricStat": {
        "Metric": {
          "Namespace": "AWS/Lambda",
          "MetricName": "Errors",
          "Dimensions": [{"Name": "FunctionName", "Value": "MyFunction"}]
        },
        "Period": 60,
        "Stat": "Sum"
      },
      "ReturnData": false
    },
    {
      "Id": "invocations",
      "MetricStat": {
        "Metric": {
          "Namespace": "AWS/Lambda",
          "MetricName": "Invocations",
          "Dimensions": [{"Name": "FunctionName", "Value": "MyFunction"}]
        },
        "Period": 60,
        "Stat": "Sum"
      },
      "ReturnData": false
    },
    {
      "Id": "errorRate",
      "Expression": "errors/invocations*100",
      "Label": "Error Rate",
      "ReturnData": true
    }
  ]' \
  --threshold 5 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 3 \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:alerts
使用 Insights 查询日志
# Find errors in Lambda logs
aws logs start-query \
  --log-group-name /aws/lambda/MyFunction \
  --start-time $(date -d '1 hour ago' +%s) \
  --end-time $(date +%s) \
  --query-string '
    fields @timestamp, @message
    | filter @message like /ERROR/
    | sort @timestamp desc
    | limit 50
  '

# Get query results
aws logs get-query-results --query-id <query-id>

boto3:

import boto3
import time

logs = boto3.client('logs')

# Start query
response = logs.start_query(
    logGroupName='/aws/lambda/MyFunction',
    startTime=int(time.time()) - 3600,
    endTime=int(time.time()),
    queryString='''
        fields @timestamp, @message
        | filter @message like /ERROR/
        | sort @timestamp desc
        | limit 50
    '''
)

query_id = response['queryId']

# Wait for results
while True:
    result = logs.get_query_results(queryId=query_id)
    if result['status'] == 'Complete':
        break
    time.sleep(1)

for row in result['results']:
    print(row)
创建指标筛选器

从日志模式中提取指标:

# Create metric filter for error count
aws logs put-metric-filter \
  --log-group-name /aws/lambda/MyFunction \
  --filter-name ErrorCount \
  --filter-pattern "ERROR" \
  --metric-transformations \
    metricName=ErrorCount,metricNamespace=MyApp,metricValue=1,defaultValue=0
创建日志警报

直接对 Logs Insights 查询创建警报(无需指标筛选器)。CloudWatch 会创建并管理底层的计划查询。ScheduledQueryRoleARN 角色必须信任 logs.amazonaws.com,并允许对日志组 ARN 执行 logs:StartQuery 和 logs:GetQueryResults,同时允许对 "Resource": "*" 执行 logs:StopQuery 和 logs:DescribeLogGroups(这两项不支持资源级权限,因此限定日志组的语句永远不会匹配)。

# ALARM when >100 errors in 3 of the last 5 query runs
aws cloudwatch put-log-alarm \
  --alarm-name "HighErrorCount" \
  --comparison-operator GreaterThanThreshold \
  --threshold 100 \
  --query-results-to-evaluate 5 \
  --query-results-to-alarm 3 \
  --treat-missing-data notBreaching \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:alerts \
  --scheduled-query-configuration '{
    "QueryString": "fields @timestamp, @message | filter @message like /ERROR/",
    "LogGroupIdentifiers": ["/aws/lambda/MyFunction"],
    "ScheduledQueryRoleARN": "arn:aws:iam::123456789012:role/ScheduledQueryRole",
    "AggregationExpression": "count(*)",
    "ScheduleConfiguration": {
      "ScheduleExpression": "rate(10 minutes)",
      "StartTimeOffset": 600
    }
  }'

# Log alarms are omitted from describe-alarms unless requested
aws cloudwatch describe-alarms --alarm-types LogAlarm
发布自定义指标
import boto3

cloudwatch = boto3.client('cloudwatch')

cloudwatch.put_metric_data(
    Namespace='MyApp',
    MetricData=[
        {
            'MetricName': 'OrdersProcessed',
            'Value': 1,
            'Unit': 'Count',
            'Dimensions': [
                {'Name': 'Environment', 'Value': 'Production'},
                {'Name': 'OrderType', 'Value': 'Standard'}
            ]
        }
    ]
)
创建控制面板
cat > dashboard.json << 'EOF'
{
  "widgets": [
    {
      "type": "metric",
      "x": 0, "y": 0, "width": 12, "height": 6,
      "properties": {
        "title": "Lambda Invocations",
        "metrics": [
          ["AWS/Lambda", "Invocations", "FunctionName", "MyFunction"]
        ],
        "period": 60,
        "stat": "Sum",
        "region": "us-east-1"
      }
    },
    {
      "type": "log",
      "x": 12, "y": 0, "width": 12, "height": 6,
      "properties": {
        "title": "Recent Errors",
        "query": "SOURCE '/aws/lambda/MyFunction' | filter @message like /ERROR/ | limit 20",
        "region": "us-east-1"
      }
    }
  ]
}
EOF

aws cloudwatch put-dashboard \
  --dashboard-name MyAppDashboard \
  --dashboard-body file://dashboard.json

CLI 参考

指标命令
命令描述
aws cloudwatch put-metric-data发布自定义指标
aws cloudwatch get-metric-data获取指标值
aws cloudwatch get-metric-statistics获取聚合统计数据
aws cloudwatch list-metrics列出可用指标
警报命令
命令描述
aws cloudwatch put-metric-alarm创建或更新警报
aws cloudwatch put-log-alarm创建或更新日志查询警报
aws cloudwatch describe-alarms列出警报(日志警报使用 --alarm-types LogAlarm)
aws cloudwatch describe-alarm-contributors显示多贡献者警报中触发警报的贡献者
aws cloudwatch put-alarm-mute-rule创建或更新计划静默时段
aws cloudwatch list-alarm-mute-rules列出静默规则(--statuses SCHEDULED ACTIVE EXPIRED)
aws cloudwatch delete-alarm-mute-rule删除静默规则(立即取消静默)
aws cloudwatch set-alarm-state手动设置警报状态
aws cloudwatch delete-alarms删除警报
日志命令
命令描述
aws logs create-log-group创建日志组
aws logs put-log-events写入日志事件
aws logs filter-log-events搜索日志事件
aws logs start-query启动 Insights 查询
aws logs put-metric-filter创建指标筛选器
aws logs put-retention-policy设置日志保留期限

最佳实践

指标
  • 合理使用维度 — 维度过多会导致指标激增
  • 发布前先进行聚合 — 批量处理自定义指标
  • 仅在需要时使用高分辨率指标(1 秒)
  • 为自定义指标设置有意义的单位
警报
  • 复杂条件使用复合警报
  • 设置恰当的评估周期,避免警报状态频繁切换
  • 包含 OK 操作,以跟踪恢复情况
  • 对动态阈值使用异常检测
  • 对基于查询的条件,使用日志警报,而不是指标筛选器 + 指标警报;对于稀疏错误,设置 --treat-missing-data notBreaching;对于检测停止到达的日志,设置为 breaching
  • 错开日志警报的计划时间 — 每个账户同时执行的计划查询上限为 100 个
  • 为与新资源同时创建的警报设置 --warm-up-configuration(1-2880 分钟),以避免指标发布前产生噪声
  • 对每日/每周批处理或备份警报使用 --evaluation-window WallClockWindow={Timezone=...};对 Auto Scaling 保持默认的滑动窗口
  • 维护期间使用静音规则,而不是 disable-alarm-actions;enable-alarm-actions 不会取消活动静音规则的静音状态
日志
  • 设置保留策略 — 不要永久保留日志
  • 使用结构化日志记录(JSON),以便更好地查询
  • 为关键事件创建指标筛选器
  • 使用 Contributor Insights 进行 Top-N 分析
成本优化
  • 删除未使用的控制面板
  • 缩短非关键日志的保留时间
  • 除非必要,否则避免使用高分辨率指标
  • 使用日志订阅筛选器,而不是轮询

故障排除

缺少指标

原因:

  • 服务尚未发布指标(等待 1-5 分钟)
  • 命名空间/维度错误
  • 未启用详细监控(EC2)

调试:

# List metrics for a namespace
aws cloudwatch list-metrics \
  --namespace AWS/Lambda \
  --dimensions Name=FunctionName,Value=MyFunction
警报卡在 INSUFFICIENT_DATA 状态

原因:

  • 未发布指标
  • 维度不匹配
  • 评估周期过短
  • 预热期仍在生效(数据填满窗口后会提前结束,除非 OnlyStartEvaluatingAfterWarmUpPeriodEnds=true)
  • 日志警报:刚创建/更新(查询、计划或日志组发生变更都会重置状态)、计划查询角色缺少权限(EvaluationState = EVALUATION_ERROR,请查看 StateReason),或摄取延迟(通过 EndTimeOffset 向后调整窗口)

调试:

# Check if metric has data
aws cloudwatch get-metric-statistics \
  --namespace AWS/Lambda \
  --metric-name Invocations \
  --dimensions Name=FunctionName,Value=MyFunction \
  --start-time $(date -d '1 hour ago' -u +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 60 \
  --statistics Sum

# Log alarm: check evaluation state and reason
aws cloudwatch describe-alarms --alarm-types LogAlarm --alarm-names HighErrorCount \
  --query 'LogAlarms[].[StateValue,EvaluationState,StateReason]'
日志事件未显示

原因:

  • 缺少 IAM 权限
  • CloudWatch Logs Agent 未运行
  • 日志组不存在

调试:

# Check log streams
aws logs describe-log-streams \
  --log-group-name /aws/lambda/MyFunction \
  --order-by LastEventTime \
  --descending \
  --limit 5
CloudWatch 成本过高

检查用量:

# Get PutLogEvents usage
aws cloudwatch get-metric-statistics \
  --namespace AWS/Logs \
  --metric-name IncomingBytes \
  --dimensions Name=LogGroupName,Value=/aws/lambda/MyFunction \
  --start-time $(date -d '7 days ago' -u +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 86400 \
  --statistics Sum

参考资料

评论

支持 Markdown