CloudWatch Metrics and Alarms
CloudWatch Metrics and Alarms
Amazon CloudWatch provides monitoring and observability for AWS resources and applications.
Key Metrics
| Metric | Source | Description |
|---|---|---|
| CPUUtilization | EC2 | Percentage of CPU used |
| NetworkIn/Out | EC2 | Network traffic |
| StatusCheckFailed | EC2 | System/instance checks |
| Duration | Lambda | Execution time |
| Errors | Lambda | Failed invocations |
| ReadCapacityUnits | DynamoDB | Read consumption |
| DatabaseConnections | RDS | Active connections |
Create Alarms
# EC2 CPU alarm
aws cloudwatch put-metric-alarm \
--alarm-name High-CPU-Alarm \
--metric-name CPUUtilization \
--namespace AWS/EC2 \
--dimensions Name=InstanceId,Value=i-xxx \
--statistic Average \
--period 300 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 2 \
--alarm-actions arn:aws:sns:us-east-1:xxx:my-topic \
--ok-actions arn:aws:sns:us-east-1:xxx:my-topic
# Lambda error alarm
aws cloudwatch put-metric-alarm \
--alarm-name Lambda-Errors \
--metric-name Errors \
--namespace AWS/Lambda \
--dimensions Name=FunctionName,Value=my-function \
--statistic Sum \
--period 300 \
--threshold 5 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 1
Composite Alarms
aws cloudwatch put-metric-alarm \
--alarm-name Combined-Alarm \
--alarm-rule 'ALARM(High-CPU-Alarm) AND ALARM(High-Network-Alarm)'
CloudWatch Logs
CloudWatch Logs
Create Log Group
# Create log group
aws logs create-log-group --log-group-name /myapp/production
# Set retention
aws logs put-retention-policy \
--log-group-name /myapp/production \
--retention-in-days 90
# Delete old logs
aws logs delete-log-group --log-group-name /old-logs
CloudWatch Agent
{
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/app/error.log",
"log_group_name": "/myapp/errors",
"log_stream_name": "{instance_id}",
"timestamp_format": "%Y-%m-%d %H:%M:%S",
"timezone": "UTC"
}
]
}
}
},
"metrics": {
"namespace": "MyApp",
"metrics_collected": {
"disk": {
"measurement": ["used_percent"],
"metrics_collection_interval": 60
},
"mem": {
"measurement": ["mem_used_percent"],
"metrics_collection_interval": 60
}
}
}
}
# Install CloudWatch agent
sudo yum install -y amazon-cloudwatch-agent
# Start agent
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config \
-m ec2 \
-c file:/opt/aws/amazon-cloudwatch-agent/config.json \
-s
Logs Insights
# Query logs with Logs Insights
aws logs start-query \
--log-group-name /myapp/production \
--start-time $(date -d '1 hour ago' +%s)000 \
--end-time $(date +%s)000 \
--query-string '
fields @timestamp, @message
| filter @message like /ERROR/
| sort @timestamp desc
| limit 20
'
Log Metric Filters
# Create metric filter
aws logs put-metric-filter \
--log-group-name /myapp/production \
--filter-name error-count \
--filter-pattern '"ERROR"' \
--metric-transformations 'metricName=ErrorCount,metricNamespace=MyApp,metricValue=1'
CloudWatch Dashboards
CloudWatch Dashboards
Create Dashboard
# Create dashboard
aws cloudwatch put-dashboard \
--dashboard-name MyApp-Dashboard \
--dashboard-body '{
"widgets": [
{
"type": "metric",
"properties": {
"title": "EC2 CPU Utilization",
"metrics": [
["AWS/EC2", "CPUUtilization", "InstanceId", "i-xxx"]
],
"period": 300,
"stat": "Average",
"region": "us-east-1"
}
},
{
"type": "metric",
"properties": {
"title": "Lambda Invocations",
"metrics": [
["AWS/Lambda", "Invocations", "FunctionName", "my-function"]
],
"period": 300,
"stat": "Sum"
}
},
{
"type": "log",
"properties": {
"title": "Recent Errors",
"query": "fields @timestamp, @message | filter @message like /ERROR/ | sort @timestamp desc | limit 10",
"region": "us-east-1",
"stacked": false
}
}
]
}'
Dashboard Widget Types
| Type | Use Case |
|---|---|
| metric | CloudWatch metrics visualization |
| log | Logs Insights query results |
| text | Markdown text |
| alarm | Alarm status |
| number | Single number value |
| graph | Line or bar chart |
EventBridge
EventBridge (CloudWatch Events)
Event Rules
# Create a rule for EC2 state changes
aws events put-rule \
--name ec2-state-change \
--event-pattern '{
"source": ["aws.ec2"],
"detail-type": ["EC2 Instance State-change Notification"],
"detail": {
"state": ["stopped", "terminated"]
}
}'
# Add Lambda target
aws events put-targets \
--rule ec2-state-change \
--targets '[{
"Id": "process-state-change",
"Arn": "arn:aws:lambda:us-east-1:xxx:function:handle-state-change",
"Input": "{\"source\": \"ec2\", \"detail\": \"<detail>\"}"
}]'
# Lambda permission
aws lambda add-permission \
--function-name handle-state-change \
--statement-id ec2-event \
--action lambda:InvokeFunction \
--principal events.amazonaws.com \
--source-arn arn:aws:events:us-east-1:xxx:rule/ec2-state-change
Scheduled Rules
# Run Lambda every hour
aws events put-rule \
--name hourly-cleanup \
--schedule-expression 'rate(1 hour)'
# Run Lambda at specific time
aws events put-rule \
--name daily-report \
--schedule-expression 'cron(0 8 * * ? *)'
CloudWatch Best Practices
CloudWatch Best Practices
Monitoring Strategy
┌─────────────────────────────────────────────────────────────┐
│ CloudWatch Monitoring Stack │
├─────────────────────────────────────────────────────────────┤
│ │
│ Layer 1: Metrics (CPU, Memory, Network) │
│ Layer 2: Logs (Application logs, Access logs) │
│ Layer 3: Alarms (Threshold-based alerts) │
│ Layer 4: Dashboards (Visual overview) │
│ Layer 5: Events (Automated responses) │
│ │
└─────────────────────────────────────────────────────────────┘
Best Practices
- Use custom namespaces for application metrics
- Set up alarms for critical metrics
- Use Logs Insights for complex queries
- Implement dashboards for visual monitoring
- Use EventBridge for automated responses
- Enable detailed monitoring for critical instances
- Use CloudWatch Agent for custom metrics
- Set retention policies for logs
Cost Optimization
| Feature | Cost |
|---|---|
| First 5GB logs/month | Free |
| Custom metrics | $0.30/metric/month |
| Alarms | $0.10/alarm/month |
| Dashboards | $3.00/dashboard/month |
| Logs Insights | $0.005/GB scanned |
# Optimize costs
# 1. Set retention policies
aws logs put-retention-policy --log-group-name /myapp/logs --retention-in-days 30
# 2. Use metric filters instead of custom metrics
aws logs put-metric-filter --log-group-name /myapp/logs --filter-name errors --filter-pattern '"ERROR"' --metric-transformations metricName=Errors,metricNamespace=MyApp,metricValue=1
# 3. Delete unused dashboards
aws cloudwatch delete-dashboard --dashboard-name old-dashboard