前言
日志就像程序的生命記錄儀,詳細記錄下了程序運行的點點滴滴。
- 慎重的選擇記錄哪些日志:在茫茫日志海中尋找真正記錄問題的日志,你是不想經歷的;
- 精心的定時壓縮轉移日志:故障發生了,日志卻丟了,此時的任何辯解都是蒼白無力的。
記錄哪些日志需要你在編寫應用程序慎重決定,本文講述如何使用Linux自帶的logrotate程序來精心組織我們可愛的日志文件。
簡介
日志,實際就是本文文件,且是個內容不斷在增長的文件。處理通常就是按天或者按大小來備份、壓縮或轉儲,非常簡單。
/var/log/messages
是大家熟悉的系統日志存放位置。如果該文件內容增長特別快,幾天可能就撐滿了整個硬盤,那么對該文件的備份、壓縮或轉儲就顯得尤為重要。
手動怎么處理呢?可能是:
- 編寫日志處理腳本,腳本檢測如果日志文件大小超過10M就拷貝一份日志並壓縮轉儲,中間還需要清空原日志;
- Crontab中把這個腳本作為定時任務,每天執行下。
Logrotate實際就是起着上述腳本作用的小工具,他通過讓用戶來配置規則的方式,檢測和處理日志文件。配合Cron可讓處理定時化;
Logrotate預制了大量判斷條件和處理方式,可大大降低手寫腳本的負擔和出錯的可能;
Logrorate檢測日志文件屬性,比對用戶配置好的檢測條件,對滿足條件的再根據用戶配置的要求來處理,整個可以通過Cron來定時調度,這其實是非常經典的Linux解決問題的思路,可以好好靜下心來品味下,簡單,好用。
組成
以下是logrotate運行的關鍵點:
/usr/bin/logrotate
程序所在位置;/etc/cron.daily/logrotate
默認讓Cron每天執行logrotate一次;/etc/logrotate.conf
全局配置文件;/etc/logrotate.d
應用自個的配置文件存放目錄,覆蓋全局配置;
全局配置文件/etc/logrotate.conf
# cat /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
# use date as a suffix of the rotated file
# dateext
# 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 and btmp -- we'll rotate them here
/var/log/wtmp {
monthly
create 0664 root utmp
minsize 1M
rotate 1
}
/var/log/btmp {
missingok
monthly
create 0600 root utmp
rotate 1
}
# system-specific logs may be also be configured here.
查看全局配置文件cat /etc/logrotate.conf
,可以發現#
是行注釋,配置項都是以關鍵字形式出現(那么想知道每個關鍵字的作用,最簡單的就是直接man查看了)。
仔細看下每個關鍵字的注釋,不難發現,比如:
- weekly:表示每周處理下日志;
- rotate4:最多保持4個輪轉備份,關於輪轉本身后文會詳述,很有意思;
- create:處理完該日志文件后,新生成一個日志文件,當然盡可能是同名同權限等;
- dateext:默認未加時間戳;
- compress:默認不壓縮;
- 對wtmp和btmp日志做了單獨處理,於是你意識到了單獨的配置可以放在
/etc/logrotate.d
目錄,或者直接放在全局配置里面。
於是當logrotate
程序被執行時,按照字面意思logrotate
默認是想每周處理下日志,對日志最多輪轉保留4份,處理方式是不壓縮也不加時間戳,處理完后再生成個同名文件。當然這些是默認設置,還對wtmp和btmp日志處理做了單獨要求並且include /etc/logrotate.d
目錄下還有一大堆處理要求。該目錄下配置文件,在logrotate
被執行后,都會不一個個讀取來執行。
自定義配置文件存放目錄/etc/logrotate.d/
# ls /etc/logrotate.d/
cups debug dracut httpd iptraf mysqld ppp psacct sssd subscription-manager syslog tomcat6 up2date vsftpd wpa_supplicant yum
例如查看下sssd
配置文件的內容:
# cat /etc/logrotate.d/sssd
/var/log/sssd/*.log {
weekly
missingok
notifempty
sharedscripts
rotate 2
compress
postrotate
/bin/kill -HUP `cat /var/run/sssd.pid 2>/dev/null` 2> /dev/null || true
endscript
}
可以發現基本格式與全局配置文件/etc/logrotate.conf
一致,不難想象單獨為某個日志配置的要求優先級肯定更高,如果與全局配置中出現相同項目的配置,單獨的肯定覆蓋全局的。
Cron執行 /etc/cron.daily/logrotate
配置文件都指定完畢,logrotate可單獨執行了,當然也可以通過cron來定時執行;
# cat /etc/cron.daily/logrotate
#!/bin/sh
/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已經放在/etc/cron.daily/logrotate
目錄,很明顯是讓cron每天執行一次logrotate程序;
當然你也可以將該腳本放到其他時間,比如每分鍾執行,甚至可以單獨寫crontab表達式來讓logrotate指定配置文件和指定時間執行;
小結
至此,我們看過了logrotate的全局配置文件,單獨配置文件,已經如何配合cront來定時執行。
為了加深記憶,我們先小結下:
- logrotate是個程序,專門用來處理日志文件;
- 處理需要用戶配置規則,比如指定超出10M則做什么動作;
- 規則可配置到獨立的配置文件中,當然全局還有個全局默認配置文件,要知道每個配置文件都放在哪哦;
- logrotate一被執行,就會搜索所有的配置文件按要求處理日志;
- 可以配合cron讓logrotate定時執行;
測試
man過logrotate的同學大概知道logrotate該怎么用了,常見的選項使用如下:
# 1. 調試 (d = debug)參數為配置文件,不指定則執行全局配置文件
logrotate -d /etc/logrotate.d/test.conf
# 2. 強制執行(-f = force),可以配合-v(-v =verbose)使用,注意調試信息默認攜帶-v;
logrotate -v -f /etc/logrotate.d/test.conf
本例通過自定義配置文件來壓縮指定日志文件來測試logrotate的使用。
注意logrotate都是需要使用root來執行的,(但是可以通過配置項來指定生成的日志文件為普通用戶的)。
# 1. 生成一個日志文件
man ps > test.log
ll -h test.log
-rw-r--r-- 1 root root 54K Sep 6 11:36 test.log
# 2. 編寫對該日志文件如何處理的logrotate配置文件
cat /etc/logrotate.d/test.conf
/var/log/test.log {
compress
rotate 4
size 30k
create 0600 root root
}
# 3. 調試是否可以按照配置文件要求生成壓縮文件
logrotate -d /etc/logrotate.d/test.conf
reading config file /etc/logrotate.d/test.conf
reading config info for /var/log/test.log
Handling 1 logs
rotating pattern: /var/log/test.log 30720 bytes (4 rotations)
empty log files are rotated, old logs are removed
considering log /var/log/test.log
log needs rotating
rotating log /var/log/test.log, log->rotateCount is 4
dateext suffix '-20150906'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
renaming /var/log/test.log.4.gz to /var/log/test.log.5.gz (rotatecount 4, logstart 1, i 4),
renaming /var/log/test.log.3.gz to /var/log/test.log.4.gz (rotatecount 4, logstart 1, i 3),
renaming /var/log/test.log.2.gz to /var/log/test.log.3.gz (rotatecount 4, logstart 1, i 2),
renaming /var/log/test.log.1.gz to /var/log/test.log.2.gz (rotatecount 4, logstart 1, i 1),
renaming /var/log/test.log.0.gz to /var/log/test.log.1.gz (rotatecount 4, logstart 1, i 0),
renaming /var/log/test.log to /var/log/test.log.1
creating new /var/log/test.log mode = 0600 uid = 0 gid = 0
compressing log with: /bin/gzip
removing old log /var/log/test.log.5.gz
error: error opening /var/log/test.log.5.gz: No such file or directory
# 4. 調試結果正常,實際測試下
logrotate -f /etc/logrotate.d/test.conf
ll -h test.log*
-rw------- 1 root root 0 Sep 6 11:44 test.log
-rw-r--r-- 1 root root 14K Sep 6 11:44 test.log.1.gz
測試正常;
以上logrotate -f /etc/logrotate.d/test.conf
指令完全可以寫入crontab中,按照要求時間來執行,此處暫時不拆開講了。
輪轉
我們從上述debug信息中,摘錄輪轉部分的日志來理解下,什么叫輪轉。
rotating log /var/log/test.log, log->rotateCount is 4
renaming /var/log/test.log.4.gz to /var/log/test.log.5.gz (rotatecount 4, logstart 1, i 4),
renaming /var/log/test.log.3.gz to /var/log/test.log.4.gz (rotatecount 4, logstart 1, i 3),
renaming /var/log/test.log.2.gz to /var/log/test.log.3.gz (rotatecount 4, logstart 1, i 2),
renaming /var/log/test.log.1.gz to /var/log/test.log.2.gz (rotatecount 4, logstart 1, i 1),
renaming /var/log/test.log.0.gz to /var/log/test.log.1.gz (rotatecount 4, logstart 1, i 0),
renaming /var/log/test.log to /var/log/test.log.1
emoving old log /var/log/test.log.5.gz
error: error opening /var/log/test.log.5.gz: No such file or directory
根據配置文件要求,輪轉4份;
以偽代碼在簡寫上述日志為:
rotateCount=4
mv 4 5
mv 3 4
mv 2 3
mv 1 2
rm 5
這就很容易理解了,所謂輪轉,就是類似二級制向右位移一樣不斷的重命名;
例子
在弄清楚logrotate的運作機制,又實地測試一番后,以下將通過多個例子方式來讓大家快速配置。
清空但不刪除日志文件
copytruncate的作用在於先復制一份當前日志文件用做處理,再清空源日志文件,讓其繼續接收日志。
當然在復制和清空的空隙可能會有若干
$ cat logrotate.conf
/tmp/output.log {
size 1k
copytruncate
create 700 bala bala
rotate 4
compress
}
摘自參考3;
日志處理完執行自定義腳本
postrotate和endscript中間可以編寫自定義腳本,用來對日志或者其他其定義處理,擴展性非常強;
例如由於logrotate對壓縮日志可指定的時間戳只能到天,於是可以再自定義腳本里面對文件做時分等細化命名;
$ cat logrotate.conf
/tmp/output.log {
size 1k
copytruncate
rotate 4
compress
postrotate
/home/bala/myscript.sh
endscript
}
摘自參考3;
更改壓縮程序
默認壓縮程序使用.gz
,當然可以自定義,需要制定壓縮程序和后綴名;
$ cat logrotate.conf
/tmp/output.log {
size 1k
copytruncate
create
compress
compresscmd /bin/bzip2
compressext .bz2
rotate 4
}