logrotate---日誌分割
logrotate命令用於對系統日誌進行輪轉、壓縮和刪除,也可以將日誌傳送到指定郵箱。使用logrotate指令,可讓你輕鬆管理系統所產生的記錄檔案。每個記錄檔案都可被設定成每日,每週或每月處理,也能在檔案太大時立即處理。您必須自行編輯,指定配置檔案,預設的配置檔案存放在/etc/logrotate.conf
檔案中。
語法
logrotate(選項)(引數)
選項
-?或--help:線上幫助; -d或--debug:詳細顯示指令執行過程,便於排錯或瞭解程式執行的情況; -f或--force :強行啟動記錄檔案維護操作,縱使logrotate指令認為沒有需要亦然; -s<狀態檔案>或--state=<狀態檔案>:使用指定的狀態檔案; -v或--version:顯示指令執行過程; -usage:顯示指令基本用法。
引數
配置檔案:指定lograote指令的配置檔案。
詳解:
我發現很多人的伺服器上都執行著一些諸如每天切分Nginx日誌之類的CRON指令碼,大家似乎遺忘了Logrotate,爭相發明自己的輪子,這真是讓人沮喪啊!就好比明明身邊躺著現成的性感美女,大家卻忙著自娛自樂,罪過!
Logrotate的介紹
顯而易見,Logrotate是基於CRON來執行的,其指令碼是「/etc/cron.daily/logrotate」:
#!/bin/sh /usr/sbin/logrotate /etc/logrotate.conf EXITVALUE=$? if [ $EXITVALUE != 0 ]; then /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]" fi exit 0
實際執行時,Logrotate會呼叫配置檔案「/etc/logrotate.conf」:
# see "man logrotate" for details # rotate log files weekly weekly # keep 4 weeks worth of backlogs rotate 4 # create new (empty) log files after rotating old ones create # uncomment this if you want your log files compressed #compress # RPM packages drop log rotation information into this directory include /etc/logrotate.d # no packages own wtmp -- we'll rotate them here /var/log/wtmp { monthly minsize 1M create 0664 root utmp rotate 1 } # system-specific logs may be also be configured here.
這裡的設定可以理解為Logrotate的預設值,當然了,可以我們在「/etc/logrotate.d」目錄裡放置自己的配置檔案,用來覆蓋Logrotate的預設值。
Logrotate的演示
按天儲存一週的Nginx日誌壓縮檔案,配置檔案為「/etc/logrotate.d/nginx」:
/usr/local/nginx/logs/*.log { daily dateext compress rotate 7 sharedscripts postrotate kill -USR1 `cat /var/run/nginx.pid` endscript }
如果你等不及CRON,可以通過如下命令來手動執行:
shell> logrotate -f /etc/logrotate.d/nginx
當然,正式執行前最好通過Debug選項來驗證一下,這對除錯也很重要:
shell> logrotate -d -f /etc/logrotate.d/nginx
BTW:類似的還有Verbose選項,這裡就不多說了。
Logrotate的疑問
問題:sharedscripts的作用是什麼?
大家可能注意到了,我在前面Nginx的例子裡宣告日誌檔案的時候用了星號萬用字元,也就是說這裡可能涉及多個日誌檔案,比如:access.log和error.log。說到這裡大家或許就明白了,sharedscripts的作用是在所有的日誌檔案都輪轉完畢後統一執行一次指令碼。如果沒有配置這條指令,那麼每個日誌檔案輪轉完畢後都會執行一次指令碼。
問題:rotate和maxage的區別是什麼?
它們都是用來控制儲存多少日誌檔案的,區別在於rotate是以個數為單位的,而maxage是以天數為單位的。如果我們是以按天來輪轉日誌,那麼二者的差別就不大了。
問題:為什麼生成日誌的時間是凌晨四五點?
前面我們說過,Logrotate是基於CRON執行的,所以這個時間是由CRON控制的,具體可以查詢CRON的配置檔案「/etc/crontab」,可以手動改成如23:59等時間執行:
SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root HOME=/ # run-parts 01 * * * * root run-parts /etc/cron.hourly 59 23 * * * root run-parts /etc/cron.daily 22 4 * * 0 root run-parts /etc/cron.weekly 42 4 1 * * root run-parts /etc/cron.monthly
如果使用的是新版CentOS,那麼配置檔案為:/etc/anacrontab。
問題:如何告訴應用程式重新開啟日誌檔案?
以Nginx為例,是通過postrotate指令傳送USR1訊號來通知Nginx重新開啟日誌檔案的。但是其他的應用程式不一定遵循這樣的約定,比如說MySQL是通過flush-logs來重新開啟日誌檔案的。更有甚者,有些應用程式就壓根沒有提供類似的方法,此時如果想重新開啟日誌檔案,就必須重啟服務,但為了高可用性,這往往不能接受。還好Logrotate提供了一個名為copytruncate的指令,此方法採用的是先拷貝再清空的方式,整個過程中日誌檔案的操作控制代碼沒有發生改變,所以不需要通知應用程式重新開啟日誌檔案,但是需要注意的是,在拷貝和清空之間有一個時間差,所以可能會丟失部分日誌資料。
logrotate 程式是一個日誌檔案管理工具。用來把舊的日誌檔案刪除,並建立新的日誌檔案,我們把它叫做“轉儲”。我們可以根據日誌檔案的大小,也可以根據其天數來轉儲,這個過程一般通過 cron 程式來執行。
安裝
yum install logrotate cron
安裝後系統會定時執行logrotate,一般是每天一次。系統是這麼實現按天執行的。crontab會每天定時執行/etc/cron.daily目錄下的指令碼,而這個目錄下有個檔案叫logrotate。在centos上指令碼內容是這樣的:
/etc/cron.daily/logrotate:
- /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
此檔案中只是執行了logrotate命令,然後傳遞一個配置引數。我們可以新建自己的指令碼來執行logrotate命令,然後把指令碼加入crontab中,就可以自定義檔案分割了。
logrotate引數
引數 | 描述 |
---|---|
compress | 通過gzip 壓縮轉儲以後的日誌 |
nocompress | 不需要壓縮時,用這個引數 |
copytruncate | 用於還在開啟中的日誌檔案,把當前日誌備份並截斷 |
nocopytruncate | 備份日誌檔案但是不截斷 |
create mode owner group | 轉儲檔案,使用指定的檔案模式建立新的日誌檔案 |
nocreate | 不建立新的日誌檔案 |
delaycompress | 一起使用時,轉儲的日誌檔案到下一次轉儲時才壓縮 |
nodelaycompress | 覆蓋 delaycompress 選項,轉儲同時壓縮。 |
errors address | 專儲時的錯誤資訊傳送到指定的Email 地址 |
ifempty | 即使是空檔案也轉儲,這個是 logrotate 的預設選項。 |
notifempty | 如果是空檔案的話,不轉儲 |
mail address | 把轉儲的日誌檔案傳送到指定的E-mail 地址 |
nomail | 轉儲時不傳送日誌檔案 |
olddir directory | 轉儲後的日誌檔案放入指定的目錄,必須和當前日誌檔案在同一個檔案系統 |
noolddir | 轉儲後的日誌檔案和當前日誌檔案放在同一個目錄下 |
prerotate/endscript | 在轉儲以前需要執行的命令可以放入這個對,這兩個關鍵字必須單獨成行 |
postrotate/endscript | 在轉儲以後需要執行的命令可以放入這個對,這兩個關鍵字必須單獨成行 |
daily | 指定轉儲週期為每天 |
weekly | 指定轉儲週期為每週 |
monthly | 指定轉儲週期為每月 |
rotate count | 指定日誌檔案刪除之前轉儲的次數,0 指沒有備份,5 指保留5 個備份 |
tabootext [+] list | 讓logrotate 不轉儲指定副檔名的檔案,預設的副檔名是:.rpm-orig, .rpmsave, v, 和 ~ |
size size | 當日志文件到達指定的大小時才轉儲,字尾MB. |
實戰
新建配置檔案:logrotate.conf,內容如下:
- /home/project/route/route.out{
- nocompress
- copytruncate
- create 0664 root root
- nomail
- rotate 10
- size 1M
- }
新建指令碼 logrotate.sh,內容如下:
/usr/sbin/logrotate /home/project/route/logrotate.conf
- 1
加入crontable:內容如下:
- [root @hadoop4 route]# crontab -e
- * * * * * /home/project/route/logrotate.sh >/home/project/route/aaa.log 2>&1
程式執行一段時間後結果如下:
- -rw-r--r--. 1 root root 641345 12月 15 14:41 route.out
- -rw-r--r--. 1 root root 1093908 12月 15 14:41 route.out.1
- -rw-r--r--. 1 root root 1883706 12月 15 14:40 route.out.2
檔案已經被分割了轉儲了。