一.概述
logrotate是一個Linux系統默認安裝了的日志文件管理工具,用來把舊文件輪轉、壓縮、刪除,並且創建新的日志文件。我們可以根據日志文件的大小、天數等來轉儲,便於對日志文件管理。
logrotate是基於crond服務來運行的,其crond服務的腳本是/etc/cron.daily/logrotate,日志轉儲是系統自動完成的。實際運行時,logrotate會調用配置文件 /etc/logrotate.conf,可以在 /etc/logrotate.d 目錄里放置自定義好的配置文件,用來覆蓋logrotate的缺省值。
二.配置文件詳解
/etc/logrotate.conf 是主配置文件
/etc/logrotate.d 是一個目錄,該目錄下的所有文件都會被主動的讀到 /etc/logrotate.conf 中執行
配置項說明:
配置項 | 說明 |
---|---|
compress | 通過 gzip 壓縮轉儲舊的日志 |
nocompress | 不需要壓縮時,用這個參數 |
copytruncate | 用於還在打開中的日志文件,把當前日志備份並截斷,是先拷貝再清空的方式,拷貝和清空之間有一個時間差,可能會丟失部分日志數據 |
nocopytruncate | 備份日志文件但是不截斷 |
create mode owner group | 使用指定的文件模式創建新的日志文件,如:create 0664 root utmp |
nocreate | 不建立新的日志文件 |
delaycompress | 和 compress 一起使用時,轉儲的日志文件到下一次轉儲時才壓縮 |
nodelaycompress | 覆蓋 delaycompress 選項,轉儲同時壓縮 |
missingok | 在日志轉儲期間,任何錯誤將被忽略 |
errors address | 轉儲時的錯誤信息發送到指定的 Email 地址 |
ifempty | 即使日志文件是空文件也轉儲,這個是 logrotate 的缺省選項 |
notifempty | 如果日志文件是空文件的話,不轉儲 |
mail E-mail | 把轉儲的日志文件發送到指定的 E-mail 地址 |
nomail | 轉儲時不發送日志文件到 E-mail 地址 |
olddir directory | 轉儲后的日志文件放入指定的目錄,必須和當前日志文件在同一個文件系統 |
noolddir | 轉儲后的日志文件和當前日志文件放在同一個目錄下 |
prerotate/endscript | 在轉儲之前需要執行的命令可以放入這個對中,這兩個關鍵字必須單獨成行 |
postrotate/endscript | 在轉儲之后需要執行的命令可以放入這個對中,這兩個關鍵字必須單獨成行 |
sharedscripts | 所有的日志文件都轉儲完畢后統一執行一次腳本 |
daily | 指定轉儲周期為每天 |
weekly | 指定轉儲周期為每周 |
monthly | 指定轉儲周期為每月 |
rotate count | 指定日志文件刪除之前轉儲的次數,0 指沒有備份,5 指保留5個備份 |
size(minsize) logsize | 當日志文件到達指定的大小時才轉儲,size 可以指定單位為k或M,如:size 500k,size 100M |
dateext | 指定轉儲后的日志文件以當前日期為格式結尾,如 |
dateformat dateformat | 配合dateext使用,緊跟在下一行出現,定義日期格式,只支持%Y %m %d %s這4個參數,如:dateformat -%Y%m%d%s |
三.實戰案例
1.nginx
cat > /etc/logrotate.d/nginx << eof
/usr/local/nginx/logs/*log {
daily
# 每天轉儲
rotate 30
# 保存30個備份
missingok
# 在日志轉儲期間,任何錯誤將被忽略
notifempty
# 文件為空時不轉儲
compress
# 通過 gzip 壓縮
dateext
# 日志文件以當前日期為格式結尾
sharedscripts
# 所有日志文件轉儲完畢后執行一次腳本
postrotate
# 轉儲之后執行命令,和endscript成對使用
/bin/kill -USR1 \$(cat /usr/local/nginx/logs/nginx.pid 2>/dev/null) 2>/dev/null || :
endscript
# 轉儲之后執行命令,和postrotate成對使用
}
eof
2.rsyslog
cat > /etc/logrotate.d/syslog << eof
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
{
sharedscripts
dateext
rotate 25
size 40M
compress
dateformat -%Y%m%d%s
postrotate
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}
eof
3.redis
cat > /etc/logrotate.d/redis << eof
/var/log/redis/*.log {
weekly
rotate 10
copytruncate
delaycompress
compress
notifempty
missingok
}
eof
4.supervisor
cat > /etc/logrotate.d/supervisor << eof
/var/log/supervisor/*.log {
missingok
weekly
notifempty
nocompress
}
eof
5.yum
cat > /etc/logrotate.d/yum << eof
/var/log/yum.log {
missingok
notifempty
yearly
create 0600 root root
}
eof
6.httpd
cat > /etc/logrotate.d/httpd << eof
/var/log/httpd/*log {
missingok
notifempty
sharedscripts
postrotate
/sbin/service httpd reload > /dev/null 2>/dev/null || true
endscript
}
eof
7.salt
cat > /etc/logrotate.d/salt << eof
/var/log/salt/master {
weekly
missingok
rotate 5
compress
notifempty
}
/var/log/salt/minion {
weekly
missingok
rotate 5
compress
notifempty
}
/var/log/salt/key {
weekly
missingok
rotate 5
compress
notifempty
}
/var/log/salt/cloud {
weekly
missingok
rotate 5
compress
notifempty
}
/var/log/salt/ssh {
weekly
missingok
rotate 5
compress
notifempty
}
eof
四.命令參數說明
使用 man logrotate 或者 logrotate --help 來查看相關命令參數
logrotate --help
Usage: logrotate [OPTION...] <configfile>
-d, --debug 調試模式,輸出調試結果,並不執行。隱式-v參數
-f, --force 強制轉儲文件
-m, --mail=command 發送郵件命令而不是用‘/bin/mail'發 -s, --state=statefile 狀態文件,對於運行在不同用戶情況下有用 -v, --verbose 顯示轉儲過程的詳細信息
如果等不及cron自動執行日志轉儲,可以強制轉儲文件(-f 參數) ,正式執行前最好使用調試模式(-d 參數)
/usr/sbin/logrotate -f /etc/logrotate.d/nginx
/usr/sbin/logrotate -d -f /etc/logrotate.d/nginx
五.自定義日志轉儲時間
現在需要將日志轉儲(切割)時間調整到每天的0點,即每天切割的日志是前一天的0點-23點59分59秒之間的內容。
1.日志轉儲流程
首先說一下基於crond服務,logrotate轉儲日志的流程:
crond服務加載/etc/cron.d/0hourly --->在每小時的01分執行/etc/cron.hourly/0anacron --->執行anacron --->根據/etc/anacrontab的配置執行/etc/cron.daily,/etc/cron.weekly,/etc/cron.monthly --->執行/etc/cron.daily/下的logrotate腳本 --->執行logrotate --->根據/etc/logrotate.conf配置執行腳本/etc/logrotate.d/nginx --->轉儲nginx日志成功
重點看一下 /etc/anacrontab
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45 # 隨機的延遲時間,表示最大45分鍾
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22 # 在3點-22點之間開始
#period in days delay in minutes job-identifier command
1 5 cron.daily nice run-parts /etc/cron.daily
7 25 cron.weekly nice run-parts /etc/cron.weekly
@monthly 45 cron.monthly nice run-parts /etc/cron.monthly
# period in days 是表示1天、7天、1個月執行一次
# delay in minutes 是延遲的分鍾數
# nice設置優先級為10,范圍為-20(最高優先級)到19(最低優先級)
# run-parts 是一個腳本,表示會執行它后面目錄里的腳本
分析可以得出,如果機器沒有關機,默認的logrotate(配置文件里設置的是daily)一般會在每天的3點05分到3點45分之間執行。
2.定義每天00點00分轉儲nginx日志
方法一
通過上面的分析,調整如下:
調整 /etc/anacrontab 配置文件,將 RANDOM_DELAY=0 , START_HOURS_RANGE=0-22 , delay in minutes 改為0。
調整 /etc/cron.d/0hourly 配置文件,將01改為00(/etc/cron.daily那一行)。
這樣logrotate就可以在每天00點00分轉儲日志(配置文件里設置的是daily)
方法二
上面的方法會影響到 /etc/cron.daily,/etc/cron.weekly,/etc/cron.monthly 下所有腳本的自動執行時間,影響范圍有點大,如果我們僅僅需要nginx的日志轉儲在每天00點執行怎么辦?
我們可以創建一個文件夾,如 /etc/logrotate.daily.0/ ,放置每天0點需要執行的轉儲日志配置,然后設置計划任務,每天00點00分 logrotate -f 強制執行。具體操作如下:
mkdir -p /etc/logrotate.daily.0/
mv /etc/logrotate.d/nginx /etc/logrotate.daily.0/ # 具體配置內容參照上文
crontab -e
#nginx log logrotate
00 00 * * * /usr/sbin/logrotate -f /etc/logrotate.daily.0/nginx >/dev/null 2>&1
注意:/etc/logrotate.d/目錄下相應的配置文件要刪掉,否則每天會自動執行兩次。
六.參考資料
運維中的日志切割操作梳理(Logrotate/python/shell腳本實現)
crontab和anacron和logrotate的關系詳解