ตั้งค่า logrotate ไม่ให้ไฟล์ Log เต็มดิสก์
ไฟล์ Log ที่ไม่มีใครดูแลจะโตขึ้นเรื่อย ๆ จนวันหนึ่งดิสก์เต็ม ฐานข้อมูลเขียนไม่ได้ และเว็บล่ม logrotate คือเครื่องมือมาตรฐานของ Linux ที่ทำหน้าที่หมุนเวียนไฟล์ Log โดยเปลี่ยนชื่อไฟล์ปัจจุบันเป็นไฟล์เก่า เริ่มไฟล์ใหม่ บีบอัดไฟล์เก่า และลบไฟล์ที่เก่าเกินจำนวนที่กำหนด แพ็กเกจอย่าง Nginx, Apache และ MariaDB มีการตั้งค่า logrotate มาให้แล้ว แต่ Log ของแอปที่คุณเขียนเองหรือโฟลเดอร์ Log ที่สร้างขึ้นใหม่ ต้องตั้งค่าเอง
สิ่งที่ต้องเตรียม
- เซิร์ฟเวอร์ Ubuntu 22.04/24.04 หรือ AlmaLinux/Rocky Linux 8-9 ที่มีแพ็กเกจ
logrotate(ติดตั้งมาเป็นค่าเริ่มต้น) - สิทธิ์ sudo
- Path ของไฟล์ Log ที่ต้องการควบคุม เจ้าของไฟล์ และวิธีที่แอปเปิดไฟล์ Log (เพื่อเลือกระหว่าง
postrotateกับcopytruncate)
ขั้นตอนที่ 1: ทำความเข้าใจโครงสร้างการตั้งค่า
ไฟล์หลักคือ /etc/logrotate.conf ซึ่งกำหนดค่าเริ่มต้นและดึงไฟล์ทุกไฟล์ใน /etc/logrotate.d/ เข้ามา แต่ละแพ็กเกจจะมีไฟล์ของตัวเองในโฟลเดอร์นั้น ดูตัวอย่างได้ด้วย
ls /etc/logrotate.d/
cat /etc/logrotate.d/nginx
logrotate ไม่ได้ทำงานตลอดเวลา แต่ถูกเรียกวันละครั้ง ตรวจได้ว่าเครื่องของคุณเรียกด้วยวิธีใด
systemctl list-timers | grep logrotate
ls /etc/cron.daily/ | grep logrotate
Ubuntu 22.04/24.04 และ AlmaLinux/Rocky 9 ใช้ systemd timer ชื่อ logrotate.timer ส่วน AlmaLinux/Rocky 8 ใช้สคริปต์ใน /etc/cron.daily/ ไม่ว่าแบบใด ค่า daily หรือ weekly ในการตั้งค่าหมายถึงเงื่อนไขว่าไฟล์ถึงรอบแล้วหรือยัง ณ ตอนที่ logrotate ถูกเรียก
ขั้นตอนที่ 2: สร้างการตั้งค่าสำหรับ Log ของแอป
ตัวอย่างนี้ใช้แอปที่เขียน Log ไว้ที่ /var/www/example.com/storage/logs/*.log โดยไฟล์เป็นของผู้ใช้ deploy กลุ่ม www-data สร้างไฟล์ใหม่
sudo nano /etc/logrotate.d/example-app
/var/www/example.com/storage/logs/*.log {
daily
rotate 14
maxsize 200M
missingok
notifempty
compress
delaycompress
dateext
su deploy www-data
create 0664 deploy www-data
sharedscripts
postrotate
systemctl reload php8.3-fpm > /dev/null 2>&1 || true
endscript
}
ความหมายของแต่ละคำสั่ง
| คำสั่ง | ความหมาย |
|---|---|
daily / weekly / monthly | รอบการหมุนเวียน |
rotate 14 | เก็บไฟล์เก่าไว้ 14 ชุด เกินจากนี้ลบทิ้ง |
maxsize 200M | หมุนก่อนถึงรอบถ้าไฟล์ใหญ่เกิน 200 MB (ตรวจเฉพาะตอนที่ logrotate ถูกเรียก) |
missingok | ไม่ถือเป็น Error ถ้าไม่พบไฟล์ |
notifempty | ไม่หมุนไฟล์ที่ว่าง |
compress / delaycompress | บีบอัดไฟล์เก่าด้วย gzip แต่เว้นไฟล์ล่าสุดไว้หนึ่งรอบ เผื่อแอปยังเขียนค้างอยู่ |
dateext | ต่อท้ายชื่อไฟล์ด้วยวันที่ เช่น app.log-20260919 แทนเลข .1 .2 |
su deploy www-data | ทำงานในนามผู้ใช้และกลุ่มนี้ จำเป็นเมื่อโฟลเดอร์ไม่ได้เป็นของ root |
create 0664 deploy www-data | สร้างไฟล์ใหม่ด้วยสิทธิ์และเจ้าของที่กำหนด |
sharedscripts + postrotate | รันคำสั่งหลังหมุนเพียงครั้งเดียวแม้จะมีหลายไฟล์ |
ปรับชื่อ Service ใน postrotate ให้ตรงกับเครื่อง บน AlmaLinux/Rocky ใช้ php-fpm และกลุ่ม Web Server มักเป็น apache หรือ nginx
ขั้นตอนที่ 3: เลือกระหว่าง postrotate กับ copytruncate
โปรแกรมที่เปิดไฟล์ Log ค้างไว้จะเขียนต่อลงไฟล์เดิมแม้ไฟล์จะถูกเปลี่ยนชื่อไปแล้ว จึงต้องบอกให้โปรแกรมเปิดไฟล์ใหม่ มี 2 วิธี
- postrotate + reload: ส่งสัญญาณให้โปรแกรมเปิดไฟล์ใหม่ เช่น Nginx ใช้
kill -USR1กับ Master Process ซึ่งไฟล์/etc/logrotate.d/nginxของแพ็กเกจทำไว้ให้แล้ว วิธีนี้ไม่ทำให้ Log หาย - copytruncate: คัดลอกไฟล์ไปเป็นไฟล์เก่า แล้วตัดไฟล์เดิมให้ว่าง ใช้กับโปรแกรมที่ไม่รองรับการเปิดไฟล์ใหม่ เช่น สคริปต์ที่เขียนด้วย
>>แต่มีโอกาสสูญเสีย Log ไม่กี่บรรทัดที่เขียนระหว่างคัดลอก และต้องมีพื้นที่ว่างเท่าขนาดไฟล์ชั่วคราว
แอป PHP ส่วนใหญ่ เช่น Laravel เปิดและปิดไฟล์ทุกครั้งที่เขียน จึงไม่จำเป็นต้องมี postrotate ก็ได้ ถ้าไม่แน่ใจให้ใช้ copytruncate แทน create และ postrotate ห้ามใช้ copytruncate พร้อมกับ create
ขั้นตอนที่ 4: ทดสอบด้วยโหมด debug
sudo logrotate -d /etc/logrotate.d/example-app
-d แสดงว่า logrotate จะทำอะไรโดยไม่เปลี่ยนไฟล์จริง ผลที่คาดหวังคือบรรทัดอย่าง considering log /var/www/example.com/storage/logs/laravel.log ตามด้วย log does not need rotating หรือ log needs rotating ถ้ามี Error ของ Syntax จะแสดงตรงนี้
เมื่อผลถูกต้อง ให้บังคับหมุนหนึ่งครั้งเพื่อทดสอบจริง
sudo logrotate -v -f /etc/logrotate.d/example-app
ls -lh /var/www/example.com/storage/logs/
ควรเห็นไฟล์ Log ใหม่ขนาดเล็ก และไฟล์เก่าที่มีวันที่ต่อท้าย
หมายเหตุ: การรัน
-fกับไฟล์/etc/logrotate.confทั้งไฟล์จะบังคับหมุน Log ทุกตัวในระบบ ให้ทดสอบเฉพาะไฟล์การตั้งค่าของคุณเอง
ขั้นตอนที่ 5: ตัวอย่างการตั้งค่าอื่นที่ใช้บ่อย
Log ของสคริปต์ Cron ที่เขียนต่อท้ายไฟล์ ขนาดไม่แน่นอน เก็บไว้ 8 สัปดาห์
/var/log/backup-script.log {
weekly
rotate 8
compress
missingok
notifempty
copytruncate
}
Log ของ Nginx แยกตามเว็บไซต์ที่อยู่นอก /var/log/nginx/ ให้ใช้การตั้งค่าเดียวกับของแพ็กเกจ โดยคัดลอกบล็อก postrotate จาก /etc/logrotate.d/nginx มาใช้ เพื่อให้ส่งสัญญาณเปิดไฟล์ใหม่ด้วยวิธีเดียวกัน
สำหรับ Log ของ Docker Container ไม่ต้องใช้ logrotate ให้ตั้งค่าที่ Docker แทน ดู จำกัดขนาด Log ของ Docker Container
ตรวจสอบผลลัพธ์
sudo cat /var/lib/logrotate/status | grep example.com
du -sh /var/www/example.com/storage/logs/
บน AlmaLinux/Rocky ไฟล์สถานะอยู่ที่ /var/lib/logrotate/logrotate.status ไฟล์นี้บันทึกวันที่หมุนครั้งล่าสุดของแต่ละไฟล์ หลังผ่านไป 2-3 วัน ให้ตรวจว่ามีไฟล์ .gz เพิ่มขึ้นตามรอบ และขนาดรวมของโฟลเดอร์ไม่โตขึ้นเรื่อย ๆ
ปัญหาที่พบบ่อย
error: skipping ... because parent directory has insecure permissions
โฟลเดอร์ที่เก็บ Log เขียนได้โดยผู้ใช้ที่ไม่ใช่ root หรือเขียนได้โดยกลุ่ม logrotate จึงไม่ยอมทำงานเพื่อความปลอดภัย ให้เพิ่มคำสั่ง su ผู้ใช้ กลุ่ม ที่ตรงกับเจ้าของโฟลเดอร์ตามตัวอย่างในขั้นตอนที่ 2
หมุนแล้วแต่ df ยังแสดงว่าดิสก์เต็ม
โปรแกรมยังเปิดไฟล์เก่าที่ถูกลบค้างไว้ พื้นที่จึงยังไม่คืน ตรวจด้วย sudo lsof +L1 ถ้าพบไฟล์ที่มีคำว่า (deleted) ให้ reload หรือ restart Service นั้น แล้วปรับการตั้งค่าให้มี postrotate หรือ copytruncate การหาไฟล์ใหญ่อื่น ๆ ดูที่ ดิสก์เต็ม: ตรวจสอบพื้นที่และหาไฟล์ขนาดใหญ่บน Linux
แอปเขียน Log ไม่ได้หลังหมุน (Permission denied)
ไฟล์ใหม่ถูกสร้างด้วยเจ้าของหรือสิทธิ์ที่แอปเขียนไม่ได้ แก้ค่า create ให้ตรงกับผู้ใช้ที่แอปรันอยู่ ตรวจด้วย ls -l และอ่านเรื่องสิทธิ์ใน ทำความเข้าใจสิทธิ์ไฟล์บน Linux ด้วย chmod และ chown
Log ไม่หมุนเลยแม้ถึงรอบ
ตรวจว่า timer หรือ cron ของ logrotate ทำงานอยู่ด้วย systemctl status logrotate.timer และดูผลการรันล่าสุดด้วย sudo journalctl -u logrotate ถ้ามีไฟล์การตั้งค่าใดไฟล์หนึ่งผิด Syntax อาจทำให้รอบนั้นแจ้ง Error ทั้งรอบได้
หากทำตามขั้นตอนแล้วยังติดปัญหา สามารถติดต่อทีมงาน THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/ โดยแจ้งชื่อเซิร์ฟเวอร์ ระบบปฏิบัติการ คำสั่งที่ใช้ และข้อความ Error ที่พบ เพื่อให้ตรวจสอบได้รวดเร็วขึ้น
- Categories:
- Cloud
- Tags:
- Cloud
- Cloud Server
Related Posts
หมวดหมู่ที่น่าสนใจ
- Account Settings
- AD Server
- AI
- Alibaba Cloud
- Anti-Spam Gateway
- AWS Amazon Web Services
- Campaign
- CentOS/AlmaLinux
- Cloud
- Cloud Backup
- Cloud Communication
- Cloud Migration
- Cloud Security
- Cloud Server Management
- Cloud Solution
- Cloud Solution for Government
- Cloud Solutions by Industry
- Cloud Storage
- Cloud VPS App Plus +
- Cloud VPS DirectAdmin
- Cloud VPS Plesk
- CSR
- Cyber Security
- Cybersecurity
- Data Sovereignty
- Database Server
- DDoS
- Digital Tranformation
- Digital Transformation
- Direct Mail
- Directadmin
- Domainname
- Ecommerce
- ERP
- Generative AI
- Getting Started
- Google Cloud
- Google G Suite
- Huawei Cloud
- IT News
- Linux Server
- Managed Cloud Services
- Managed Service Provider
- Manual
- Microsoft
- Microsoft 365
- Microsoft Azure
- News
- On-premise
- Private Mail Server
- Promotion
- Recommend Solution (Enterprise)
- Server
- Sovereign Cloud
- THAI DATA CLOUD Platform
- Ubuntu
- Ubuntu
- Uncategorized
- VMware
- VPS Server
- Web Design
- Web Hosting
- Web Hosting (DirectAdmin)
- Web Hosting (Plesk)
- Web Technologies
- Windows Server
- Wordpress
- Zimbra
- เรื่องราวความประทับใจ
- โซลูชันสำหรับธุรกิจการผลิตและยานยนต์
- โซลูชันสำหรับธุรกิจการศึกษา
- โซลูชันสำหรับธุรกิจการเงิน
- โซลูชันสำหรับธุรกิจขนส่งและกระจายสินค้า
- โซลูชันสำหรับธุรกิจค้าปลีก
- โซลูชันสำหรับธุรกิจท่องเที่ยว
- โซลูชันสำหรับธุรกิจบริการสุขภาพและโรงพยาบาล
- โซลูชันสำหรับธุรกิจประกันภัย
- โซลูชันสำหรับธุรกิจพลังงานและสาธารณูปโภค
- โซลูชันสำหรับธุรกิจสื่อสารมวลชนและเอ็นเตอร์เทนเมนท์
- โซลูชันสำหรับธุรกิจอสังหาริมทรัพย์
- โซลูชันสำหรับธุรกิจเทคโนโลยี


