標籤:
FROM : http://www.2cto.com/os/201503/381812.html
在很多實際項目中,應用程式會持續寫日誌,如果程式碼中沒有調用支援自動切分(如按filesize或date切割)的日誌庫,則記錄檔會很快增長到G層級。單機操作大檔案對後續跟進日誌來說非常不方便。
本文介紹如何利用logrotate這個工具來在應用程式外部切分日誌。
1. logrotate是什麼
logrotate是大多數linux系統內建的日誌切割工具,在shell終端輸入"man logrotate"可查看其簡介(部分摘出如下):
logrotate is designed to ease administration of systems that generate large numbers of log files. It allows automatic rotation, compression, removal, and mailing of log files.Each log file may be handled daily, weekly, monthly, or when it grows too large.
更完整的簡介可以在shell終端查看其man文檔,這裡不贅述。
總之,我們知道它可以用來切割仍在滾動的記錄檔即可,這裡的“仍在滾動”是指當前記錄檔仍在被應用程式持續進行追加寫操作。
2. logrotate的適用情境
如果檔案是靜態(即當前沒有應用程式對齊進行寫操作),則split是更常用的靜態檔案切割工具,其用法簡介見這裡,此處略過。
logrotate常用來切割仍在被寫的“動態”檔案,它支援按時間間隔或檔案大小來觸發檔案的自動切分(automatic rotation)。具體用法下面說明。
3. 如何使用logrotate
根據man logrotate的說明,logrotate用法很簡單:
?
1 |
logrotate [-dv] [-f|--force] [-s|--state file] config_file+ |
其中[]中出現的option(s)均是可選項,我們只需提供一份設定檔即可,下面用樣本對設定檔格式做說明。
?
1234567891011121314151617181920212223242526272829303132333435363738394041 |
# sample logrotate configuration file compress # 全域配置項,對切分後的檔案做gzip壓縮 # 一個設定檔中可以包含多個相互獨立的sections # 其中,待切分檔案路徑 + { xxx }構成了一個獨立的section,每個section可以配置針對該類檔案的切分行為 # 注意:全域配置項會作用於每個section,除非在該section配置中覆蓋了全域配置項的行為 # 下面section的配置表明按時間間隔(weekly)觸發日誌的自動切分,曆史資料只儲存最近的 5 份 # 切分完成後,通過發送-HUP訊號來重啟syslogd這個daemon進程。 /var/log/messages { rotate 5 weekly postrotate /sbin/killall -HUP syslogd endscript } # 下面的樣本section表明按檔案大小觸發日誌自動切分,大小單位除了上面所示的k外,還可以是M或G # 待切分檔案路徑可以有多個,多個路徑用空格隔開 "/var/log/httpd/access.log" /var/log/httpd/error.log { rotate 5 mail www @my .org size=100k sharedscripts # 表明HUP訊號只需在所有檔案均切分完成後發送一次,若無該配置,則每完成一個檔案的切分就會執行一次postrotate/endscript之間配置的命令 postrotate /sbin/killall -HUP httpd endscript } # 下面的樣本section表明按時間(monthly)觸發切分 # 切分後的曆史檔案會被儲存到olddir指定的目錄下(該目錄需要事先mkdir出來,否則會報錯) /var/log/news/news.crit { monthly rotate 2 olddir /var/log/news/old missingok # 若section起始處指定的待切分檔案不存在,也不會報錯(預設會報錯) postrotate kill -HUP ‘cat /var/run/inn.pid‘ endscript nocompress # 切分時不做壓縮,這裡改寫了設定檔第 1 行的全域配置 } |
上述設定檔中,"#"表示後面是注釋,它可以獨佔一行,也可以與配置項在同一行。
配置項"rotate 5"表明切分後的曆史檔案最多儲存最近的5份,若觸發本次切分時已有5份曆史檔案(預設為messages.1/messages.2/messages.3/messages.4/messages.5),則檔案messages.5會被物理刪除,剩餘檔案尾碼序號依次加1。
切分的具體執行過程可以參考《鳥哥的Linux私房菜》在這裡的說明。
上面的樣本設定檔只是展示了logrotate設定檔的基本格式,該工具還支援其它眾多配置項,具體可以參考man logrotate的說明。
下面的設定檔說明了在實際項目中如何按檔案大小對不允許restart的應用程式進行日誌自動切分。
?
123456789 |
# filename: logrotate.conf /home/work/running.log { copytruncate # 先copy running.log內容至曆史檔案,然後清空running.log的內容 rotate 30 # 儲存 30 份曆史日誌 size=1G # 若記錄檔達到1G,則觸發切分 olddir /home/work/history # 指定曆史日誌存放目錄 notifempty # 若/home/work/running.log是空檔案,則不做切分 missingok # 若/home/work/running.log不存在,不報錯 } |
特別注意copytruncate這個配置項,根據其文檔說明(見下面的摘錄),它可能會導致部分資料丟失,在不允許日誌資料丟失的應用情境下,不應該使用該配置(若日誌不允許丟失,則最好在應用程式代碼中支援HUP訊號來實現優雅重啟,這樣就可以避免使用copytruncate;當然,也可以用logrotate支援的create配置來達到目的)。
copytruncate
Truncate the original log file in place after creating a copy, instead of moving the old log file and optionally creating a new one, It can be used when some program can not be told to close its logfile and thus might continue writing (appending) to the previous log file forever. Note that there is a very small time slice between copying the file and truncating it, so some logging data might be lost. When this option is used, the create option will have no effect, as the old log file stays in place.=
【轉】如何利用logrotate工具自動切分滾動中的記錄檔