logrotate
logrotate是一个日志文件管理工具。用来把旧文件轮转、压缩、删除,并且创建新的日志文件。我们可以根据日志文件的大小、天数等来转储,便于对日志文件管理,一般都是通过cron计划任务来完成的。
配置选项说明:
compress:通过gzip 压缩转储旧的日志
nocompress:不需要压缩时,用这个参数
copytruncate:用于还在打开中的日志文件,把当前日志备份并截断
nocopytruncate:备份日志文件但是不截断
create mode owner group:使用指定的文件模式创建新的日志文件
nocreate:不建立新的日志文件
delaycompress:和 compress 一起使用时,转储的日志文件到下一次转储时才压缩
nodelaycompress:覆盖 delaycompress 选项,转储同时压缩。
errors address:专储时的错误信息发送到指定的Email 地址
ifempty:即使是空文件也转储,这个是 logrotate 的缺省选项。
notifempty:如果是空文件的话,不转储
mail address:把转储的日志文件发送到指定的E-mail 地址
nomail:转储时不发送日志文件
olddir directory:转储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统
noolddir:转储后的日志文件和当前日志文件放在同一个目录下
prerotate/endscript:在转储以前需要执行的命令可以放入这个对,这两个关键字必须单独成行
postrotate/endscript:在转储以后需要执行的命令可以放入这个对,这两个关键字必须单独成行
sharedscripts:所有的日志文件都轮转完毕后统一执行一次脚本
daily:指定转储周期为每天
weekly:指定转储周期为每周
monthly:指定转储周期为每月
rotate count:指定日志文件删除之前转储的次数,0 指没有备份,5 指保留5 个备份
size size:当日志文件到达指定的大小时才转储,Size 可以指定 bytes (缺省)以及KB (sizek)或者MB
missingok: 如果日志丢失,不报错继续滚动下一个日志
执行方式:
既然是通过crontab去执行的话,我们就能发现,在/etc/corn.daily目录下,会有logrotate这个文件,也就是说cron会每天都去执行这个目录下的所有可执行文件,其中就包括了logrotate。
[root@VM_0_12_centos cron.daily]# cat 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
#!/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
我们看到他通过/usr/sbin/logrotate二进制去执行了/etc/logrotate.conf配置文件,我们看看配置文件:
[root@VM_0_12_centos cron.daily]# 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 #这里表示创建新的日志文件,权限为0664,拥有者和所属组分别是root和utmp!
minsize 1M #如果wtmp的大小没有达到1M,哪怕执行了crontab,wtmp也不会切割!在一个周期内,达到了minsize的限制时,就执行一次切割,后面就不会切割了,在一个周期内,如果一直没达到minsize的限制,那就一直不会有切割操作!
# 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 #这里表示创建新的日志文件,权限为0664,拥有者和所属组分别是root和utmp!
minsize 1M #如果wtmp的大小没有达到1M,哪怕执行了crontab,wtmp也不会切割!在一个周期内,达到了minsize的限制时,就执行一次切割,后面就不会切割了,在一个周期内,如果一直没达到minsize的限制,那就一直不会有切割操作!
rotate 1 #只保留一个备份
}
/var/log/btmp {
missingok
monthly
create 0600 root utmp
rotate 1
}
}
/var/log/btmp {
missingok
monthly
create 0600 root utmp
rotate 1
}
其中‘include /etc/logrotate.d’说明了还包括该目录下的所有配置文件,我们去看看:
[root@game-kg-mygj-07 logrotate.d]# pwd
/etc/logrotate.d
[root@game-kg-mygj-07 logrotate.d]# ll
total 48
drwxr-xr-x 2 root root 4096 Mar 16 2018 2018-03-16
-rw-r--r--. 1 root root 139 May 11 2016 dracut
-rw-r--r-- 1 root root 185 Feb 19 2018 httpd
-rw-r--r-- 1 root root 135 Jun 22 2012 iptraf
-rw-r--r-- 1 root root 215 Jul 16 10:26 nginx
-rw-r--r-- 1 root root 207 Jan 12 2019 php-fpm
-rw-r--r--. 1 root root 329 Jul 17 2012 psacct
-rw-r--r-- 1 root root 127 Oct 26 2018 redis
-rw-r--r--. 1 root root 265 Mar 16 2018 syslog
-rw-r--r-- 1 root root 188 Mar 22 2017 vsftpd
-rw-r--r--. 1 root root 87 May 12 2016 yum
-rw-r--r-- 1 root root 132 Nov 12 2018 zabbix-agent
/etc/logrotate.d
[root@game-kg-mygj-07 logrotate.d]# ll
total 48
drwxr-xr-x 2 root root 4096 Mar 16 2018 2018-03-16
-rw-r--r--. 1 root root 139 May 11 2016 dracut
-rw-r--r-- 1 root root 185 Feb 19 2018 httpd
-rw-r--r-- 1 root root 135 Jun 22 2012 iptraf
-rw-r--r-- 1 root root 215 Jul 16 10:26 nginx
-rw-r--r-- 1 root root 207 Jan 12 2019 php-fpm
-rw-r--r--. 1 root root 329 Jul 17 2012 psacct
-rw-r--r-- 1 root root 127 Oct 26 2018 redis
-rw-r--r--. 1 root root 265 Mar 16 2018 syslog
-rw-r--r-- 1 root root 188 Mar 22 2017 vsftpd
-rw-r--r--. 1 root root 87 May 12 2016 yum
-rw-r--r-- 1 root root 132 Nov 12 2018 zabbix-agent
你看,这里包含了各种服务的日志切割配置文件,我们单独拿一个出来看看:
[root@game-kg-mygj-07 logrotate.d]# cat nginx
/var/log/nginx/*log {
daily #每天一次
rotate 7 #保留7个备份文件
missingok #如果日志丢失,不报错继续滚动下一个日志
notifempty #日志为空时,不转储
compress #压缩
sharedscripts #所有的日志文件都轮转完毕后统一执行一次脚本
postrotate #在转储以后需要执行的命令可以放入这个对,endscript为收尾字符!
/bin/kill -USR1 $(cat /var/run/nginx.pid 2>/dev/null) 2>/dev/null || : ##这里就是转储完成后需要执行的指令,他表示在不重启nginx的情况下,重新加载nginx的配置,当我们对配置文件进行了修改后,发出kill -HUP pid命令,就会以动态的方式更新配置!具体细节在Nginx的热更新里会详细介绍!
endscript
}
/var/log/nginx/*log {
daily #每天一次
rotate 7 #保留7个备份文件
missingok #如果日志丢失,不报错继续滚动下一个日志
notifempty #日志为空时,不转储
compress #压缩
sharedscripts #所有的日志文件都轮转完毕后统一执行一次脚本
postrotate #在转储以后需要执行的命令可以放入这个对,endscript为收尾字符!
/bin/kill -USR1 $(cat /var/run/nginx.pid 2>/dev/null) 2>/dev/null || : ##这里就是转储完成后需要执行的指令,他表示在不重启nginx的情况下,重新加载nginx的配置,当我们对配置文件进行了修改后,发出kill -HUP pid命令,就会以动态的方式更新配置!具体细节在Nginx的热更新里会详细介绍!
endscript
}
ok,logrotate的配置和细节就写到这里,下面分享一个关于logrotate的实际经历。
logrotate的默认周期轮训时间好像是在每天的凌晨3点多钟,如果我们需要获取nginx完整的某一天的日志,就需要拿到当天的日志以及后一天的日志,并从后一天的日志里截取3点钟之后的部分,而且,当天的日志当中,还包括了前一天三点钟之后的日志!
这样是不是很麻烦啊!
我们让logrotate在零点的时候切割不就好了?
如何改logrotate的切割时间?
把logrotate从/etc/crond.daily中拿出来,放到其他另外的地方,然后再从crontab中指定每天零点的时候执行切割操作:
0 0 * * * /etc/logrotate > /dev/null 2>&1 &
这样的话,就会在每天的零点执行切割了,同时看下效果:
[root@game-kg-mygj-07 nginx]# pwd
/var/log/nginx
[root@game-kg-mygj-07 nginx]# ll
total 564
-rw-r--r-- 1 nginx root 11349 Jul 27 10:20 access.log
-rw-r--r-- 1 nginx root 1898 Jul 21 00:00 access.log-20200721.gz
-rw-r--r-- 1 nginx root 12620 Jul 22 00:00 access.log-20200722.gz
-rw-r--r-- 1 nginx root 1836 Jul 23 00:00 access.log-20200723.gz
-rw-r--r-- 1 nginx root 3053 Jul 24 00:00 access.log-20200724.gz
-rw-r--r-- 1 nginx root 17312 Jul 25 00:00 access.log-20200725.gz
-rw-r--r-- 1 nginx root 3926 Jul 26 00:00 access.log-20200726.gz
-rw-r--r-- 1 nginx root 10342 Jul 27 00:00 access.log-20200727.gz
-rw-r--r-- 1 nginx root 8115 Jul 27 10:04 error.log
-rw-r--r-- 1 nginx root 932 Jul 21 00:00 error.log-20200721.gz
-rw-r--r-- 1 nginx root 17583 Jul 22 00:00 error.log-20200722.gz
-rw-r--r-- 1 nginx root 784 Jul 23 00:00 error.log-20200723.gz
-rw-r--r-- 1 nginx root 1191 Jul 24 00:00 error.log-20200724.gz
-rw-r--r-- 1 nginx root 25398 Jul 25 00:00 error.log-20200725.gz
-rw-r--r-- 1 nginx root 3002 Jul 26 00:00 error.log-20200726.gz
-rw-r--r-- 1 nginx root 15200 Jul 27 00:00 error.log-20200727.gz
/var/log/nginx
[root@game-kg-mygj-07 nginx]# ll
total 564
-rw-r--r-- 1 nginx root 11349 Jul 27 10:20 access.log
-rw-r--r-- 1 nginx root 1898 Jul 21 00:00 access.log-20200721.gz
-rw-r--r-- 1 nginx root 12620 Jul 22 00:00 access.log-20200722.gz
-rw-r--r-- 1 nginx root 1836 Jul 23 00:00 access.log-20200723.gz
-rw-r--r-- 1 nginx root 3053 Jul 24 00:00 access.log-20200724.gz
-rw-r--r-- 1 nginx root 17312 Jul 25 00:00 access.log-20200725.gz
-rw-r--r-- 1 nginx root 3926 Jul 26 00:00 access.log-20200726.gz
-rw-r--r-- 1 nginx root 10342 Jul 27 00:00 access.log-20200727.gz
-rw-r--r-- 1 nginx root 8115 Jul 27 10:04 error.log
-rw-r--r-- 1 nginx root 932 Jul 21 00:00 error.log-20200721.gz
-rw-r--r-- 1 nginx root 17583 Jul 22 00:00 error.log-20200722.gz
-rw-r--r-- 1 nginx root 784 Jul 23 00:00 error.log-20200723.gz
-rw-r--r-- 1 nginx root 1191 Jul 24 00:00 error.log-20200724.gz
-rw-r--r-- 1 nginx root 25398 Jul 25 00:00 error.log-20200725.gz
-rw-r--r-- 1 nginx root 3002 Jul 26 00:00 error.log-20200726.gz
-rw-r--r-- 1 nginx root 15200 Jul 27 00:00 error.log-20200727.gz
ok,这里看到也生效了!
但是,这里就把/etc/logrotate.d底下的所有服务日志都设置成零点切割了!
如何做到仅仅修改指定服务的日志切割时间?
很简单,logrotate的执行指令你是知道的的:/usr/sbin/logrotate /etc/logrotate.conf
并且我们是在/etc/logrotate.conf中指定了需要执行的额外的服务详情的,也就是include /etc/logrotate.d
那么,我们能不能模仿他的写法,新建一个自定义的logrotate.conf?再去include一个仅仅包含我们想要修改切割时间的服务的配置文件?
这么一套下来,就相当于我们复制了一套完整的logrotate执行方式,只不过,include ***,这个***目录中,只包含我们的目标服务,不涉及系统默认的那些程序日志!
然后再去crontab里做计划任务,指定零点执行切割!
logrotate的相关知识就写到这里,以上,共勉!