🐧 Linux Logrotate 進階攻略:服務日誌分割、壓縮、輪替與常見錯誤排查
Linux 系統中的日誌會隨著服務運作不斷成長,若沒有妥善管理,容易造成:
- 磁碟空間被吃滿(尤其 /var/log)
- 系統效能下降
- 無法追蹤舊日誌
Logrotate 是 Linux 內建的日誌輪替工具,可自動執行以下動作:
- 日誌分割(rotation)
- 壓縮(gzip)
- 保留特定份數
- 重啟服務重新寫入日誌
- 刪除過舊的檔案
本篇將用最完整方式介紹 Logrotate 的使用、配置與常見問題排查。
📌 一、Logrotate 的運作方式
Logrotate 的配置分成兩部分:
/etc/logrotate.conf:主設定檔/etc/logrotate.d/*:服務各自的設定
大多數服務都會在 logrotate.d 裡放自己的規則,例如:
/etc/logrotate.d/nginx /etc/logrotate.d/mysql /etc/logrotate.d/rsyslog
Logrotate 通常由 cron.daily 或 systemd timer 驅動:
systemctl status logrotate.timer
📌 二、查看 Logrotate 今天有沒有執行
可以查看 logrotate 的 log:
cat /var/lib/logrotate/logrotate.status
或手動執行一次:
sudo logrotate -f /etc/logrotate.conf
📌 三、範例:自訂服務的 Logrotate 設定
1️⃣ 基礎版範例(最常用)
/var/log/myapp/*.log {
daily
rotate 14
compress
missingok
notifempty
}
解釋:
- daily:每天分割一次
- rotate 14:保留 14 天
- compress:舊日誌自動 gzip
- missingok:日誌不存在也不報錯
- notifempty:空檔案不輪替
📌 四、進階:重新啟動服務(postrotate)
有些服務在日誌切割後必須重新載入才會繼續寫入新的檔案(例如 Nginx)。
/var/log/nginx/*.log {
daily
rotate 7
missingok
compress
sharedscripts
postrotate
[ -f /run/nginx.pid ] && kill -USR1 $(cat /run/nginx.pid)
endscript
}
此範例中,Logrotate 切割日誌後會通知 Nginx 重新開啟 log。
📌 五、進階設定:限制最大檔案大小
若你希望日誌只要超過一定大小就輪替,而不是看日期,可以使用:
size 100M
範例:
/var/log/myapp/app.log {
size 100M
rotate 5
compress
}
📌 六、進階設定:copytruncate vs USR1 reload
| 方式 | 行為 | 適用情境 |
|---|---|---|
| copytruncate | 複製後清空原檔案 | 不支援 USR1 / reload 的服務(部分 App) |
| postrotate + reload | 告訴服務重新開啟 log | Nginx、Apache、MySQL、systemd 服務 |
📌 七、Logrotate 常見錯誤與排查方式
❗ 1. "error: skipping log … because parent directory has insecure permissions"
原因:目錄權限太開放,例如 777。
chmod 755 /var/log/myapp
❗ 2. Logrotate 完全沒有執行
檢查 timer:
systemctl status logrotate.timer
若關閉:
systemctl enable --now logrotate.timer
❗ 3. 切割後日誌沒更新(最常見)
原因:服務未 reload。
解法:
postrotate
systemctl reload nginx
endscript
❗ 4. “gzip: stdin: file size changed”
原因:服務持續寫入日誌。
解法:改用 copytruncate
❗ 5. logrotate.status 記錄損毀
rm /var/lib/logrotate/logrotate.status logrotate -f /etc/logrotate.conf
📌 八、專業級 Logrotate 設定模板(可直接套用)
/var/log/myapp/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
dateext
dateformat -%Y%m%d
create 0640 root adm
sharedscripts
postrotate
systemctl reload myapp.service >/dev/null 2>&1 || true
endscript
}
說明:
- delaycompress:隔一天再壓縮,避免服務還在寫入
- dateext:使用日期為副檔名
- create:自動建立新 log
- postrotate:輪替後重啟服務
📌 九、結論:Logrotate 最佳實務
- ✔ 每個服務應有自己的 logrotate 設定
- ✔ Nginx / Apache / MySQL 必須 reload log
- ✔ /var/log 建議定期監控大小
- ✔ 避免使用 777 權限,會讓 logrotate 失效
- ✔ 建議搭配 systemd timer(更穩定)
- ✔ 企業環境建議使用 dateext + delaycompress
完整掌握 Logrotate 之後,你可以有效管理大量服務日誌,避免磁碟被塞滿,讓系統運作更安全、更穩定。
沒有留言: