部署網路應用時,會對請求進行日誌保存,用於數據統計分析以及故障排除,但對於高並發請求的伺服器,日誌文件會迅速增長,快速的消耗磁碟空間,同時,分析一個大文件來排查問題也會非常慢。因此,我們通常需要將日誌按照天級別進行存儲,並對過舊的日誌進行壓縮轉存或刪除,方便節省磁碟空間和進行腳本分析。

當我第一次有這種需求的時候,最先想到的是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 work 0 Feb 28 13:40 nginx.access.log
-rw-r--r-- 1 work work 5379846 Feb 28 13:37 nginx.access.log-20190228

可以看到我們已經對日誌進行了切分,最新的日誌文件大小為0。以後系統就會對該日誌進行自動的輪轉管理。

參考資料

  1. Linux日誌文件總管——logrotate:linux.cn/article-4126-1
  2. logrotate-(8) manual page:linuxconfig.org/logrota
  3. 運維中的日誌切割操作梳理:cnblogs.com/kevingrace/

推薦閱讀:

相關文章