CloudWatch: Monitoring & Logs

CloudWatch collects metrics and logs from almost every AWS service automatically, and lets you set alarms that notify you — or trigger an automated response — the moment something looks wrong, instead of finding out from an angry user.

Metrics

Every EC2 instance, Lambda function, and RDS database already reports metrics (CPU utilization, invocation count, database connections) to CloudWatch with no setup required:

bash terminal
aws cloudwatch get-metric-statistics \
  --namespace AWS/EC2 --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=i-0a1b2c3d4e5f67890 \
  --start-time 2026-09-08T00:00:00Z --end-time 2026-09-08T01:00:00Z \
  --period 300 --statistics Average
Output (abridged)
{
    "Datapoints": [
        {"Timestamp": "2026-09-08T00:15:00Z", "Average": 12.4},
        {"Timestamp": "2026-09-08T00:20:00Z", "Average": 87.9}
    ]
}

Logs

CloudWatch Logs collects application and system output into log groups — Lambda functions, for instance, send everything printed during execution here automatically, with no configuration needed:

bash terminal
aws logs tail /aws/lambda/greet --since 10m
Output
2026-09-08T14:02:11 START RequestId: 8f3a2b1c
2026-09-08T14:02:11 Hello, Priya!
2026-09-08T14:02:11 END RequestId: 8f3a2b1c
2026-09-08T14:02:11 REPORT Duration: 4.21 ms  Billed Duration: 5 ms

Alarms

An alarm watches a metric and fires when it crosses a threshold you define — CPU above 90% for 5 minutes, error count above zero, database connections near the limit — and can notify you or trigger an automated action like adding more instances.

An alarm is only useful if something's actually listening: it's easy to create an alarm, wire it to an SNS topic, and forget to actually subscribe an email address or Slack webhook to that topic — leaving an alarm that fires silently forever. Test that a new alarm's notification path actually reaches you before you trust it.