编辑logrotate的配置文件

cat /etc/logrotate.d/nginx
/user/webuser01/nginx-1.18.0/logs/*.log {
daily
rotate 3
missingok
dateext
notifempty
compress
delaycompress
create 644 webuser01 webuser01
sharedscripts
postrotate
[ ! -f /user/webuser01/nginx-1.18.0/nginx.pid ] || kill -USR1 `cat /user/webuser01/nginx-1.18.0/nginx.pid`
endscript
}

compress 通过 gzip 压缩转储以后的日志 nocompress 不做 gzip 压缩处理 create mode owner group 轮转时指定创建新文件的属性,如 create 0777 nobody nobody nocreate 不建立新的日志文件 delaycompress 和 compress 一起使用时,转储的日志文件到下一次转储时才压缩 nodelaycompress 覆盖 delaycompress 选项,转储同时压缩。 missingok 如果日志丢失,不报错继续滚动下一个日志 ifempty 即使日志文件为空文件也做轮转,这个是logrotate的缺省选项。 notifempty 当日志文件为空时,不进行轮转 mail address 把转储的日志文件发送到指定的E-mail 地址 olddir directory 转储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统 noolddir 转储后的日志文件和当前日志文件放在同一个目录下 sharedscripts 运行postrotate脚本,作用是在所有日志都轮转后统一执行一次脚本。如果没有配置这个,那么每个日志轮转后都会执行一次脚本 prerotate 在logrotate转储之前需要执行的指令,例如修改文件的属性等动作;必须独立成行 postrotate 在logrotate转储之后需要执行的指令,例如重新启动 (kill -HUP) 某个服务!必须独立成行 daily 指定转储周期为每天 weekly 指定转储周期为每周 monthly 指定转储周期为每月 rotate count 指定日志文件删除之前转储的次数,0 指没有备份,5 指保留5 个备份 dateext 使用当期日期作为命名格式 dateformat .%s 配合dateext使用,紧跟在下一行出现,定义文件切割后的文件名,必须配合dateext使用,只支持 %Y %m %d %s 这四个参数 size(或minsize) log-size 当日志文件到达指定的大小时才转储,log-size能指定bytes(缺省)及KB (sizek)或MB(sizem).当日志文件 >= log-size 的时候就转储。 (size = 5,无单位为字节,单位可以为K,M,G) size 参数跟转储周期参数:hourly、daily、monthly、yearly完全是互斥的。即是说,一旦设置了size参数,转储周期参数就自动无效了,只要每次执行logrotate指令时,log文件大小超过size,就会触发一次滚动,没有滚动周期一说了。 maxsize 在logrotate执行时,每满足文件大小maxsize就转储一次,不满足则按照转储周期转储1次,(每个转储周期内,n次或1次) minsize 在logrotate执行时,满足文件大小大于minsize则滚动一次,不满足则滚动0次,(每个滚动周期内,1次或0次)

值得注意的一个配置是:copytruncate

copytruncate 如果没有这个选项的话,操作方式:是将原log日志文件,移动成类似log.1的旧文件, 然后创建一个新的文件。如果设置了,操作方式为拷贝原日志文件,并且将其变成大小为0的文件。

区别是如果进程,比如nginx使用了一个文件写日志,没有copytruncate的话,切割日志时, 把旧日志log->log.1,然后创建新日志log。

这时候nginx打开的文件描述符依然时log.1,由没有信号通知nginx要换日志描述符,所以它会继续向log.1写日志,但我们希望切割日志后,nginx 自动会向新的log 文件写日志,而不是旧的log.1文件。

解决方法有两个:

  • 在postrotate里写个脚本
postrotate
在logrotate转储之后需要执行的指令,例如重新启动 (kill -HUP) 某个服务!必须独立成行
[ -s /run/nginx.pid ] && kill -USR1 `cat /run/nginx.pid`
endscript

这样就是发信号给nginx,让nginx关闭旧日志文件描述符,重新打开新的日志文件描述,并写入日志。

  • 使用copytruncate参数,配置以后,操作方式为将log 复制一份 成为log.1,然后清空log的内容,使大小为0,那此时log依然时原来的旧log,对进程(nginx)来说,依然打开的是原来的文件描述符,可以继续往里面写日志,而不用发送信号给nginx,copytruncate这种方式操作,拷贝和清空之间有一个时间差,可能会丢失部分日志数据。

logrotate配置文件编辑完成后,创建crontab计划任务

crontab -e
0 * * * /usr/sbin/logrotate  -f /etc/logrotate.d/nginx > /dev/null 2>&1 #注意,此处的-f表示强制执行

注意,如果logrotate执行命令为-f强制执行,则其配置文件中的daliy,size,maxsize,minsize将全部无视,只会按照crontab的执行周期进行日志分割,因此建议如果设置按照文件大小分割日志,正确的计划任务如下:

crontab -e
0 * * * /usr/sbin/logrotate /etc/logrotate.d/nginx > /dev/null 2>&1

这样logrotate就在执行时自动检查,老老实实按照我们的规则进行日志的分割。