[Update] วิธีการบันทึก Access Log ของ ELB ใน Elastic Beanstalk ไปยัง S3

แนะนำการบันทึก Access Log ของ ALB ใน S3 และอ่านทำความเข้าใจเนื้อหาในไฟล์ Log (สำหรับผู้เริ่มต้น)

สวัสดีครับ POP จากบริษัท Classmethod (Thailand) ครับ

ผมได้มีโอกาสทำงานเกี่ยวกับการบันทึก Access Log ของ ALB ไปยัง S3 ดังนั้นผมเลยจะมาแบ่งปันวิธีการเหล่านี้และแนะนำการอ่านเนื้อหาใน Log ครับ

สร้าง Buckets ใน Amazon S3

เข้ามาที่บริการ S3 แล้วเลือก Buckets จากเมนูด้านซ้าย

คลิก Create bucket

การตั้งค่า General configuration:
・AWS Region: Asia Pacific (Singapore) ap-southeast-1 (ตรวจสอบและเลือกใช้รีเจี้ยนที่ใกล้กลับประเทศที่เราอาศัยอยู่ให้มากที่สุด)
・Bucket name: tinnakorn-elb-log (ชื่ออะไรก็ได้)

เลื่อนลงมาด้านล่างสุด คลิกปุ่ม Create bucket

ตั้งค่า Bucket policy

เมื่อสร้าง Bucket เสร็จแล้ว ให้ค้นหาชื่อ Bucket ของเราและคลิกเข้ามาได้เลย แล้วเลือกแท็บ Permissions

แล้วคลิก Edit ที่หัวข้อ Bucket policy

คัดลอก Code ด้านล่างนี้วางใน Policy ของเราโดยผมจะอธิบายและแนะนำส่วนที่ต้องเปลี่ยนแปลงข้อมูลดังนี้
・Principal: 114774131450 คือ ELB account ID ของรีเจี้ยน Singapore (กรณีที่ใช้รีเจี้ยนอื่นให้ดูที่ ELB account ID)
・Resource: "arn:aws:s3:::bucket-name/AWSLogs/your-aws-account-id/*" (ต้องเปลี่ยน bucket-name และ your-aws-account-id ให้เป็นของคุณ)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::114774131450:root"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::bucket-name/AWSLogs/your-aws-account-id/*"
        }
    ]
}

เมื่อเปลี่ยนแปลงข้อมูลเป็นของคุณเสร็จแล้ว เลื่องลงมาด้านล่างสุด และคลิก Save changes


สำหรับผู้ใช้งานที่ต้องการศึกษาเกี่ยวกับ Bucket permissions เพิ่มเติม สามารถดูได้ที่ลิงก์ด้านล่างนี้ครับ

สร้าง Environment สำหรับบันทึก Access Log

ก่อนอื่นผมจะสร้าง Environment ที่ใช้สำหรับบันทึก Access Log ของ ELB ใน Elastic Beanstalk ไปยัง S3

สร้าง Application

ตัวอย่างครั้งนี้จะสร้าง Application โดยใช้ชื่อดังนี้
Application: tinnakorn

ดูตัวอย่างได้ที่ลิงก์หัวข้อนี้: สร้าง Application ใน Elastic Beanstalk

สร้าง Environment

ตัวอย่างครั้งนี้จะสร้าง Environment โดยใช้ชื่อดังนี้
Environment name: tinnakorn-elb-log

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

ครั้งนี้จะสร้าง Environment โดย Deploy Laravel ใน Elastic Beanstalk และเชื่อมต่อกับ RDS ดังนี้

Step 1: Configure environment

หัวข้อ Environment information
・Environment name: tinnakorn-elb-log (ชื่ออะไรก็ได้)
・Domain: tinnakorn-elb-log (ชื่ออะไรก็ได้)

หัวข้อ Platform
・Platform: PHP

หัวข้อ Application code
・เลือกวิธีอัปโหลดไฟล์ตามต้องการ (ครั้งนี้จะใช้โปรเจกต์ Laravel)

・คลิก Next

Step 2: Configure service access

หัวข้อ Service access
・Service role: Use an existing service role
・Existing service roles: aws-elasticbeanstalk-service-role
・EC2 key pair: tinnakorn-elb-log
・EC2 instance profile: aws-elasticbeanstalk-ec2-role
・คลิก Next

Step 3 - optional: Set up networking, database, and tags

Step นี้ระบุว่า "optional" จึงไม่จำเป็นต้องตั้งค่าอะไร เพราะเป็นการทดสอบการใช้งาน ให้คลิก Next ได้เลย

**ตั้งแต่ขั้นตอนนี้ไปจะแตกต่างจากตัวอย่างในบทความข้างต้น**

Step 4 - optional: Configure instance traffic and scaling

Step นี้ระบุว่า "optional" แต่จะตั้งค่าเพิ่มเติมดังนี้

หัวข้อ Instances
Root volume (boot device):
・Root volume type: General Purpose (SSD)
・Size: 10 GB (ขั้นต่ำคือ 10 GB)

แล้วค้นหาและเลือก EC2 security groups สำหรับ Elastic Beanstalk ที่สร้างในตอนแรก เช่น tinnakorn-elb-log

หัวข้อ Capacity
Auto scaling group
・Environment type: Load balanced
・Instances: 2 Min, 2 Max (ครั้งนี้จะตั้งค่าจำนวน Instance สูงสุดอยู่ที่ 2 ตัว)

Scaling triggers
Lower threshold: 0 capacity

หัวข้อ Load Balancer Type
เลือก Application load balancer

Log files access
・Store logs: ✅️ Enabled
・S3 Bucket: tinnakorn-elb-log (เลือก S3 bucket ที่สร้างไว้ในตอนแรก)
・คลิก Next

Step 5 - optional: Configure updates, monitoring, and logging

Step นี้ระบุว่า "optional" แต่จะตั้งค่าเพิ่มเติมดังนี้

หัวข้อ Managed platform updates
・Managed updates: ▢ Activated (ติ๊ก ✅ ออกเพื่อไม่ให้อัปเดต)
แล้วคลิก Next ด้านล่างสุด

หากต้องการอัปเดต OS โดยอัตโนมัติ ให้ติ๊ก ✅ และเมื่อมีการอัปเดต Instance จะรีสตาร์ทโดยอัตโนมัติ ซึ่งการรีสตาร์ท Instance หรือการอัปเดต OS อาจทำให้เกิดปัญหา เช่น บริการหยุดทำงานระหว่างการดำเนินการ แล้วในกรณีที่ติ๊ก ✅ นี้ จำเป็นต้องยืนยันว่าบริการยังทำงานตามปกติระหว่างการดำเนินการหรือไม่ หากมีความกังวล เราขอแนะนำว่าไม่ต้องไปติ๊ก ✅ ครับ

หัวข้อ Platform software Info
Container options
Proxy server: Nginx
Document root: /public

Step 6: Review

ตรวจสอบการตั้งค่าตั้งแต่ "Step 1 - Step 5" แล้วคลิก Submit ด้านล่างสุด แล้วรอสักครู่

ระหว่างที่ระบบกำลังเริ่มต้นจะมีสถานะเป็น [UnknownPendingOK] เมื่อระบบเริ่มต้นเสร็จแล้วจะแสดงหน้าจอแบบนี้ โดยมี Domain ที่เป็นลิงก์สำหรับแสดงผลหน้าไซต์ และมี Running version เป็นชื่อตามที่ป้อนตอนอัปโหลดไฟล์ ZIP

ตั้งค่า Configuration: Updates, monitoring, and logging

ต่อไปคลิก Configuration แล้วเลื่อนลงมาคลิก Edit ที่หัวข้อ "Updates, monitoring, and logging"

กดปุ่ม Ctrl + F แล้วค้นหา DB_DATABASE และเปลี่ยนข้อมูลตามด้านล่างนี้ให้เป็นของเรา (การตั้งค่านี้เป็นแค่ตัวอย่าง)
・DB_DATABASE: laravel
・DB_HOST: tinnakorn-laravel-rds.xxxxxxxx.ap-southeast-1.rds.amazonaws.com
・DB_PASSWORD: PassW0rd

แล้วเลื่อนลงมาด้านล่างสุด คลิก Apply

รอประมาณ 2-3 นาที แล้วคลิก Reload ก็จะแสดงแจ้งเตือนในหน้าจอแบบนี้

ตรวจสอบ Log ใน S3

เปิดหน้าเว็บไซต์โดยคลิกที่ Domain จากหน้า Environment ของเรา เช่น

http://tinnakorn-elb-log.ap-southeast-1.elasticbeanstalk.com/

แล้วจะแสดงหน้าหลัก (Home page) ของ Laravel แบบนี้

แล้วให้เข้ามาที่ S3 bucket ของเราที่สร้างไว้ก่อนหน้านี้ เช่น tinnakorn-elb-log
จากนั้นให้ระประมาณ 1-2 นาที แล้วจะเห็นโฟลเดอร์ AWSLogs/ แสดงขึ้นมาแบบนี้ (ถ้าไม่แสดงแบบนี้ให้กลับไป Reload หน้าเว็บไซต์อีกหลายๆครั้ง และกลับมาที่หน้านี้อีกครั้ง ตามด้วยคลิกปุ่ม Reload ที่นี่ แล้วรออีกสักครู่ครับ)

ทำการ Download ไฟล์ Log ดังนี้:
・เข้าไปยัง Path ตามรูปภาพด้านล่างนี้ (โฟลเดอร์ 2024/ > 06/ > 27/ จะเปลี่ยนไปตามวันที่ปัจจุบัน)
・เลือกไฟล์ Log และคลิก Download (ตัวอย่างนี้เป็นแค่การสาธิตจึงแนะนำให้ดาวน์โหลดไฟล์แรกสุดเพื่อให้ง่ายต่อการตรวจสอบ)

แตกไฟล์ gz ที่ดาวน์โหลดมา และเปิดไฟล์ Log แล้วจะแสดงข้อมูลแบบนี้

http 2024-06-27T07:56:41.282457Z app/awseb--AWSEB-x5tPHJ9gxhOc/77aeac8f6a796c71 xx.xx.xx.xx:49860 xx.xx.xx.xx:80 0.001 0.022 0.000 200 200 205 27686 "GET http://xx.xx.xx.xx:80/ HTTP/1.1" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36" - - arn:aws:elasticloadbalancing:ap-southeast-1:[AWS Account ID]:targetgroup/awseb-AWSEB-UWDYQDAZWZSR/6dd5ff3258f7bdb1 "Root=1-667d1b39-3eef6c4e4ff6931007ccfcc2" "-" "-" 0 2024-06-27T07:56:41.258000Z "forward" "-" "-" "xx.xx.xx.xx:80" "200" "-" "-" TID_a79d3b22a78a264886f2bc4eb1d338f1

เนื่องจากถูกแบ่งหัวข้อโดยเครื่องหมาย Space (ช่องว่าง) จึงได้ทำการตรวจสอบว่ามีหัวข้อใดบ้าง

http [Request type]
2024-06-27T07:56:41.282457Z [เวลาสร้าง Response]
app/awseb--AWSEB-x5tPHJ9gxhOc/77aeac8f6a796c71 [Resource ID ของ Load balancer]
xx.xx.xx.xx:49860 [IP Address ของ Client : Port number]
xx.xx.xx.xx:80 [IP Address ของ Target ที่ประมวลผล Request นี้]
0.001 [ระยะเวลาทั้งหมดตั้งแต่ช่วงเวลาที่ Load Balancer ได้รับ Request จนถึงการส่งข้อมูลไปยัง Target]
0.022 [ระยะเวลาทั้งหมดตั้งแต่ช่วงเวลาที่ Load Balancer ส่ง Request ไปยัง Target จนถึงช่วงเวลาที่ Target นั้นเริ่มส่ง Header ตอบกลับมา]
0.000 [ระยะเวลาทั้งหมดตั้งแต่ช่วงเวลาที่ Load Balancer ได้รับ Header ตอบกลับมาจาก Target จนถึงช่วงเวลาที่เริ่มส่งการตอบกลับไปยัง Client]
200 [Status code ของการตอบสนองจาก Load Balancer]
200 [Status code ของการตอบสนองจาก Target]
205 [ขนาดของ Request ที่ได้รับจาก Client (หน่วย Bytes)]
27686 [ขนาดของการตอบกลับที่ถูกส่งคืนไปยัง Client (หน่วย Bytes)]
"GET http://xx.xx.xx.xx:80/ HTTP/1.1" [Request จาก Client]
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36" [String User-Agent ที่ระบุ Client ของ Request]
- [การเข้ารหัส SSL ของ HTTPS Listener (ครั้งนี้ไม่มีเพราะว่าเป็น HTTP เท่านั้น)]
- [Protocol SSL ของ HTTPS Listener (ครั้งนี้ไม่มีเพราะว่าเป็น HTTP เท่านั้น)]
arn:aws:elasticloadbalancing:ap-southeast-1:[AWS Account ID]:targetgroup/awseb-AWSEB-UWDYQDAZWZSR/6dd5ff3258f7bdb1 [Amazon Resource Name ของ Target Group (ARN)]
"Root=1-667d1b39-3eef6c4e4ff6931007ccfcc2" [Trace ID]
"-" [SNI Domain ที่ได้รับจาก Client ใน TLS Handshake (HTTPS Listener เท่านั้น)]
"-" [ARN ของใบรับรองที่แสดงใน Client (HTTPS Listener)]
0 [ค่าระดับความสำคัญของ Rule ที่ตรงกับ Request]
2024-06-27T07:56:41.258000Z [เวลาที่ Load Balancer ได้รับ Request จาก Client]
"forward" [Action ที่ได้ดำเนินการเมื่อประมวลผลตาม Request]
"-" [URL ของ Redirect Target ใน Location Header ของ HTTP Response]
"-" [Error Code]
"xx.xx.xx.xx:80" [IP Address และ Port ของ Target ที่ประมวลผล Request นี้]
"200" [Status code จากการตอบกลับของ Target]
"-" [เหตุผลของการส่งคืนรหัสสถานะ HTTP (ไม่ได้ระบุ)]
"-" [ข้อมูลเพิ่มเติม (ไม่ได้ระบุ)]
TID_a79d3b22a78a264886f2bc4eb1d338f1 [Transaction ID สำหรับการติดตามคำขอ]

เพียงเท่านี้เราก็สามารถวิเคราะห์ข้อมูลในไฟล์ Log ของเราได้แล้วครับ

สุดท้ายนี้

ผมได้ทำการบันทึก Access Log ของ ALB ใน S3 และอ่านทำความเข้าใจเนื้อหาในไฟล์ Log ซึ่งเป็นการใช้งานที่น่าสนใจมาก เพราะเป็นครั้งแรกที่ได้ทำเกี่ยวกับจัดการไฟล์ Log ของ Load Balancer

ผมหวังว่าบทความนี้จะเป็นประโยชน์ให้กับผู้อ่านได้นะครับ

POP (Tinnakorn Maneewong) จากบริษัท Classmethod (Thailand) ครับ !

บทความต้นฉบับ

บทความนี้เป็นภาษาญี่ปุ่น

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