使用logrotate完成日誌自動切分並輪轉
部署網路應用時,會對請求進行日誌儲存,用於資料統計分析以及故障排除,但對於高併發請求的伺服器,日誌檔案會迅速增長,快速的消耗磁碟空間,同時,分析一個大檔案來排查問題也會非常慢。因此,我們通常需要將日誌按照天級別進行儲存,並對過舊的日誌進行壓縮轉存或刪除,方便節省磁碟空間和進行指令碼分析。
當我第一次有這種需求的時候,最先想到的是crontab
指令碼定時執行日誌清理指令碼。就是先編寫一個cleanLog.sh
,然後讓crontab
定期的來執行它。這個方法可行,但是比較麻煩費事,此時一個Linux
內建的工具就比較有用了:logrotate
。
logrotate
:Linux
日誌檔案總管
logrotate
(日誌輪轉工具)可以自動對日誌檔案提供截斷、壓縮以及輪轉的功能。
logrotate
工具預設安裝在linux
機器上,全域性命令在/usr/sbin/logrotate
,另外還包含兩個配置檔案:
// 全域性配置檔案,儲存的為公用的預設配置項 /etc/logrotate.conf // 子項配置資料夾,該資料夾下提供一些系統級別的日誌配置,你的自定義配置也需要配置在這裡 /etc/logrotate.d/
這個工具能做到自動執行的功能,其實還是依賴於crontab
工具,只不過這些設定系統自動完成了,我們可以檢視crontab
系統級別的日執行指令碼:
$ vim /etc/cron.daily/logrotate #!/bin/sh /usr/sbin/logrotate /etc/logrotate.conf >/dev/null 2>&1 EXITVALUE=$? if [ $EXITVALUE != 0 ]; then /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]" fi exit 0
可以看到在crontab
的日級別配置檔案目錄下有一個logrotate
子項,它會每天執行logrotate
命令,呼叫的配置為/etc/logrotate.conf
。
在實際執行中,logrotate
命令會先讀取/etc/logrotate.conf
的配置作為預設項,然後再依次讀取/etc/logrotate.d/
目錄下的各檔案配置來覆蓋預設項,並執行日誌輪轉功能。
logrotate
命令
logrotate [OPTION...] <configfile>
引數說明:
-d, --debug :
debug模式,測試配置檔案是否有錯誤。
-f, --force :
強制轉儲檔案。
-m, --mail=command :
壓縮日誌後,傳送日誌到指定郵箱。
-s, --state=statefile :
使用指定的狀態檔案。
-v, --verbose :
顯示轉儲過程。
logrotate
使用
假設我們現在有一個日誌檔案儲存在/home/work/log/nginx.access.log
,需要對其每日進行切分為新舊兩個日誌檔案,並刪除7天前的舊日誌。
首先我們建立新的日誌輪轉配置:
$vim /etc/logrotate.d/nginxAccessLog # 指定需要輪轉處理的日誌檔案 /home/work/log/nginx.access.log { # 日誌檔案輪轉週期,可用值為: daily/weekly/yearly daily # 新日誌檔案的許可權 create 0664 work work # 輪轉次數,即最多儲存7個歸檔日誌,會刪除最久的歸檔日誌 rotate 7 # 以當前日期作為命名格式 dateext # 輪循結束後,已歸檔日誌使用gzip進行壓縮 compress # 與compress共用,最近的一次歸檔不要壓縮 delaycompress # 忽略錯誤資訊 missingok # 日誌檔案為空,輪循不會繼續執行 notifempty # 當日志文件大於指定大小時,才繼續執行,單位為bytes(預設)/k/M/G size = 100M # 將日誌檔案轉儲後執行的命令,以endscript結尾,命令需要單獨成行 postrotate # 重啟nginx日誌服務,寫入到新的檔案中去,否則會依然寫入重新命名後的檔案中 /bin/kill -USR1 `cat /home/work/run/nginx.pid 2> /dev/null` 2> /dev/null || true endscript }
在使用前,我們先演練一下,也就是debug
模式,此時,不用實際輪循,而是模擬並輸出,使用強制執行是因為還沒到輪循週期:
$logrotate -d -f /etc/logrotate.d/nginxAccessLog reading config file /etc/logrotate.d/nginxAccessLog reading config info for /home/work/log/nginx.access.log Handling 1 logs rotating pattern: /home/work/log/nginx.access.log forced from command line (7 rotations) empty log files are rotated, old logs are removed considering log /home/work/log/nginx.access.log log needs rotating rotating log /home/work/log/nginx.access.log, log->rotateCount is 7 dateext suffix '-20190228' glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' glob finding old rotated logs failed renaming /home/work/log/nginx.access.log to /home/work/log/nginx.access.log-20190228 creating new /home/work/log/nginx.access.log mode = 0664 uid = 500 gid = 501 running postrotate script running script with arg /home/work/log/nginx.access.log: " /bin/kill -USR1 `cat /home/work/run/nginx.pid 2> /dev/null` 2> /dev/null || true "
可以看到整個執行流程,以及沒有什麼報錯資訊,此時我們直接繼續執行:
$logrotate -f /etc/logrotate.d/nginxAccessLog $ll /home/work/lnmp/log/ -rw-r--r-- 1 work work0 Feb 28 13:40 nginx.access.log -rw-r--r-- 1 work work5379846 Feb 28 13:37 nginx.access.log-20190228
可以看到我們已經對日誌進行了切分,最新的日誌檔案大小為0
。以後系統就會對該日誌進行自動的輪轉管理。
參考資料
- Linux日誌檔案總管——logrotate:https://linux.cn/article-4126...
- logrotate-(8) manual page:https://linuxconfig.org/logro...
- 運維中的日誌切割操作梳理:https://www.cnblogs.com/kevin...