Linux 日誌定時輪詢流程詳解

發表於2017-06-08

logrotate介紹

對於Linux系統安全來說,日誌檔案是極其重要的工具。日誌檔案包含了關於系統中發生的事件的有用資訊,在排障過程中或者系統效能分析時經常被用到。當日志檔案不斷增長的時候,就需要定時切割,否則,寫日誌的速度和效能也會下降,更不便於我們歸檔,查詢。

所以便有了使用logrotate的時候 ,logrotate是個十分有用的工具,它可以自動對日誌進行截斷(或輪循)、壓縮以及刪除舊的日誌檔案。例如,你可以設定logrotate,讓/var/log/foo日誌檔案每30天輪循,並刪除超過6個月的日誌。配置完後,logrotate的運作完全自動化,不必進行任何進一步的人為干預。

logrotate配置檔案位置

Linux系統預設安裝logrotate工具,它預設的配置檔案在:

logrotate.conf 才主要的配置檔案,logrotate.d 是一個目錄,該目錄裡的所有檔案都會被主動的讀入/etc/logrotate.conf中執行。
另外,如果 /etc/logrotate.d/ 裡面的檔案中沒有設定一些細節,則會以/etc/logrotate.conf這個檔案的設定來作為預設值。

實際執行時,Logrotate會呼叫配置檔案/etc/logrotate.conf。

可以在/etc/logrotate.d目錄裡放置自定義好的配置檔案,用來覆蓋Logrotate的預設值。

定時輪循機制

Logrotate是基於CRON來執行的,其指令碼是/etc/cron.daily/logrotate,日誌輪轉是系統自動完成的。

logrotate這個任務預設放在cron的每日定時任務cron.daily下面 /etc/cron.daily/logrotate/etc/目錄下面還有cron.weekly/, cron.hourly/, cron.monthly/ 的目錄都是可以放定時任務的

這裡實際操作輪詢的命令最後一行
/usr/sbin/logrotate /etc/logrotate.conf

定義好了每日執行任務的指令碼cron.daily/logrotate ,再檢視crontab的內容,裡面設定好了對應的cron.xxly

執行時間

可以看出來了只要是在

  • /etc/cron.daily/ 下面的任務都是每天6:25 執行
  • /etc/cron.weekly/ 下面的任務都是每週日 6:47 執行
  • /etc/cron.monthly/ 下面的任務都是每月1號 6:52 執行

如果等不及cron自動執行日誌輪轉,想手動強制切割日誌,需要加-f引數;
不過正式執行前最好通過Debug選項來驗證一下(-d引數),這對除錯也很重要

那麼至此,我們就知道logrotate是如何實現自動切割日誌的

logrotate配置案例

nginx 常用日誌切割配置

如果要配置一個每日0點執行切割任務,怎麼做到?我們的logrotate預設每天執行時間已經寫到了/etc/cron.daily/目錄下面,而這個目錄下面的任務執行時間上面也說了,在/etc/crontab裡面定義了時6:25。我之前就有個這樣的需求,看看下面的配置

然後去root的crontab配置一個0點執行的任務

因為logrotate的切割週期是weekly,每次切割都是根據上一個切割的時間來進行,如果距離上一次有一週時間,就會切割,但是我們設定了crontab的每天切割,既不會進入/etc/cron.daily/的每日切割,也不會每週切割。這樣就能完美定製自己想要的切割日誌時間

logrotate引數說明

值得注意的一個配置是:copytruncate
copytruncate 如果沒有這個選項的話,操作方式:是將原log日誌檔案,移動成類似log.1的舊檔案, 然後建立一個新的檔案。 如果設定了,操作方式:拷貝原日誌檔案,並且將其變成大小為0的檔案。

區別是如果程式,比如nginx 使用了一個檔案寫日誌,沒有copytruncate的話,切割日誌時, 把舊日誌log->log.1 ,然後建立新日誌log。這時候nginx 開啟的檔案描述符依然時log.1,由沒有訊號通知nginx 要換日誌描述符,所以它會繼續向log.1寫日誌,這樣就不符合我們的要求了。 因為我們想切割日誌後,nginx 自動會向新的log 檔案寫日誌,而不是舊的log.1檔案

解決方法有兩個:

1.向上面的nginx 切割日誌配置,再postrotate裡面寫個指令碼

這樣就是發訊號給nginx ,讓nginx 關閉舊日誌檔案描述符,重新開啟新的日誌檔案描述,並寫入日誌

2.使用copytruncate引數,向上面說的,配置了它以後,操作方式是把log 複製一份 成為log.1,然後清空log的內容,使大小為0,那此時log依然時原來的舊log,對程式(nginx)來說,依然開啟的是原來的檔案描述符,可以繼續往裡面寫日誌,而不用傳送訊號給nginx

copytruncate這種方式操作的時候, 拷貝和清空之間有一個時間差,可能會丟失部分日誌資料。
nocopytruncate 備份日誌檔案不過不截斷

參考

Linux下logrotate日誌輪詢操作梳理

相關文章