前言
在一次測試中,為了方便,直接使用了 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 來處理。