Crisp answer: CloudWatch is AWS's observability platform: metrics, logs, alarms, dashboards, and events. Every AWS service publishes metrics to CloudWatch automatically. You add custom metrics, set alarms, and analyse logs from a central place.
Metrics:
# View metrics in CLI
aws cloudwatch list-metrics --namespace AWS/EC2
aws cloudwatch get-metric-statistics \
--namespace AWS/EC2 \
--metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=i-0abc123 \
--start-time 2025-06-01T00:00:00Z \
--end-time 2025-06-01T01:00:00Z \
--period 60 \
--statistics Average
# Publish a custom metric
aws cloudwatch put-metric-data \
--namespace MyApp \
--metric-name RequestCount \
--value 42 \
--unit Count
Key EKS/Kubernetes metrics:
AWS/EKS namespace:
cluster_failed_node_count — nodes in NotReady state
cluster_node_count — total nodes
Container Insights (requires the CloudWatch agent add-on):
pod_cpu_utilization_over_pod_limit — CPU throttling
pod_memory_utilization_over_pod_limit — approaching OOM
pod_number_of_container_restarts — CrashLoopBackOff detection
node_cpu_utilization
node_memory_utilization
Alarms:
# Create an alarm on EC2 CPU
aws cloudwatch put-metric-alarm \
--alarm-name "high-cpu-web" \
--metric-name CPUUtilization \
--namespace AWS/EC2 \
--dimensions Name=InstanceId,Value=i-0abc123 \
--statistic Average \
--period 300 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 2 \
--alarm-actions arn:aws:sns:eu-west-2:123:my-topic
Alarm states:
OK— metric within thresholdALARM— metric breached threshold for evaluation-periodsINSUFFICIENT_DATA— not enough data to evaluate
CloudWatch Logs:
# View log groups
aws logs describe-log-groups --log-group-name-prefix /aws/lambda
# Tail logs in real time
aws logs tail /aws/lambda/my-function --follow
# Filter logs
aws logs filter-log-events \
--log-group-name /aws/eks/my-cluster/cluster \
--filter-pattern "ERROR" \
--start-time $(date -d '1 hour ago' +%s)000
# Logs Insights query (run in console or CLI)
aws logs start-query \
--log-group-name /aws/lambda/my-function \
--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 20'
Log Groups structure for AWS services:
/aws/lambda/<function-name> Lambda function logs
/aws/eks/<cluster>/cluster EKS control plane logs
/aws/rds/cluster/<id>/postgresql RDS/Aurora PostgreSQL logs
/aws/apigateway/<api-id> API Gateway access logs
/aws-glue/jobs/output Glue job logs
CloudWatch Agent:
For EC2 and EKS nodes, install the CloudWatch agent to collect:
- Custom application metrics
- System metrics (memory, disk — not collected by default)
- Log files from the filesystem
Container Insights for EKS:
# Enable Container Insights on an EKS cluster
aws eks update-addon \
--cluster-name my-cluster \
--addon-name amazon-cloudwatch-observability \
--addon-version v2.1.0-eksbuild.1
What to say in the interview:
"CloudWatch is the central monitoring plane for AWS. Every service publishes metrics automatically — I set alarms on the critical ones: CPUUtilization, memory for custom metrics, error rates on Lambda. For EKS I enable Container Insights which gives pod-level CPU and memory metrics, plus restart counts which is how I detect CrashLoopBackOff at scale before it causes an incident. For log analysis I use Logs Insights for ad-hoc queries and set metric filters to turn log patterns into CloudWatch metrics for alarming. The key gap: CloudWatch does not collect memory or disk metrics from EC2 by default — you need the CloudWatch agent for those."