การจัดการ laravel.log ด้วย CloudWatch Logs บน Elastic Beanstalk

CloudWatch เป็นบริการที่สามารถช่วยให้เราสามารถดูประวัติการใช้งานผ่าน Log ได้ ต่อให้เป็นการสร้าง EC2 ในรูปแบบ Auto Scaling บน Elastic Beanstalk ก็สามารถทำการบันทึก Log ได้อย่างง่ายดาย และสำหรับคนที่กำลังใช้งาน Auto Scaling บน EC2 อยู่และมีการเปิด-ปิดการใช้งานอัตโนมัติอยู่ตลอดเวลา ผมแนะนำให้ลองใช้ CloudWatch ดูครับ ซึ่งในบทความนี้ผมจะมาสาธิตวิธีการจัดการ laravel.log ด้วย CloudWatch Logs บน Elastic Beanstalk ครับ

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ครั้งนี้ผมจะมาแนะนำเกี่ยวกับ การจัดการ laravel.log ด้วย CloudWatch Logs บน Elastic Beanstalk

สิ่งที่ต้องมี

ทำการ Deploy Laravel ด้วย Elastic Beanstalk และเชื่อมต่อกับ RDS ตามบทความด้านล่างนี้ครับ

เมื่อทำวิธีการตามลิงก์ในหัวข้อ สิ่งที่ต้องมี เสร็จแล้ว ให้เริ่มทำขั้นตอนถัดไปได้เลยครับ

การตั้งค่า CloudWatch Log และ Deploy Laravel ใน Elastic Beanstalk

ทำการสร้างไฟล์และโฟลเดอร์ที่จะใช้ตั้งค่า CloudWatch ในขณะที่ระบบ Deploy Laravel ใน Elastic Beanstalk ดังนี้

สร้าง: [.ebextensions/03_cloudwatchlog.config] และ Copy Code นี้วางที่ไฟล์03_cloudwatchlog.config

files:
  "/home/ec2-user/cloudwatch_log_setup.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/bin/bash
      # export $(cat /opt/elasticbeanstalk/deployment/env | grep -v ^# | xargs);
      export INSTANCE_ID=`cat /var/lib/cloud/data/instance-id`
      aws logs create-log-group --log-group-name "/${APP_NAME}/${APP_ENV}/laravel_log" --region ap-southeast-1
      aws logs put-retention-policy --log-group-name "/${APP_NAME}/${APP_ENV}/laravel_log" --retention-in-days 30 --region ap-southeast-1
      aws logs create-log-stream --log-group-name "/${APP_NAME}/${APP_ENV}/laravel_log" --log-stream-name ${INSTANCE_ID} --region ap-southeast-1
      echo -n "" >> /etc/awslogs/awslogs.conf
      echo "[laravel_log]" >> /etc/awslogs/awslogs.conf
      echo "log_group_name=/${APP_NAME}/${APP_ENV}/laravel_log" >> /etc/awslogs/awslogs.conf
      echo "log_stream_name=${INSTANCE_ID}" >> /etc/awslogs/awslogs.conf
      echo "file=/var/app/current/storage/logs/laravel*.log" >> /etc/awslogs/awslogs.conf
      echo "datetime_format=%Y-%m-%d %H:%M:%S" >> /etc/awslogs/awslogs.conf
      echo "buffer_duration=5000" >> /etc/awslogs/awslogs.conf
      echo "initial_position=start_of_file" >> /etc/awslogs/awslogs.conf
      echo "time_zone=LOCAL" >> /etc/awslogs/awslogs.conf
      echo "" >> /etc/awslogs/awslogs.conf

container_commands:
  "01_awslogs_install":
    command: |
      echo `date`." 01_awslogs_install" >> /var/log/ebextensions_test.log
      yum install awslogs -y
      /home/ec2-user/cloudwatch_log_setup.sh
      echo -n "" > /etc/awslogs/awscli.conf
      echo "[plugins]" >> /etc/awslogs/awscli.conf
      echo "cwlogs = cwlogs" >> /etc/awslogs/awscli.conf
      echo "[default]" >> /etc/awslogs/awscli.conf
      echo "region = ap-southeast-1" >> /etc/awslogs/awscli.conf
      sed -i -e "s/^\[\/var\/log\/messages\]/# \[\/var\/log\/messages\]/" /etc/awslogs/awslogs.conf
      sed -i -e "s/^datetime_format \= \%b \%d \%H\:\%M\:\%S/# datetime_format \= \%b \%d \%H\:\%M\:\%S/" /etc/awslogs/awslogs.conf
      sed -i -e "s/^file \= \/var\/log\/messages/# file \= \/var\/log\/messages/" /etc/awslogs/awslogs.conf
      sed -i -e "s/^buffer_duration \= 5000/# buffer_duration \= 5000/" /etc/awslogs/awslogs.conf
      sed -i -e "s/^log_stream_name \= /# log_stream_name \= /" /etc/awslogs/awslogs.conf
      sed -i -e "s/^initial_position \= start_of_file/# initial_position \= start_of_file/" /etc/awslogs/awslogs.conf
      sed -i -e "s/^log_group_name \= \/var\/log\/messages/# log_group_name \= \/var\/log\/messages/" /etc/awslogs/awslogs.conf
      systemctl restart awslogsd
      systemctl enable awslogsd

เมื่อเตรียมไฟล์การตั้งค่า CloudWatch Log เสร็จแล้ว ให้ทำการสร้างไฟล์ Zip และ Deploy ใน Elastic Beanstalk

การสร้าง Role ใน IAM

ขั้นตอนนี้ผมจะสร้าง Role เพื่อนำไปใช้กับ EC2 ที่จะสร้างใน Elastic Beanstalk ในขั้นตอนถัดไปครับ

ดูตัวอย่างที่นี่เฉพาะหัวข้อนี้: การสร้าง Role ใน IAM

ตัวอย่างการสร้าง Role ใน IAM ของบทความนี้

※Step 1: Select trusted entity
Trusted entity type: ◉AWS service
Use case
Common use cases: ◉EC2(ข้อควรระวัง: เราจะไม่ใช้ Elastic Beanstalk ! แต่ให้ใช้ EC2)

※Step 2: Add permissions
Permissions policies:CloudWatchLogsFullAccess,AWSElasticBeanstalkWebTier
หมายเหตุ: Permission ที่ต้องทำการอนุญาตที่นี่คือ CloudWatchLog ดังนั้นให้เพิ่ม "CloudWatchLogsFullAccess"
นอกจากนี้ Elastic Beanstalk ต้องได้รับการเพิ่ม Permission ของ "AWSElasticBeanstalkWebTier" เข้ามาด้วย】

※Step 3: Name, review, and create
Role details
Role name:ec2-tinnakorn-cloudwatchlog

การตั้งค่าขณะสร้าง Environment ใน Elastic Beanstalk

ผมจะสร้าง Environment ใน Application ที่ชื่อว่าtinnakornที่สร้างไว้ก่อนหน้านี้ครับ

ตอนสร้าง Environment แนะนำให้ใช้วิธีในบทความนี้ครับ และในส่วนของการตั้งค่าConfigure more optionsให้ดูตามขั้นตอนของ ตัวอย่างการสร้าง Environment ของบทความนี้ ที่ด้านล่างนี้ครับ (ถ้ามีขั้นตอนที่ซ้ำกันให้ข้ามไปได้เลยครับ)

ตัวอย่างการสร้าง Environment ของบทความนี้

※Environment information
Environment name:tinnakorn-cloudwatchlog(ชื่ออะไรก็ได้)
Domain:tinnakorn-cloudwatchlog(ชื่ออะไรก็ได้)

※Platform
Platform:PHP

※Application code
เลือกวิธีอัปโหลดไฟล์ตามที่คุณต้องการ


** จากนี้ไปให้ดูวิธีการตั้งค่าใน [Configure more options] จากตัวอย่างและลิงก์ที่เรียงไว้ด้านล่างนี้ **

เมื่อทำเสร็จในแต่ละขั้นตอนของลิงก์ด้านล่างนี้แล้ว อย่าพึ่งคลิกปุ่มCreate environmentนะครับ เพราะว่าต้องตั้งค่าให้ครบตามที่เขียนไว้ด้านล่างนี้

  1. การตั้งค่าหน้า Configure more options สำหรับการใช้ ELB (ALB)

  2. เข้าไปที่ Software ตรงหัวข้อEnvironment properties
    แล้วเปลี่ยน APP_ENV และ APP_NAME ตามตัวอย่างนี้
    หมายเหตุ: เนื่องจากใช้ตัวแปรสภาพแวดล้อม (APP_ENV, APP_NAME) ในการตั้งค่า CloudWatch Logs จึงจำเป็นต้องตั้งค่าทั้ง 2 ตัวนี้ และตั้งชื่อไม่ให้เหมือนกันในแต่ละ Environment】
    » APP_ENV=cloudwatchlog
    » APP_NAME=tinnakorn
    » เมื่อเปลี่ยนเสร็จแล้ว เลื่อนลงมาด้านล่างสุด คลิกSave

  3. กลับมาที่หัวข้อหัวข้อ Security แล้วตั้งค่าดังนี้
    Virtual machine permissions
    » IAM instance profile:ec2-tinnakorn-cloudwatchlog
    » คลิกSave

เมื่อตั้งค่าตามขั้นตอนข้างต้นเสร็จแล้ว ให้เลื่อนลงมาด้านล่างสุดและคลิกปุ่มCreate environmentจากนั้นรอระบบเริ่มต้นสักครู่ครับ

ถ้าเสร็จแล้วให้คลิกลิงก์เปิดหน้าเว็บไซต์โปรเจกต์ของเราจากหน้า Environment ได้เลยครับ (ลิงก์นี้เป็นแค่ตัวอย่าง)

http://tinnakorn-cloudwatchlog.ap-southeast-1.elasticbeanstalk.com/

ตรวจสอบ CloudWatch Log

ไปที่ Service [CloudWatch > Log groups]

ทำการตรวจสอบ Log ดังนี้:
ค้นหาชื่อของเรา เช่น/tinnakorn/cloudwatchlogแล้วคลิกเข้าไปครับ (นี่คือตัวแปรสภาพแวดล้อมที่ถูกใช้งาน ซึ่งเป็น/APP_NAME/APP_ENVนั่นเอง)

เมื่อเข้ามาแล้วดูที่ Log streams จะเห็นว่ามี Instance ID แสดงขึ้นมา 2 ตัวตามที่กำหนดไว้ใน Elastic Beanstalk
ซึ่งเราสามารถ Copy Instance ID จากที่นี่ไปค้นหาในหน้า Instance ได้ครับ
ทีนี้ให้คลิกเข้าไปดูในแต่ละ Instance ได้เลยครับ

Instance ID ของบทความนี้:i-0d63fc42463547f0a,i-028ffabac790e4516

จะเห็นว่าไม่มีข้อมูลแสดงใน Log events เพราะว่ายังไม่มี Error ครับ

เชื่อมต่อ Server EC2 ด้วย SSH

ดูตัวอย่างการเชื่อมต่อ Server EC2 ด้วย SSH จาก EC2 ไปยัง EC2 อื่นตามลิงก์บทความด้านล่างนี้ครับ

ทดสอบ Error Log ใน VSCode และ CloudWatch Log

เมื่อเชื่อมต่อเสร็จแล้ว รันคำสั่งด้านล่างใน Server EC2 ทั้ง 2 ตัวนี้เพื่อดูข้อมูล Error ใน awslogs.log

tail -f /var/log/awslogs.log

ตอนที่ยังไม่มี Error จะแสดงหน้าจอแบบนี้


กลับมาที่หน้าเว็บไซต์โปรเจกต์ของเรา แล้วเปิดหน้าเว็บอะไรก็ได้ที่ทำให้เกิด Error เพื่อให้บันทึก Log ไปยัง laravel.log เช่น

http://tinnakorn-cloudwatchlog.ap-southeast-1.elasticbeanstalk.com/customer/3

กลับมาที่ VSCode จะเห็นว่ามี Error แสดงขึ้นมาแล้ว ซึ่งในส่วนของ/var/app/current/storage/logs/laravel.logนี้คือไฟล์ที่มีการตรวจสอบ Error และข้อมูลนี้ก็จะไปแสดงใน CloudWatch Log ของเราครับ (ในส่วนนี้ผมจะอธิบายในภายหลัง)

ต่อไปให้สลับ Terminal ไปยัง Server EC2 อีกตัว จะเห็นว่ายังไม่มีข้อมูล Error แสดงขึ้นมา

ทีนี้ให้กลับไปที่หน้าเว็บไซต์โปรเจ็กต์ที่ Error ของเราและ Reload 1-2 ครั้ง
แล้วกลับมาที่ Terminal จะเห็นว่ามี Error แสดงขึ้นมาแล้วครับ

ไปที่หน้า Service [CloudWatch > Log groups > /your_app_name/cloudwatchlog/laravel_log > i-your_instance_id]
จะเห็นว่ามีข้อมูล Error Log แสดงขึ้นมาแล้วครับ

Terminate Instance และตรวจสอบ CloudWatch Log

มาที่ Service [EC2 > Instance] แล้วทำการ Terminate instance ตัวไหนก็ได้สัก 1 ตัว
เช่นi-0d63fc42463547f0aแล้วรอจนกว่า Instance state เป็นTerminate

เมื่อ Instance state เป็น Terminate แล้วให้กดปุ่ม Reload
จะเห็นว่ามี Instance ใหม่เพิ่มขึ้นมา 1 ตัว นั่นก็คือi-0b6f7576c18529905ครับ

ทีนี้ให้มาที่หน้า Service [CloudWatch > Log groups > /your_app_name/cloudwatchlog/laravel_log]
จะเห็นว่า Log stream ของ Instance ID:i-0b6f7576c18529905เพิ่มขึ้นมา ซึ่งยังไม่มีข้อมูล Error Log นะครับ (ถ้าต้องการดู Log ของ Instance ID ที่ Terminate ไปแล้ว คลิกเข้าไปที่ Instance ID นั้นได้เลยครับ)

ไปที่หน้าเว็บไซต์โปรเจกต์ที่ Error ของเรา แล้วทำการ Reload ประมาณ 2-3 ครั้งครับ

จากนั้นกลับมาที่หน้า Service [CloudWatch > Log groups > /your_app_name/cloudwatchlog/laravel_log] อีกครั้งแล้วทำการ Reload ครับ
ถ้า Last event time ในแถวของ Instance ID ตัวใหม่แสดงวันที่และเวลาขึ้นมาแล้ว ให้คลิกเข้าไปได้เลยครับ

จะเห็นว่ามีข้อมูล Error Log แสดงขึ้นมาแล้ว เพียงเท่านี้เราก็สามารถดูข้อมูล Log ใน Instance ของเราได้โดยไม่ต้องเข้าไปใน Linux และรันคำสั่งให้ยุ่งยากอีกต่อไปครับ

สรุป

ผมได้มีโอกาสใช้ CloudWatch Log แล้วทำให้ผมรู้สึกว่าเวลาจะดูข้อมูล Error, ข้อมูลการเชื่อมต่อ หรือประวัติการใช้งานต่างๆ ก็ไม่ต้องไปรันคำสั่งใน Server EC2 ทุกครั้งให้ยุ่งยาก และตั้งแต่ได้รู้จักกับ Service CloudWatch แล้วทำให้ผมได้เห็นถึงความสะดวกในการตรวจสอบข้อมูลที่เรียกว่า Log คือเราสามารถเข้าไปดูใน Service CloudWatch ได้เลยนั่นเอง

นอกจากนี้ต่อให้เราทำการ Terminate Instance ไปแล้วเราก็ยังสามารถดูประวัติการใช้งานย้อนหลังของ Instance นั้นใน CloudWatch Log ได้อีกด้วย

บทความที่เกี่ยวข้อง