使用logrotate 进行日志管理
1 概述
logrotate是一个Linux系统默认安装了的日志文件管理工具,用来把旧文件轮转、压缩、删除,并且创建新的日志文件。我们可以根据日志文件的大小、天数等来转储,便于对日志文件管理。
logrotate是基于crond服务来运行的,其crond服务的脚本是/etc/cron.daily/logrotate,日志转储是系统自动完成的。实际运行时,logrotate会调用配置文件 /etc/logrotate.conf,可以在 /etc/logrotate.d 目录里放置自定义好的配置文件,用来覆盖logrotate的缺省值。
2 命令
-?或--help:在线帮助;
-d或--debug:详细显示指令执行过程,便于排错或了解程序执行的情况;
-f或--force :强行启动记录文件维护操作,纵使logrotate指令认为没有需要亦然;
-s<状态文件>或--state=<状态文件>:使用指定的状态文件;
-v或--version:显示指令执行过程;
-usage:显示指令基本用法。
一般测试使用-vf选项,因为可以显示执行过程,方便我们排除错误。
一般使用直接使用-f选项就可以。
3 配置文件说明
1、 主配置文件为/etc/logrotate.conf
2、 子配置文件为/etc/logrotate.d
3、 参数说明
·daily 指定转储周期为每天
·weekly 指定转储周期为每周
·monthly 指定转储周期为每月
·compress 通过 gzip 压缩转储旧的日志
·nocompress 不需要压缩时,用这个参数
·copytruncate 用于还在打开中的日志文件,把当前日志备份并截断,是先拷贝再清空的方式,拷贝和清空之间有一个时间差,可能会丢失部分日志数据。(其实是先cp之后清空原来的日志,适合要求不高、日志量。不能自动生成日志文件的。)
·nocopytruncate 备份日志文件但是不截断(是直接mv改名,不丢失日志但是。不适合不能自动生成日志文件的服务。)
·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 所有的日志文件都转储完毕后统一执行一次脚本
·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
4 自定义日志轮转时间
现在需要将日志转储(切割)时间调整到每天的0点,即每天切割的日志是前一天的0点-23点59分59秒之间的内容。
4.1 日志转储流程
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日志成功
2、重点看一下 /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分之间执行。
4.2 定义每天23点59分转储nginx日志
由于dateformat只支持%Y、%m、%d、%s这4个参数,如:dateformat -%Y%m%d%s。只能以当前日期命名,在每天23:59为一天最后的时间,在此时截取日志正好截取当天的日志。如果每天零点执行脚本的话,以当日命名的日志实际为上一天的日志。所以我们要在每天的最后一分钟去切割日志,并以当天的日期命名。
4.2.1 方法一
我们可以创建一个文件夹,如 /etc/logrotate.d0/,放置每天需要执行的转储日志配置,然后设置计划任务,每天23点59分 logrotate –f 强制执行。具体操作如下:
mkdir –p /etc/logrotate.d0/
mv /etc/logrotate.d/nginx /etc/logrotate.d0/ # 具体配置内容参照上文
crontab –e
#nginx log logrotate
59 23 * * * /usr/sbin/logrotate –f /etc/logrotate.d0/nginx >/dev/null 2>&1
4.3 方法二(未实践,网友方法)
此方法谨慎,因为需要调整系统自身的配置。
通过上面的分析,调整如下:
1、调整/etc/anacrontab配置文件,将RANDOM_DELAY=0, START_HOURS_RANGE=0-22。
2、调整 /etc/cron.d/0hourly 配置文件,将01改为59(/etc/cron.daily那一行)。
这样logrotate就可以在每天23点59分转储日志(配置文件里设置的是daily)
5 注意
/etc/logrotate.d/目录下相应的配置文件要删掉,或者crontab的执行时间要在自动执行之前。因为每天只能允许执行一次,如果有文件了,默认是不覆盖的。
例如:我在23:59执行的crontab,我在/etc/logrotate.d文件内有nginx文件。我的crontab写的是
59 23 * * * /usr/sbin/logrotate –f /etc/logrotate.d0/nginx >/dev/null 2>&1
因为每天3点多会执行一次默认的(上边提到,默认执行时间)。所以23点59就不执行了。所以我每天截取的日志是3点到另一天3点的日志。这样并没有达到我们的目的。和之前没有两样。如果/etc/logrotate.d0/里有的文件,在/etc/logrotate.d/里不要有。
6 案例
6.1 Nginx
1、两个日志文件不同操作
/opt/nginx_log/pic.log {
rotate 40
daily
copytruncate
nocompress
notifempty
dateext
dateformat .%Y-%m-%d
missingok
}
/opt/nginx_log/san.log {
rotate 90
daily
copytruncate
compress
tifempty
dateext
dateformat .%Y-%m-%d
missingok
}
2、使用通配符
/opt/nginx_log/*.log {
rotate 30
daily
copytruncate
nocompress
notifempty
dateext
dateformat .%Y-%m-%d
missingok
}
6.2 Httpd
/var/log/httpd/*log {
missingok
notifempty
sharedscripts
postrotate
/sbin/service httpd reload > /dev/null 2>/dev/null || true
endscript
}
1 报错解决
1.1 报错内容
写完测试下logrotate是否生效,最好使用-fv选项,可以看到执行的过程,不然报错都不会发现。
# logrotate -fv ./tomcat7
error: Ignoring ./tomcat7 because of bad file mode - must be 0644 or 0444.
Allocating hash table for state file, size 15360 B
Handling 0 logs
set default create context
此报错意识是权限错误,因为文件权限必须是0644或者0444
1.2 解决方案
# chmod 644 tomcat7
# logrotate -fv ./tomcat7 #以下为输出,表示成功
reading config file ./tomcat7
Allocating hash table for state file, size 15360 B
Handling 1 logs
rotating pattern: /opt/tomcat7/logs/catalina.out forced from command line (30 rotations)
empty log files are not rotated, old logs are removed
considering log /opt/tomcat7/logs/catalina.out
log needs rotating
rotating log /opt/tomcat7/logs/catalina.out, log->rotateCount is 30
Converted ' .%Y-%m-%d' -> '.%Y-%m-%d'
dateext suffix '.2018-11-16'
glob pattern '.[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]'
glob finding old rotated logs failed
copying /opt/tomcat7/logs/catalina.out to /opt/tomcat7/logs/catalina.out.2018-11-16
set default create context to system_u:object_r:usr_t:s0
truncating /opt/tomcat7/logs/catalina.out
set default create context
8 参考文章:
1、 https://www.cnblogs.com/wushuaishuai/p/9330952.html#_label0
2、 https://blog.csdn.net/damiaomiao666/article/details/72597731