Tech Blog

วิธีตรวจสอบ Log Spring Boot App ที่รันบน AWS ECS ด้วย CloudWatch Logs

by y104
AWS ECS CloudWatch Spring Boot

บทนำ

เมื่อ Spring Boot app ที่ deploy ขึ้น ECS ทำงานไม่ได้ การตรวจสอบ log คือก้าวแรก
แต่ก็แปลกที่บ่อยครั้งที่เปิด ECS console แล้วไม่รู้ว่า log อยู่ที่ไหน

บทความนี้ครอบคลุมตั้งแต่การตั้งค่า ECS + CloudWatch Logs ไปจนถึง command จริงสำหรับตรวจสอบ log


การตั้งค่า CloudWatch Logs

การตั้งค่า Log ใน Task Definition

ตั้ง log driver ของ container เป็น awslogs ใน ECS task definition

การตั้งค่าด้วย CDK

// cdk/lib/app-stack.ts
const logGroup = new logs.LogGroup(this, 'AppLogGroup', {
  logGroupName: '/dvd-rental/app',
  retention: logs.RetentionDays.ONE_WEEK,
  removalPolicy: cdk.RemovalPolicy.DESTROY,
});

const container = taskDefinition.addContainer('AppContainer', {
  image: ecs.ContainerImage.fromEcrRepository(ecrRepo, 'latest'),
  logging: ecs.LogDrivers.awsLogs({
    streamPrefix: 'dvd-rental',
    logGroup: logGroup,
  }),
});

การตั้งค่าใน Task Definition JSON

{
  "logConfiguration": {
    "logDriver": "awslogs",
    "options": {
      "awslogs-group": "/dvd-rental/app",
      "awslogs-region": "ap-northeast-1",
      "awslogs-stream-prefix": "dvd-rental"
    }
  }
}

การให้สิทธิ์กับ IAM Role

ECS Task Execution Role ต้องมีสิทธิ์ write ไปยัง CloudWatch Logs

// การตั้งค่า CDK
taskDefinition.addToExecutionRolePolicy(new iam.PolicyStatement({
  actions: [
    'logs:CreateLogGroup',
    'logs:CreateLogStream',
    'logs:PutLogEvents',
  ],
  resources: ['*'],
}));

AmazonECSTaskExecutionRolePolicy managed policy มีสิทธิ์เหล่านี้อยู่แล้ว
ดังนั้นการ attach policy นี้ให้ task execution role ก็เพียงพอ


โครงสร้างของ CloudWatch Logs

หลังจากตั้งค่า log จะถูกเก็บในโครงสร้างต่อไปนี้:

Log Group: /dvd-rental/app
  Log Stream: dvd-rental/AppContainer/{task-id}

Log stream ใหม่จะถูกสร้างทุกครั้งที่ task เริ่มต้น


วิธีตรวจสอบ Log

ตรวจสอบผ่าน AWS Console

  1. CloudWatch → Log Groups → /dvd-rental/app
  2. เลือก stream ล่าสุดจากรายการ log streams
  3. ใช้กล่อง filter เพื่อค้นหาด้วย keyword

ตรวจสอบผ่าน AWS CLI

แสดงรายการ Log Streams

aws logs describe-log-streams \
    --log-group-name "/dvd-rental/app" \
    --order-by LastEventTime \
    --descending \
    --max-items 5 \
    --region ap-northeast-1

ตรวจสอบ Log ล่าสุด

# ดึงชื่อ log stream ล่าสุด
STREAM=$(aws logs describe-log-streams \
    --log-group-name "/dvd-rental/app" \
    --order-by LastEventTime \
    --descending \
    --max-items 1 \
    --query "logStreams[0].logStreamName" \
    --output text \
    --region ap-northeast-1)

# แสดง log (30 รายการล่าสุด)
aws logs get-log-events \
    --log-group-name "/dvd-rental/app" \
    --log-stream-name "$STREAM" \
    --limit 30 \
    --region ap-northeast-1 \
    --query "events[*].message" \
    --output text

ค้นหาด้วย Keyword

# ค้นหา log ที่มีคำว่า "ERROR"
aws logs filter-log-events \
    --log-group-name "/dvd-rental/app" \
    --filter-pattern "ERROR" \
    --start-time $(date -d '1 hour ago' +%s000) \
    --region ap-northeast-1

# ตรวจสอบ active profile
aws logs filter-log-events \
    --log-group-name "/dvd-rental/app" \
    --filter-pattern "profiles is active" \
    --region ap-northeast-1 \
    --query "events[*].message" \
    --output text

ขั้นตอนการตรวจสอบหลัง Deploy

หลังจาก deploy ขึ้น ECS ให้ตรวจสอบ log ตามลำดับต่อไปนี้

Step 1: ตรวจสอบว่า Task เริ่มต้นแล้วหรือยัง

aws ecs describe-services \
    --cluster dvd-rental-cluster \
    --services dvd-rental-service \
    --region ap-northeast-1 \
    --query "services[0].{Running:runningCount,Desired:desiredCount,Status:status}"

ถ้า runningCount ตรงกับ desiredCount แสดงว่า task กำลังรัน

Step 2: ตรวจสอบ Log ของ Task ใหม่

# ดึง ARN ของ task ล่าสุด
TASK_ARN=$(aws ecs list-tasks \
    --cluster dvd-rental-cluster \
    --service-name dvd-rental-service \
    --desired-status RUNNING \
    --region ap-northeast-1 \
    --query "taskArns[0]" \
    --output text)

echo "Task ARN: $TASK_ARN"

Step 3: ตรวจสอบ Log การเริ่มต้นของ Spring Boot

จุดสำคัญที่ต้องตรวจสอบ:

# ✅ ตรวจสอบ 1: มี profile ที่ถูกต้องถูก apply หรือไม่
INFO  - The following 1 profile is active: "prod"

# ✅ ตรวจสอบ 2: การเชื่อมต่อ DB สำเร็จหรือไม่
INFO  - HikariPool-1 - Start completed.

# ✅ ตรวจสอบ 3: Flyway migrations สำเร็จหรือไม่
INFO  - Successfully applied 4 migrations to schema "public"

# ✅ ตรวจสอบ 4: App เริ่มต้นเสร็จสมบูรณ์หรือไม่
INFO  - Started DvdRentalApplication in 8.234 seconds

กรณีปัญหาที่พบ

Container หยุดทันที

ถ้า log มี error แบบนี้:

ERROR - Failed to configure a DataSource: 'url' attribute is not specified

การตั้งค่าการเชื่อมต่อ DB ไม่ถูกส่งผ่านอย่างถูกต้อง
ตรวจสอบการตั้งค่า environment variables และ Secrets ใน ECS task definition

Log ไม่ปรากฏเลย

Log group ของ CloudWatch Logs อาจไม่มีอยู่ หรือ IAM role อาจไม่มีสิทธิ์ write

# ตรวจสอบว่า log group มีอยู่หรือไม่
aws logs describe-log-groups \
    --log-group-name-prefix "/dvd-rental" \
    --region ap-northeast-1

สรุป

ขั้นตอนการตรวจสอบ log หลัง ECS deploy:

  1. describe-services — ตรวจจำนวน task (running == desired หรือไม่?)
  2. CloudWatch Logs — เปิด log stream ล่าสุด
  3. ตรวจสอบ log การเริ่มต้นของ Spring Boot สำหรับ active profile, DB connection, Flyway
  4. ถ้ามี error ใช้ filter-log-events เพื่อค้นหาด้วย keyword

“CloudFormation ถึง COMPLETE ≠ deploy สำเร็จ”
สิ่งสำคัญคือ ทำให้การตรวจสอบ log ของ app เพื่อยืนยันการทำงานเป็นส่วนหนึ่งของทุก deployment


แผนที่บทความสำหรับซีรีส์นี้

สร้างแอป DVD Rental สำหรับผู้ใช้ปลายทาง — โครงสร้าง Vue 3 + Spring Boot คู่กับแอปผู้ดูแลระบบ พร้อมแผนที่บทความ
สร้างแอปผู้ดูแลระบบ DVD Rental ด้วย Spring Boot + Thymeleaf บน dvdrental Sample DB

ส่งข้อความได้ตามสบาย

กรุณาส่งข้อความ หากมีคำปรึกษาด้านเทคนิค ความคิดเห็น หรือคำถาม