Skip to content
intermediate Phase 7 · AWS Monitoring & Cost

CloudWatch Monitoring

Monitor metrics, create alarms, and build dashboards with CloudWatch.

1h 15m
0 problems
Topic Progress 0%

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

  1. Use custom namespaces for application metrics
  2. Set up alarms for critical metrics
  3. Use Logs Insights for complex queries
  4. Implement dashboards for visual monitoring
  5. Use EventBridge for automated responses
  6. Enable detailed monitoring for critical instances
  7. Use CloudWatch Agent for custom metrics
  8. 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