CloudWatch: Giám Sát và Xem Log của Ứng Dụng

K
Kai··5 min read

Trong bài này chúng ta thêm phần giám sát cho hệ thống: tạo một cảnh báo gửi email khi CPU của EC2 tăng cao, và đưa log của ứng dụng lên một nơi tập trung để xem. Sau khi pipeline ở Bài 7 đã tự deploy, đây là phần giúp bạn biết hệ thống đang sống thế nào.

CloudWatch là dịch vụ giám sát của AWS. Nó thu thập metric (số liệu như CPU, mạng, bộ nhớ), lưu log, và cho phép đặt alarm (cảnh báo) khi một metric vượt ngưỡng. SNS (Simple Notification Service) là dịch vụ gửi thông báo; ta dùng nó để alarm gửi email tới bạn.

Mục tiêu

  1. Tạo một SNS topic và đăng ký email nhận thông báo.
  2. Tạo một CloudWatch alarm theo dõi CPU của EC2, gửi cảnh báo qua SNS.
  3. Đưa log của container lên CloudWatch Logs và xem chúng.
  4. Dọn dẹp.

Chi phí dự kiến

  • CloudWatch alarm: mô hình cũ miễn phí 10 alarm mỗi tháng; mô hình credit thì trừ credit (chi phí rất nhỏ).
  • SNS email: gần như miễn phí ở mức học (hạn mức email miễn phí rất rộng).
  • CloudWatch Logs: tính theo dung lượng log đẩy lên và lưu trữ; vài dòng log của bài này không đáng kể.
  • EC2: như Bài 2.

Phần tốn tiền vẫn là EC2; alarm và log để lại lâu cũng phát sinh chút ít, nên ta dọn ở cuối.

Chuẩn bị

Cần một EC2 đang chạy container todo-app như cuối Bài 7. Nếu đã dọn, dựng lại EC2 và chạy lại container (kéo từ ECR như Bài 7, hoặc build trực tiếp). Đặt vài biến trên máy:

REGION=ap-southeast-1
INSTANCE_ID=$(aws ec2 describe-instances \
  --filters Name=instance-state-name,Values=running \
  --query "Reservations[0].Instances[0].InstanceId" --output text)
echo $INSTANCE_ID

Bước 1: Tạo SNS topic và đăng ký email

Alarm cần một nơi để gửi thông báo. Ta tạo một SNS topic rồi đăng ký email vào đó.

# Tạo topic
TOPIC_ARN=$(aws sns create-topic --name devops-alerts \
  --query "TopicArn" --output text)
echo $TOPIC_ARN

# Đăng ký email vào topic (thay email của bạn)
aws sns subscribe \
  --topic-arn $TOPIC_ARN \
  --protocol email \
  --notification-endpoint ban@example.com

AWS gửi một email xác nhận tới địa chỉ đó. Mở email và bấm "Confirm subscription" — nếu không xác nhận, bạn sẽ không nhận được cảnh báo. Kiểm tra trạng thái đăng ký:

aws sns list-subscriptions-by-topic --topic-arn $TOPIC_ARN \
  --query "Subscriptions[].{Endpoint:Endpoint,Status:SubscriptionArn}" --output table

Khi cột status hiện một ARN (thay vì PendingConfirmation), nghĩa là đã xác nhận.

Bước 2: Tạo alarm theo dõi CPU

EC2 tự gửi metric CPUUtilization lên CloudWatch sẵn, không cần cài gì thêm. Ta tạo alarm: nếu CPU trung bình vượt 70% trong hai chu kỳ 5 phút liên tiếp thì báo động và gửi SNS.

aws cloudwatch put-metric-alarm \
  --alarm-name todo-ec2-high-cpu \
  --alarm-description "Canh bao khi CPU EC2 vuot 70%" \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --statistic Average \
  --period 300 \
  --evaluation-periods 2 \
  --threshold 70 \
  --comparison-operator GreaterThanThreshold \
  --dimensions Name=InstanceId,Value=$INSTANCE_ID \
  --alarm-actions $TOPIC_ARN

Giải thích vài tham số:

  • --period 300--evaluation-periods 2: xét trung bình mỗi 5 phút, cần 2 chu kỳ liên tiếp vượt ngưỡng mới báo. Yêu cầu liên tiếp giúp tránh báo động giả khi CPU chỉ nhảy lên một lúc.
  • --alarm-actions $TOPIC_ARN: khi vào trạng thái ALARM thì gửi tới SNS topic.

Xem trạng thái alarm:

aws cloudwatch describe-alarms --alarm-names todo-ec2-high-cpu \
  --query "MetricAlarms[].{Name:AlarmName,State:StateValue}" --output table

Ban đầu alarm thường ở trạng thái INSUFFICIENT_DATA (chưa đủ dữ liệu), sau đó chuyển sang OK. Muốn thử cho nó báo động, SSH vào EC2 và tạo tải CPU giả trong vài phút:

# Trên EC2: ép CPU bận trong khoang 5 phut (so 2 = so nhan)
timeout 360 sh -c 'while true; do :; done & while true; do :; done'

Sau vài phút, alarm chuyển sang ALARM và bạn nhận được email từ SNS. Khi tải giảm, nó quay lại OK.

Bước 3: Đưa log của container lên CloudWatch Logs

Hiện log của app chỉ nằm trong container trên EC2; SSH vào mới xem được, và mất khi container bị xóa. Ta đẩy log lên CloudWatch Logs để xem tập trung và giữ lại.

Docker hỗ trợ gửi log thẳng lên CloudWatch qua log driver awslogs. Để dùng được, EC2 cần quyền ghi log. Nếu đã làm Bài 7, EC2 đang gắn role ec2-ecr-pull; gắn thêm quyền ghi CloudWatch Logs cho role đó:

aws iam attach-role-policy \
  --role-name ec2-ecr-pull \
  --policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy

Tạo một log group để chứa log:

aws logs create-log-group --log-group-name /todo-app

SSH vào EC2, chạy lại container với log driver awslogs (dừng container cũ trước):

docker stop todo-app && docker rm todo-app

docker run -d --name todo-app -p 80:3000 --restart unless-stopped \
  --log-driver=awslogs \
  --log-opt awslogs-region=ap-southeast-1 \
  --log-opt awslogs-group=/todo-app \
  --log-opt awslogs-stream=container \
  <IMAGE>

Thay <IMAGE> bằng image đang dùng (ví dụ image trên ECR từ Bài 7). Truy cập http://<EC2_IP> vài lần để app sinh log.

Xem log từ máy của bạn:

aws logs tail /todo-app --follow

logs tail --follow bám theo log mới như tail -f. Bạn sẽ thấy dòng Server dang chay tren cong 3000 và các request tới app. Log giờ nằm trên CloudWatch, không mất khi container bị thay trong lần deploy sau.

Đặt thời gian giữ log (retention) để log cũ tự xóa, tránh tích tụ tốn tiền. Ví dụ giữ 7 ngày: bash aws logs put-retention-policy --log-group-name /todo-app --retention-in-days 7

🧹 Dọn dẹp

Xóa các thứ vừa tạo. EC2 vẫn là phần tốn tiền chính.

# Xóa alarm
aws cloudwatch delete-alarms --alarm-names todo-ec2-high-cpu

# Xóa log group (kèm toàn bộ log bên trong)
aws logs delete-log-group --log-group-name /todo-app

# Xóa SNS topic (kèm các subscription)
aws sns delete-topic --topic-arn $TOPIC_ARN

Nếu ở Bước 3 bạn đã gắn thêm policy cho role EC2 và không định dùng nữa, gỡ ra:

aws iam detach-role-policy --role-name ec2-ecr-pull \
  --policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy

Cuối cùng, nếu không học tiếp ngay, terminate EC2 và xóa ECR repository như phần dọn dẹp Bài 7.

Tổng kết

Bạn vừa thêm hai mảnh giám sát quan trọng: một alarm chủ động báo qua email khi CPU bất thường, và log tập trung trên CloudWatch để xem ứng dụng đang làm gì. Cùng với pipeline ở Bài 7, giờ bạn có thể deploy tự động và biết được khi có sự cố — đủ các mảnh cơ bản của một hệ thống vận hành được.

Bài 9 là bài cuối: ta rà soát lại toàn bộ tài khoản để chắc chắn không còn resource nào đang âm thầm tính tiền, điểm lại các best practices, và gợi ý hướng học tiếp.