
Amazon CloudWatch 是 AWS 提供的全托管监控和可观测性平台,统一处理指标(Metrics)、日志(Logs)和告警(Alarms)三类数据。
EC2 实例、RDS 数据库、Lambda 函数、ECS 容器、S3 存储桶等 70 多个 AWS 服务的标准指标自动流入 CloudWatch,不需要安装任何 Agent 也不需要任何配置,这些标准指标永久免费。
CloudWatch 在生产环境中的价值体现在两个方向:一是主动监控,通过告警在问题发生时第一时间通知运维团队;二是被动排查,通过日志分析和指标历史数据定位问题的触发时间和原因。两者配合使用,才能构建完整的生产环境可观测体系。
指标监控:内置指标与自定义指标
内置指标(永久免费)
AWS 服务的标准指标自动发布到 CloudWatch,常用的内置指标包括:
EC2 的 CPU 使用率(CPUUtilization)、网络进出流量(NetworkIn/NetworkOut)、磁盘读写 IO(DiskReadOps/DiskWriteOps)、状态检查(StatusCheckFailed)。
RDS 的数据库连接数(DatabaseConnections)、CPU 使用率、可用存储空间(FreeStorageSpace)、读写延迟(ReadLatency/WriteLatency)。
Lambda 的调用次数(Invocations)、报错次数(Errors)、执行时长(Duration)、并发执行数(ConcurrentExecutions)。
这些指标在 CloudWatch 控制台的「所有指标」页面直接查看,按服务和维度分层组织。指标数据默认保留 15 个月,超过 15 天的数据以较低粒度存储(1 分钟精度 → 5 分钟精度 → 1 小时精度),不影响长期趋势分析,但无法查看 15 天前的分钟级细节。
自定义指标
内置指标无法覆盖应用层的业务指标,例如每分钟的订单量、支付成功率、缓存命中率。通过 AWS CLI 或 SDK 发布自定义指标到 CloudWatch:
# 发布一条自定义指标:当前队列中的待处理订单数
aws cloudwatch put-metric-data \
–namespace “MyApp/Orders” \
–metric-name “PendingOrders” \
–value 142 \
–unit Count \
–dimensions Service=payment,Environment=production \
–region ap-east-1
用 Python 批量发布多条自定义指标:
import boto3
cloudwatch = boto3.client(‘cloudwatch’, region_name=’ap-east-1′)
cloudwatch.put_metric_data(
Namespace=’MyApp/Performance’,
MetricData=[
{
‘MetricName’: ‘RequestLatency’,
‘Value’: 245.5,
‘Unit’: ‘Milliseconds’,
‘Dimensions’: [
{‘Name’: ‘Service’, ‘Value’: ‘api-gateway’},
{‘Name’: ‘Environment’, ‘Value’: ‘production’}
]
},
{
‘MetricName’: ‘ErrorRate’,
‘Value’: 0.02,
‘Unit’: ‘Percent’,
‘Dimensions’: [
{‘Name’: ‘Service’, ‘Value’: ‘api-gateway’},
{‘Name’: ‘Environment’, ‘Value’: ‘production’}
]
}
]
)
自定义指标按每个指标每月 $0.30 计费(前 10 个免费,超出后前 10,000 个 $0.30/个/月)。指标的”维度”(Dimensions)组合直接决定指标数量——如果为每个用户 ID 创建一个维度,10 万用户就是 10 万条自定义指标,月费 $3 万。设计自定义指标时应控制维度的基数,用枚举值(Service 名称、Environment 类型)而不是高基数值(用户 ID、会话 ID)作为维度。
CloudWatch Agent:EC2 内存和磁盘监控
EC2 的内置指标有一个容易被忽视的缺失:CloudWatch 默认不采集 EC2 实例的内存使用率和磁盘空间占用率。内存和磁盘属于操作系统层面的数据,CloudWatch 从外部无法直接读取,必须在实例内部安装 CloudWatch Agent 才能采集。
在 Amazon Linux 2 上安装并配置 CloudWatch Agent:
# 安装 CloudWatch Agent
sudo yum install amazon-cloudwatch-agent -y
# 使用向导生成配置文件
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
# 或者直接创建配置文件
sudo cat > /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json << ‘EOF’
{
“metrics”: {
“namespace”: “CWAgent”,
“metrics_collected”: {
“mem”: {
“measurement”: [“mem_used_percent”],
“metrics_collection_interval”: 60
},
“disk”: {
“measurement”: [“disk_used_percent”],
“resources”: [“/”, “/data”],
“metrics_collection_interval”: 60
}
}
}
}
EOF
# 启动 Agent
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config \
-m ec2 \
-c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json \
-s
Agent 配置完成后,mem_used_percent 和 disk_used_percent 作为自定义指标发布到 CloudWatch,按自定义指标费率计费($0.30/指标/月)。对于需要监控内存和磁盘的 EC2 实例,这是必须的配置步骤,否则内存打满导致应用崩溃时,CloudWatch 告警无法提前发出预警。关于 EC2 实例规格和资源配置,可以参考 AWS EC2 实例类型 选择指南。
告警配置
CloudWatch 告警在指标达到阈值时触发通知或自动操作,是生产环境异常响应的核心机制。告警可以通过 SNS 发送邮件、短信或触发 Lambda 函数,也可以直接触发 EC2 Auto Scaling 扩缩容动作。
创建 EC2 CPU 告警
# 创建告警:EC2 实例 CPU 超过 80% 持续 2 个 5 分钟周期触发
aws cloudwatch put-metric-alarm \
–alarm-name “ec2-cpu-high” \
–alarm-description “EC2 CPU usage exceeds 80%” \
–metric-name CPUUtilization \
–namespace AWS/EC2 \
–statistic Average \
–period 300 \
–evaluation-periods 2 \
–threshold 80 \
–comparison-operator GreaterThanThreshold \
–dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
–alarm-actions arn:aws:sns:ap-east-1:123456789012:ops-alerts \
–ok-actions arn:aws:sns:ap-east-1:123456789012:ops-alerts \
–treat-missing-data breaching \
–region ap-east-1
–evaluation-periods 2 表示连续 2 个周期(共 10 分钟)都超过阈值才触发告警,避免短暂的 CPU 峰值产生误报。–treat-missing-data breaching 表示当指标数据缺失时,把告警状态视为 ALARM,这适合监控关键实例——实例如果宕机就不会上报指标,数据缺失本身就是异常信号。
告警的三种状态
告警始终处于三种状态之一:OK(指标正常,未超阈值)、ALARM(指标超阈值,告警已触发)、INSUFFICIENT_DATA(指标数据不足,无法评估)。合理配置 –ok-actions 让告警恢复正常时也发送通知,这样运维团队能知道问题已经自动恢复,不需要持续跟进。
CloudWatch Logs:日志采集与分析
日志组和日志流
CloudWatch Logs 以日志组(Log Group)和日志流(Log Stream)组织日志数据。每个日志组对应一类日志源,例如 /aws/lambda/my-function 是 Lambda 函数的日志组,/ecs/my-service 是 ECS 服务的日志组。日志流是日志组内的时序日志序列,通常每个实例或容器对应一个独立的日志流。
必须配置的日志组保留时长: 日志组默认保留时长为”永不过期”,意味着存储成本会随时间无限积累。生产环境日志按业务需要设置保留时长(通常 30–90 天),调试和开发环境日志设 7 天。修改保留时长:
# 将日志组保留时长设为 30 天
aws logs put-retention-policy \
–log-group-name “/aws/lambda/my-function” \
–retention-in-days 30 \
–region ap-east-1
不设置保留时长是 CloudWatch 最常见的成本浪费来源,一个没有配置保留时长的日志组在高流量服务下可能一年积累数 TB 的存储,按 $0.03/GB/月计算会产生持续增长的费用。
日志类型:Standard vs Infrequent Access
2026 年初 CloudWatch Logs 新增了 Infrequent Access(IA)日志类,写入费用为 $0.25/GB,比 Standard 类的 $0.50/GB 便宜一半,且同样支持完整的 Logs Insights 查询功能。对于不需要实时指标过滤或 Live Tail 的应用日志,IA 类应该成为默认选择,能直接将日志写入成本减半。
Logs Insights 查询
Logs Insights 提供对日志数据的 SQL 风格查询,按实际扫描的 GB 量计费($0.005/GB),支持在控制台实时查询,也支持通过 CLI 或 API 执行。
# 统计过去 1 小时内的 Lambda 报错次数,按错误类型分组
filter @message like /ERROR/
| parse @message “* Error: *” as timestamp, errorMessage
| stats count(*) as errorCount by errorMessage
| sort errorCount desc
| limit 20
# 分析 API 响应时间分布
filter @type = “REPORT”
| parse @message “Duration: * ms” as duration
| stats
avg(duration) as avgDuration,
percentile(duration, 95) as p95,
percentile(duration, 99) as p99
by bin(5m)
控制查询成本的关键是缩短时间范围和提前过滤。将时间范围从”过去 7 天”改为”过去 1 小时”,扫描量从数百 GB 降到数 GB,查询成本降低 100 倍以上。查询前先用 filter 条件缩小范围,再做聚合统计。
Container Insights:ECS 和 EKS 容器监控
Container Insights 为 ECS 和 EKS 集群提供容器级别的监控,采集集群、节点、Pod 和容器维度的 CPU、内存、网络、磁盘指标,以及 Pod 重启次数、容器镜像拉取时间等 Kubernetes 运行状态数据。
Container Insights 通过 CloudWatch Agent 以 DaemonSet 形式部署在每个节点上,采集的数据以自定义指标形式发布到 CloudWatch。Container Insights 的成本非常显著,必须在启用前充分评估:
一个 10 节点的 EKS 集群,每个节点发布约 20 个指标,月度 Container Insights 指标费用约 $2,190(1,000 个自定义指标 × $0.30/月 × 7.3 小时成本乘数),这个数字可能超过集群本身的节点计算成本。关于 ECS 集群的完整配置,可以参考 AWS ECS 完整教程的集群监控部分。
合理控制 Container Insights 成本的实践:只在生产集群上开启 Container Insights,开发和测试集群使用基础的免费 CloudWatch 指标;大规模 EKS 集群考虑使用 Prometheus + Grafana 的自托管方案替代 Container Insights,一次性设置成本换取长期的显著节省。
Dashboard:集中展示多服务指标
CloudWatch Dashboard 将多个指标图表组合到一个页面,方便运维团队统一查看系统状态。每个账号有 3 个免费 Dashboard(每个最多 50 个指标),超出后每个 Dashboard 每月 $3。
用 CLI 创建一个包含 EC2 CPU 和 RDS 连接数的 Dashboard:
aws cloudwatch put-dashboard \
–dashboard-name “production-overview” \
–dashboard-body ‘{
“widgets”: [
{
“type”: “metric”,
“properties”: {
“title”: “EC2 CPU 使用率”,
“metrics”: [
[“AWS/EC2”, “CPUUtilization”, “InstanceId”, “i-1234567890abcdef0”]
],
“period”: 300,
“stat”: “Average”,
“view”: “timeSeries”
}
},
{
“type”: “metric”,
“properties”: {
“title”: “RDS 数据库连接数”,
“metrics”: [
[“AWS/RDS”, “DatabaseConnections”, “DBInstanceIdentifier”, “my-db”]
],
“period”: 300,
“stat”: “Average”,
“view”: “timeSeries”
}
}
]
}’ \
–region ap-east-1
计费方式与成本控制
CloudWatch 的月度费用由多个计费项叠加,小规模环境月费 $30–80,中等规模 $200–600,大型环境开启 Container Insights 和大量自定义指标后可以超过 $2,000–5,000。以下是最直接的成本控制方法:
立即生效的操作: 为所有日志组设置保留时长(30 天通常足够日常排查),这一步能阻止存储成本无限增长。用 CLI 批量查找没有保留策略的日志组:
aws logs describe-log-groups \
–query ‘logGroups[?retentionInDays==`null`].logGroupName’ \
–region ap-east-1
日志类型选择: 不需要实时指标过滤的应用日志改用 Infrequent Access 类,直接节省 50% 的写入费用。
自定义指标维度控制: 避免用高基数值(用户 ID、请求 ID)作为指标维度,每个唯一维度组合都是一条独立的自定义指标,高基数维度会让指标数量爆炸。
Container Insights 按需开启: 只在生产集群开启,开发和测试集群关闭,显著减少自定义指标数量和对应的月度费用。
账号开通与代理充值
使用 CloudWatch 需要有效的 AWS 账号,CloudWatch 本身不需要单独开通,随 AWS 账号自动启用。通过 亚马逊云账号出售 渠道获取的高权重账号,账单中 CloudWatch 等监控产品同样享受代理商折扣,1 分钟交付,免实名免绑卡。
月均 AWS 综合消耗较高的团队,通过 亚马逊云代理商 充值可以享受低至 7 折的代理专属折扣,CloudWatch 的日志写入费、指标费和告警费同样适用,付款支持 USDT 和对公转账,年度实际监控成本明显低于官网直充。


