前言
在一次測試中,為了方便,直接使用了 Yum 安裝 nginx ,使用起來也沒差,第二天在登錄上來的時候,發現 ngx 自動對 日志進行了歸檔而且打包,如圖:

之前為了實現這個功能是通過 shell 腳本 + crond 來做,但是這次只是通過 yum install nginx -y 就實現了這個日志歸檔操作,為了究其原因,展開了學習。
Logrotate 實現日志切割
稍微一查詢發現了原來是 Logrotate 這個工具實現的日志切割,查看 logrotate 包:

總共也就這些文件,/etc/cron.daily/logrotate 一看這個文件就知道和 crond 聯系起來了。

這是一個每日執行的 cron 腳本,logrotate 實際會調用它的主配置文件:/etc/logrotate.conf
logrotate.conf 主配置文件如下:

這個主配置文件也就是起到一個默認配置項的作用,在這個配置文件中找到了 include /etc/logrotate.d 這個很容易理解,簡單來說:/etc/logrotate.d/ 是 logrotate的擴展文件夾,需要的個性化配置在這里面。
查看 /etc/logrotate.d/

/etc/logrotate 里文件就多了, 這里找到了 nginx 、php-fpm、甚至還有 zabbix-agent , 查看下 nginx

頭大, 最討厭這種異類,如果是 shell 腳本就很容易理解。沒辦法,只能查詢下具體的語法意義了。
/var/log/nginx/*log { # 需要輪詢日志路徑
create 0664 nginx root # 以指定的權限創建全新的日志文件
daily # 日志文件切割頻率 daily: 每日,monthly: 每月,weekly: 每周,yearly: 每年
rotate 10 # 一次將存儲10個歸檔日志,對於第11個歸檔,時間最久的歸檔將刪除
missingok # 在日志輪詢期間,任何錯誤將被忽略,例如:文件無法找到 之類的錯誤
notifempty # 如果文件為空,將不會對日志進行歸檔
compress # 在日志歸檔之后,對日志進行gzip壓縮
sharedscripts # 表示下面 postrotate 腳本在壓縮日志之后只執行一次
postrotate # 腳本開始
/bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true # 腳本正文
endscript # 腳本結束
}
sharedscripts / postrotate / endscript
通常是成套出現的,而這里的腳本主要也是讓程序重啟,以切換到新的日志文件
還有一個比較方便的參數,這里沒有用上:
dateext: 使用日期作為命名格式
有了以上對 logrotate 的了解,在測試環境中進行測試下具體的運行:
使用源碼編譯的 nginx 是沒有對 logrotate 設置的

為 ngx 添加 日志切割腳本:
[root@192.168.118.11 ~]#cat /etc/logrotate.d/nginx
/usr/local/nginx/logs/*log {
create 0664 nginx root
daily
dateext
rotate 10
missingok
notifempty
compress
sharedscripts
postrotate
/bin/kill -USR1 `cat /usr/local/nginx/logs/nginx.pid 2>/dev/null` 2>/dev/null || true
endscript
}
如上配置就完成了,nginx 每天日志歸檔壓縮的操作,是不是比自己編寫 shell腳本方便很多?真的是有發現新大陸的感覺。
配置完成需要調試或者運行一次驗證下,首先進行 debug 模式測試:
[root@192.168.118.11 ~]#logrotate -d -f /etc/logrotate.d/nginx
reading config file /etc/logrotate.d/nginx
Allocating hash table for state file, size 15360 B
Handling 1 logs
rotating pattern: /usr/local/nginx/logs/*log forced from command line (10 rotations)
empty log files are not rotated, old logs are removed
considering log /usr/local/nginx/logs/access.log
log needs rotating
considering log /usr/local/nginx/logs/error.log
log does not need rotating (log is empty)rotating log /usr/local/nginx/logs/access.log, log->rotateCount is 10
dateext suffix '-20200426'
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 /usr/local/nginx/logs/access.log to /usr/local/nginx/logs/access.log-20200426
creating new /usr/local/nginx/logs/access.log mode = 0664 uid = 80 gid = 0
running postrotate script
running script with arg /usr/local/nginx/logs/*log : "
/bin/kill -USR1 `cat /usr/local/nginx/logs/nginx.pid 2>/dev/null` 2>/dev/null || true
"
compressing log with: /bin/gzip
主要是關注 error ,以上沒有任何語法報錯信息,接下來就可以手動執行一次看看是否生效:
[root@192.168.118.11 ~]#logrotate -f /etc/logrotate.d/nginx
這樣就執行完成了,接下來查看下日志目錄是否歸檔:

可以發現 logrotate執行過程,首先將 access.log 重命名為 access.log-20200426 然后在使用 gzip 歸檔
這里為什么 error.log 沒有做歸檔呢?這是因為我們在 /etc/logrotate.d/nginx 中配置了參數: notifempty # 如果文件為空,將不會對日志進行歸檔。
總結
以上就實現了nginx 每天日志的歸檔驗證,比起 shell腳本效率要高很多。以后關於日志歸檔切割備份的工作,全部可以交給 logrotate 來處理。
