Server log monitoring management

จัดการ Log Files ด้วย Logrotate บน VPS ไม่ให้ Disk เต็ม

มิถุนายน 2026 · อ่าน 6 นาที

Log file คือปัญหาเงียบที่ทำให้ disk เต็มโดยไม่รู้ตัว โดยเฉพาะ VPS ขนาดเล็กที่ disk ไม่มาก Logrotate ช่วย rotate, compress และลบ log เก่าอัตโนมัติ ติดมากับ Ubuntu/Debian อยู่แล้ว แค่ต้องตั้งค่าให้ถูก


โครงสร้าง Logrotate

ตัวอย่าง Config สำหรับ Nginx

/var/log/nginx/*.log {
    daily          # rotate ทุกวัน
    missingok      # ไม่ error ถ้าไม่มีไฟล์
    rotate 14      # เก็บ 14 รอบ (14 วัน)
    compress       # compress ด้วย gzip
    delaycompress  # compress รอบก่อน (ปัจจุบันยังไม่ compress)
    notifempty     # ไม่ rotate ถ้าไฟล์ว่าง
    sharedscripts  # รัน script ครั้งเดียวสำหรับทุก log
    postrotate
        nginx -s reopen
    endscript
}

Config สำหรับ MySQL / MariaDB

/var/log/mysql/*.log {
    weekly
    rotate 4
    compress
    delaycompress
    missingok
    notifempty
    create 640 mysql adm
    postrotate
        mysqladmin flush-logs
    endscript
}

Config สำหรับ Application Log ทั่วไป

/var/www/myapp/logs/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    dateext           # ใส่วันที่ในชื่อไฟล์ backup
    dateformat -%Y%m%d
    copytruncate      # copy แล้ว truncate แทน rename (ถ้าแอปยังเปิดไฟล์อยู่)
}

ทดสอบ Config โดยไม่ rotate จริง

logrotate -d /etc/logrotate.d/nginx

-d คือ dry-run แสดงผลว่าจะทำอะไรบ้างโดยไม่แตะไฟล์จริง

Force Rotate ทันที

logrotate -f /etc/logrotate.d/nginx

ดู Log ที่ Rotate แล้ว

ls -lh /var/log/nginx/
# จะเห็นไฟล์ .gz เรียงตามวันที่
# access.log.1, access.log.2.gz, access.log.3.gz ...

ตรวจสอบ Disk ก่อน-หลัง

# ดูขนาด log directory
du -sh /var/log/*

# ดู disk ทั้งหมด
df -h
copytruncate vs rename: Default คือ rename (เร็วและ atomic) แต่ถ้า process เปิด file handle ค้างอยู่ใช้ copytruncate แทน ข้อเสียคืออาจเสีย log เล็กน้อยช่วง copy

สรุป

Logrotate ตั้งครั้งเดียวแล้วทำงานเองตลอด ไม่ต้องกังวลเรื่อง disk เต็มจาก log อีก ควรตรวจ df -h เป็นประจำและตั้ง alert เมื่อ disk เกิน 80%

ตรวจสอบว่า Logrotate ทำงานถูกต้อง

# ดู status ว่า rotate ล่าสุดเมื่อไร
cat /var/lib/logrotate/status | grep nginx

# ดู log ของ logrotate เอง
cat /var/log/syslog | grep logrotate

# ตรวจ config syntax
logrotate -d /etc/logrotate.d/nginx
# -d คือ dry-run ไม่แตะไฟล์จริง
ดู disk ที่ถูกใช้โดย log: รัน du -sh /var/log/* เพื่อดูว่า service ไหนกิน disk มากที่สุด แล้วตั้ง rotate frequency ให้เหมาะสม

แก้ปัญหาที่พบบ่อย

Error: "error: skipping ... because parent directory has insecure permissions"

Owner ของ /etc/logrotate.d/ หรือ config file ไม่ถูกต้อง:

# ตรวจ permission
ls -la /etc/logrotate.d/
# ต้องเป็น root:root และ 644

# แก้ไข
chown root:root /etc/logrotate.d/myapp
chmod 644 /etc/logrotate.d/myapp

Log หายหลัง rotate / service เขียน log ไม่ได้

บาง service เปิด file handle ค้างไว้ ต้องใช้ copytruncate หรือส่ง signal:

# ใช้ copytruncate สำหรับ process ที่เปิดไฟล์ค้าง
/var/www/myapp/logs/*.log {
    daily
    rotate 30
    compress
    copytruncate   # copy แทน rename
    missingok
    notifempty
}

Logrotate ไม่รันตามกำหนด (cron ไม่ทำงาน)

# ตรวจ cron service
systemctl status cron
# หรือ crond บน AlmaLinux

# ตรวจว่า logrotate อยู่ใน cron.daily
ls /etc/cron.daily/ | grep logrotate

# รัน manual เพื่อทดสอบ
logrotate -f /etc/logrotate.conf

Error: "nginx: error while loading shared libraries" หลัง postrotate

Script postrotate ผิดพลาด Nginx reload ไม่ได้ ตรวจ nginx config ก่อน:

# ทดสอบ nginx config
nginx -t

# ถ้าไม่ได้ใช้ nginx แต่ใช้ Apache แก้ postrotate
postrotate
    apache2ctl graceful 2>/dev/null || true
endscript

คำถามที่พบบ่อย

ควรตั้ง rotate กี่วัน?

ขึ้นอยู่กับขนาด log และ disk ที่มี แนะนำ: web access log ตั้ง daily rotate 14 (2 สัปดาห์) สำหรับ VPS disk ขนาดเล็ก application log ตาม retention requirement ของงาน

log ที่ compress ด้วย gzip อ่านได้ยังไง?

zcat access.log.2.gz | head -50
zgrep "404" access.log.2.gz
# หรือ gunzip มาก่อน

logrotate เขียน config เพิ่มเองได้ที่ไหน?

สร้างไฟล์ใหม่ใน /etc/logrotate.d/ ชื่อไฟล์ตามชื่อ service เช่น /etc/logrotate.d/myapp logrotate จะอ่านทุกไฟล์ใน directory นี้โดยอัตโนมัติ