Nginx

Log Rotation สำหรับ Nginx บน Cloud VPS — จัดการไฟล์ Log ไม่ให้ล้นเซิร์ฟเวอร์

เมื่อเซิร์ฟเวอร์ Nginx ทำงาน ไฟล์ log จะเพิ่มขึ้นเรื่อย ๆ ทุกวัน บันทึกรายการ request แต่ละรายและข้อมูลข้อผิดพลาด หากไม่มีการจัดการ ไฟล์เหล่านี้จะกินพื้นที่จัดเก็บข้อมูลจำนวนมหาศาล ลดประสิทธิภาพของเซิร์ฟเวอร์ และอาจทำให้เซิร์ฟเวอร์หยุดทำงานได้ Log rotation หรือการหมุนเวียนไฟล์ log เป็นเทคนิคสำคัญในการจัดการปัญหานี้ โดยการบีบอัด เก็บถาวร และลบไฟล์ log เก่าออกจากระบบโดยอัตโนมัติ

บทความนี้จะอธิบายวิธีตั้งค่า log rotation สำหรับ Nginx บนเซิร์ฟเวอร์ Cloud VPS ตั้งแต่พื้นฐาน การใช้เครื่องมือ logrotate ถึงการแก้ไขปัญหาทั่วไป พร้อมตัวอย่างโค้ดและ best practices สำหรับสภาพแวดล้อม production

ทำไม Log Rotation จึงสำคัญสำหรับ Nginx

ไฟล์ log ของ Nginx เก็บข้อมูลสำคัญหลายประเภท เช่น access log ที่บันทึก IP address ของผู้เยี่ยมชม วิธี request ที่ใช้ (GET/POST) และสถานะการตอบสนอง หากไฟล์เหล่านี้ไม่ได้รับการจัดการ จะเกิดปัญหาดังต่อไปนี้

  • พื้นที่จัดเก็บข้อมูลเต็ม — ไฟล์ log ขนาดใหญ่จะใช้ storage มากขึ้น และในที่สุดจะไม่มีพื้นที่เหลือสำหรับข้อมูลสำคัญ
  • ประสิทธิภาพลดลง — การเข้าถึงไฟล์ log ขนาดใหญ่ช้าลง ทำให้การวิเคราะห์ log ใช้เวลานาน
  • ความยากในการวิเคราะห์ — ไฟล์ log ขนาดใหญ่หลายพันเมกะไบต์ยากต่อการค้นหาข้อมูลเฉพาะจำนวน
  • การสูญหายของข้อมูล — บางระบบอาจหยุดทำงานหากเต็มเนื่องจากพื้นที่เก็บข้อมูล

Log rotation แก้ไขปัญหาเหล่านี้โดยการแบ่งไฟล์ log ตามช่วงเวลา บีบอัด และลบเฉพาะไฟล์เก่าที่ไม่ต้องการอีกต่อไป

พื้นฐาน Logrotate บน Linux

Logrotate เป็นเครื่องมือมาตรฐานใน Linux ที่จัดการการหมุนเวียนไฟล์ log โดยอัตโนมัติ ตัวโปรแกรมนี้ใช้งานผ่าน cron job และอ่านข้อกำหนดการจัดการจากไฟล์คอนฟิกูเรชัน

ไฟล์คอนฟิกูเรชันหลักของ logrotate อยู่ที่:

  • /etc/logrotate.conf — ไฟล์คอนฟิกูเรชันหลัก
  • /etc/logrotate.d/ — โฟลเดอร์สำหรับคอนฟิกเฉพาะแต่ละแอปพลิเคชัน

Logrotate ทำงานประมาณ 1 ครั้งต่อวัน ผ่าน cron job /etc/cron.daily/logrotate

ตำแหน่งไฟล์ Log ของ Nginx

ก่อนตั้งค่า log rotation เราต้องรู้ว่าไฟล์ log ของ Nginx อยู่ที่ไหน ตามปกติจะเป็น:

# Access log — บันทึก request ทั้งหมด
/var/log/nginx/access.log

# Error log — บันทึกข้อผิดพลาด
/var/log/nginx/error.log

# สำหรับ Virtual Host เฉพาะ
/var/log/nginx/yourdomain.com_access.log
/var/log/nginx/yourdomain.com_error.log

คุณสามารถตรวจสอบตำแหน่งจริงในไฟล์คอนฟิกูเรชัน nginx.conf ด้วยคำสั่ง:

grep -n "access_log\|error_log" /etc/nginx/nginx.conf

การตั้งค่า Logrotate สำหรับ Nginx

ขั้นตอนแรกคือสร้างไฟล์คอนฟิกูเรชัน logrotate เฉพาะสำหรับ Nginx ในโฟลเดอร์ /etc/logrotate.d/

sudo nano /etc/logrotate.d/nginx

ตัวอย่างคอนฟิกเบื้องต้น:

/var/log/nginx/*.log {
    daily
    rotate 14
    missingok
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    prerotate
        if [ -d /etc/logrotate.d/httpd-prerotate.d ]; then \
            run-parts /etc/logrotate.d/httpd-prerotate.d; \
        fi
    endscript
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
    endscript
}

อธิบายรายละเอียด Logrotate Directives

ทีละตัวเลือกหลัก:

1. daily / weekly / monthly — ความถี่ในการหมุนเวียน

daily     # หมุนเวียนทุกวัน (แนะนำสำหรับ Nginx บน production)
weekly    # หมุนเวียนสัปดาห์ละครั้ง
monthly   # หมุนเวียนเดือนละครั้ง
yearly    # หมุนเวียนปีละครั้ง

2. rotate — จำนวนไฟล์ log เก่าที่เก็บไว้

rotate 14  # เก็บไฟล์ log 14 ไฟล์เก่า หลังจากนั้นจะลบ

3. compress — บีบอัดไฟล์ log

compress       # บีบอัดไฟล์เก่าด้วย gzip ตั้งแต่รอบ 2 เป็นต้นไป
delaycompress  # รอวันถัดไปแล้วจึงบีบอัด (เพื่อให้ app อ่านได้อีกวันนึง)

4. missingok — ไม่ผิดพลาดถ้าไฟล์ไม่พบ

missingok  # หากไฟล์ log ไม่มี logrotate จะไม่ส่งข้อผิดพลาด

5. notifempty — ไม่หมุนเวียนหากไฟล์ว่างเปล่า

notifempty  # ข้ามการหมุนเวียนหากไฟล์ขนาด 0 bytes

6. create — สร้างไฟล์ log ใหม่

create 0640 www-data adm
# สร้างไฟล์ log ใหม่พร้อมกำหนด:
# - Permission: 0640 (rw-r-----)
# - Owner: www-data
# - Group: adm

7. postrotate — คำสั่งหลังหมุนเวียน

postrotate
    [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
# หลังหมุนเวียนเสร็จ ส่งสัญญาณ USR1 ให้กับ Nginx
# เพื่อให้ Nginx เปิดไฟล์ log ใหม่

สัญญาณ USR1 สำหรับการเปิดไฟล์ Log ใหม่

สัญญาณ USR1 เป็นสิ่งที่สำคัญในการหมุนเวียน log ของ Nginx เมื่อไฟล์ log ถูกหมุนเวียน ไฟล์เก่าจะได้รับชื่อใหม่ แต่ process ของ Nginx ยังคงเขียนข้อมูลไปที่ inode เดิม หากไม่ส่งสัญญาณ USR1 Nginx จะเขียนต่อไปที่ไฟล์เก่าแทนที่จะเขียนไปที่ไฟล์ใหม่

# ส่งสัญญาณ USR1 ให้กับ Nginx process
kill -USR1 $(cat /var/run/nginx.pid)

# หรือใช้ nginx command
nginx -s reload

การหมุนเวียน Log ด้วย Shell Script

นอกจาก logrotate ยังสามารถสร้าง script เองเพื่อจัดการ log rotation ด้วย shell script ได้

#!/bin/bash
# rotate_nginx_logs.sh

LOG_DIR="/var/log/nginx"
BACKUP_DIR="/var/log/nginx/backup"
DATE=$(date +%Y%m%d_%H%M%S)

# สร้างโฟลเดอร์ backup หากไม่มี
mkdir -p $BACKUP_DIR

# หมุนเวียน access log
if [ -f "$LOG_DIR/access.log" ]; then
    mv "$LOG_DIR/access.log" "$BACKUP_DIR/access_$DATE.log"
    gzip "$BACKUP_DIR/access_$DATE.log"
    touch "$LOG_DIR/access.log"
    chown www-data:adm "$LOG_DIR/access.log"
    chmod 0640 "$LOG_DIR/access.log"
fi

# หมุนเวียน error log
if [ -f "$LOG_DIR/error.log" ]; then
    mv "$LOG_DIR/error.log" "$BACKUP_DIR/error_$DATE.log"
    gzip "$BACKUP_DIR/error_$DATE.log"
    touch "$LOG_DIR/error.log"
    chown www-data:adm "$LOG_DIR/error.log"
    chmod 0640 "$LOG_DIR/error.log"
fi

# ส่งสัญญาณให้ Nginx ปิด/เปิด log file
kill -USR1 $(cat /var/run/nginx.pid)

# ลบไฟล์ log เก่าที่เก็บไว้กว่า 30 วัน
find $BACKUP_DIR -name "*.log.gz" -mtime +30 -delete

echo "Log rotation completed at $(date)"

บันทึก script ไว้ในไฟล์ /usr/local/bin/rotate_nginx_logs.sh และให้สิทธิ execute:

sudo chmod +x /usr/local/bin/rotate_nginx_logs.sh

ตั้งค่า Cron Job สำหรับการหมุนเวียนอัตโนมัติ

เพื่อให้ log rotation เกิดขึ้นอัตโนมัติ จำเป็นต้องตั้ง cron job ให้เรียกใช้ script หรือ logrotate

sudo crontab -e

เพิ่มบรรทัดต่อไปนี้เพื่อให้ script ทำงานทุกวันเวลา 2:00 น.

# หมุนเวียน Nginx log ทุกวันเวลา 2:00 น.
0 2 * * * /usr/local/bin/rotate_nginx_logs.sh >> /var/log/nginx_rotation.log 2>&1

หรือหากใช้ logrotate ในบริจาค (Debian/Ubuntu):

# Cron job สำหรับ logrotate ทำงานทุกวันเวลา 3:00 น.
0 3 * * * /usr/sbin/logrotate /etc/logrotate.conf >> /var/log/logrotate.log 2>&1

การตรวจสอบไฟล์ Log ที่ใหญ่เกินไป

เพื่อตรวจสอบขนาดของไฟล์ log และตรวจจับปัญหาได้เร็ว สามารถใช้คำสั่ง:

# ดูขนาดไฟล์ log
du -sh /var/log/nginx/*

# ดูไฟล์ที่ใหญ่ที่สุด
ls -lhS /var/log/nginx/ | head -10

# นับจำนวน log file
ls -1 /var/log/nginx/ | wc -l

# ดูการใช้ disk space ในโฟลเดอร์ log
df -h /var/log

Log Rotation สำหรับ Nginx ใน Docker / Container

หากใช้ Nginx บน Docker Container สถานการณ์จะต่างไปเล็กน้อย ไฟล์ log อาจไม่อยู่บน host machine แต่อยู่ใน container filesystem

วิธี 1: Logrotate ภายใน Container

ติดตั้ง logrotate ภายใน Docker image และตั้งค่า cron:

FROM nginx:latest

# ติดตั้ง logrotate และ supervisor
RUN apt-get update && apt-get install -y logrotate supervisor

# คัดลอกไฟล์ logrotate config
COPY logrotate-nginx.conf /etc/logrotate.d/nginx

# คัดลอกไฟล์ supervisor config
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

วิธี 2: Docker Logging Driver

ใช้ docker logging driver เพื่อเลี่ยงการเก็บ log ภายใน container:

docker run -d \
  --name nginx \
  --log-driver json-file \
  --log-opt max-size=10m \
  --log-opt max-file=5 \
  nginx:latest

หรือใน docker-compose.yml:

version: '3.8'
services:
  nginx:
    image: nginx:latest
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "5"

การทดสอบ Logrotate

ก่อนปรับใช้งาน ควรทดสอบคอนฟิก logrotate ก่อน:

# ดูว่า logrotate จะทำอะไร (dry run)
sudo logrotate -d /etc/logrotate.d/nginx

# บังคับให้ logrotate ทำงาน (ทั้งในการสอบ)
sudo logrotate -f /etc/logrotate.d/nginx

แก้ไขปัญหาทั่วไป

ปัญหา: Log file ยังบันทึกไปที่ไฟล์เก่า

สาเหตุ: Nginx process ไม่ได้รับสัญญาณ USR1 หลังการหมุนเวียน

# ตรวจสอบว่าไฟล์ PID ของ Nginx มีอยู่หรือไม่
ls -la /var/run/nginx.pid

# ส่งสัญญาณ USR1 ด้วยมือ
sudo kill -USR1 $(cat /var/run/nginx.pid)

# ตรวจสอบ log
tail -f /var/log/nginx/error.log

ปัญหา: Logrotate ไม่ทำงาน

ตรวจสอบสิทธิ์ของไฟล์ config และเรียกใช้ด้วย sudo:

# ตรวจสอบสิทธิ์
ls -la /etc/logrotate.d/nginx

# ลองเรียกด้วย sudo
sudo /usr/sbin/logrotate -f /etc/logrotate.d/nginx

# ดูสถานะ logrotate
sudo logrotate -d /etc/logrotate.d/nginx

ปัญหา: Permission denied เมื่อหมุนเวียน

ตรวจสอบสิทธิ์ของโฟลเดอร์ log:

# ตรวจสอบสิทธิ์โฟลเดอร์
ls -ld /var/log/nginx/

# กำหนดสิทธิ์ที่ถูกต้อง
sudo chmod 755 /var/log/nginx/
sudo chmod 644 /var/log/nginx/*.log

Best Practices สำหรับ Production

  • ตั้ง daily rotation — หมุนเวียนทุกวัน เพื่อเก็บขนาดไฟล์ให้เล็กและจัดการได้ง่าย
  • เก็บ 14-30 วัน — ความสมดุลระหว่างการจัดเก็บข้อมูลและการใช้ storage
  • บีบอัด log เก่า — ใช้ compress เพื่อประหยัด disk space
  • กำหนดสิทธิ์ที่ปลอดภัย — ใช้ create directive เพื่อตั้งสิทธิ์ที่ถูกต้อง
  • เก็บ log โครงการ rotation — บันทึก output ของ logrotate เพื่อตรวจสอบปัญหา
  • จัดการ log ของ Virtual Host แยกกัน — ตั้งค่า logrotate สำหรับแต่ละ virtual host
  • ใช้ Log Aggregation Tool — บน production ใหญ่ๆ ใช้เครื่องมือเก็บ log เช่น ELK Stack, Splunk, Datadog
  • เฝ้าดูสถานะ — ตั้ง alert หากไฟล์ log ใหญ่เกิน threshold

การกำหนดค่าขั้นสูง: หลายไฟล์ Log

สำหรับเซิร์ฟเวอร์ที่มี virtual host หลายชุด สามารถตั้งค่า logrotate ให้จัดการทีละไฟล์:

# /etc/logrotate.d/nginx-vhosts
/var/log/nginx/example.com_access.log {
    daily
    rotate 30
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    postrotate
        kill -USR1 $(cat /var/run/nginx.pid) 2>/dev/null || true
    endscript
}

/var/log/nginx/example.com_error.log {
    daily
    rotate 30
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    postrotate
        kill -USR1 $(cat /var/run/nginx.pid) 2>/dev/null || true
    endscript
}

วิธีตรวจสอบสถานะ Log Rotation

ตรวจสอบสถานะการหมุนเวียนผ่านคำสั่ง:

# ดูไฟล์ log เก่า
ls -lart /var/log/nginx/

# ดู log ของ logrotate เอง
cat /var/log/logrotate.log

# ตรวจสอบไฟล์ที่บีบอัดแล้ว
ls -la /var/log/nginx/*.gz

# นับไฟล์ log
find /var/log/nginx/ -name "*.gz" | wc -l

สรุป

Log rotation เป็นส่วนสำคัญในการจัดการ Nginx บนเซิร์ฟเวอร์ production ไม่ว่าจะใช้ logrotate หรือ script เอง หลักการคือ ต้องจัดการไฟล์ log ให้ไม่เต็มพื้นที่เก็บข้อมูล และต้องส่งสัญญาณ USR1 ให้กับ Nginx หลังการหมุนเวียน เพื่อให้ process เปิดไฟล์ log ใหม่

ประโยชน์หลักของ log rotation ได้แก่ การประหยัด disk space การจัดการไฟล์ log ที่ง่ายขึ้น และประสิทธิภาพที่ดีขึ้น โดยการเปลี่ยนแปลงเพียงเล็กน้อยในโฟลเดอร์ /etc/logrotate.d/ และการตั้ง cron job สามารถทำให้ระบบ log ทำงานได้อย่างมีประสิทธิภาพบน Cloud VPS

แนะนำบริการ Cloud VPS จาก Dot Enterprise

หากคุณต้องการตั้งค่า Nginx บนเซิร์ฟเวอร์ที่มีการจัดการและ support ที่ดี Dot Enterprise ขอแนะนำบริการ Cloud VPS และ Cloud Hosting

  • Cloud VPS จาก DE — เซิร์ฟเวอร์เสมือนแบบ Full Root Access ที่คุณสามารถติดตั้ง Nginx, logrotate และจัดการ log rotation ได้อย่างเต็มที่ รองรับการสเกลได้ตามความต้องการและมี support 24/7
  • Cloud Hosting จาก DE — บริการ hosting ที่มี Nginx preconfigured สำหรับเวบไซต์ WordPress และแอปพลิเคชันเว็บอื่นๆ พร้อมการจัดการ log rotation โดยอัตโนมัติ

ทั้ง Cloud VPS และ Cloud Hosting ของ DE ใช้ infrastructure ที่เสถียร ราคาแข่งขัน และ support team พร้อมช่วยคุณตั้งค่าและแก้ไขปัญหาตั้งแต่วันแรก โปรดติดต่อ https://de.co.th เพื่อข้อมูลเพิ่มเติมและเริ่มต้นใช้บริการวันนี้