จัดการ Log Files ด้วย Logrotate บน VPS ไม่ให้ Disk เต็ม
Log file คือปัญหาเงียบที่ทำให้ disk เต็มโดยไม่รู้ตัว โดยเฉพาะ VPS ขนาดเล็กที่ disk ไม่มาก Logrotate ช่วย rotate, compress และลบ log เก่าอัตโนมัติ ติดมากับ Ubuntu/Debian อยู่แล้ว แค่ต้องตั้งค่าให้ถูก
โครงสร้าง Logrotate
/etc/logrotate.conf— config หลัก/etc/logrotate.d/— config แยกสำหรับแต่ละ service- รันโดย cron ทุกวันใน
/etc/cron.daily/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 แทน ข้อเสียคืออาจเสีย 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 ไม่แตะไฟล์จริง
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 นี้โดยอัตโนมัติ