Nginx - 使用 logrotate 进行日志分割

时间:2020-08-28

在一次测试中,为了方便,直接使用了 Yum 安装 nginx ,使用起来也没差,第二天在登录上来的时候,发现 ngx 自动对 日志进行了归档而且打包,如图:

之前为了实现这个功能是通过 shell 脚本 + crond 来做,但是这次只是通过 yum install nginx -y 就实现了这个日志归档操作,为了究其原因,展开了学习。

Logrotate 实现日志切割

稍微一查询发现了原来是 Logrotate 这个工具实现的日志切割,查看 logrotate 包:

总共也就这些文件,/etc/cron.daily/logrotate  一看这个文件就知道和 crond 联系起来了。

这是一个每日执行的 cron 脚本,logrotate 实际会调用它的主配置文件:/etc/logrotate.conf

logrotate.conf 主配置文件如下:

这个主配置文件也就是起到一个默认配置项的作用,在这个配置文件中找到了 include /etc/logrotate.d  这个很容易理解,简单来说:/etc/logrotate.d/ 是 logrotate的扩展文件夹,需要的个性化配置在这里面。

查看 /etc/logrotate.d/

/etc/logrotate 里文件就多了, 这里找到了 nginx 、php-fpm、甚至还有 zabbix-agent , 查看下 nginx

头大, 最讨厌这种异类,如果是 shell 脚本就很容易理解。没办法,只能查询下具体的语法意义了。

/var/log/nginx/*log { # 需要轮询日志路径 create 0664 nginx root # 以指定的权限创建全新的日志文件 daily # 日志文件切割频率 daily: 每日,monthly: 每月,weekly: 每周,yearly: 每年 rotate 10 # 一次将存储10个归档日志,对于第11个归档,时间最久的归档将删除 missingok # 在日志轮询期间,任何错误将被忽略,例如:文件无法找到 之类的错误 notifempty # 如果文件为空,将不会对日志进行归档 compress # 在日志归档之后,对日志进行gzip压缩 sharedscripts # 表示下面 postrotate 脚本在压缩日志之后只执行一次 postrotate # 脚本开始 /bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true # 脚本正文 endscript # 脚本结束 } sharedscripts / postrotate / endscript 通常是成套出现的,而这里的脚本主要也是让程序重启,以切换到新的日志文件 还有一个比较方便的参数,这里没有用上: dateext: 使用日期作为命名格式 

有了以上对 logrotate 的了解,在测试环境中进行测试下具体的运行:

使用源码编译的 nginx 是没有对 logrotate 设置的

为 ngx 添加 日志切割脚本:

如上配置就完成了,nginx 每天日志归档压缩的操作,是不是比自己编写 shell脚本方便很多?真的是有发现新大陆的感觉。

配置完成需要调试或者运行一次验证下,首先进行 debug 模式测试:

[root@192.168.118.11 ~]#logrotate -d -f /etc/logrotate.d/nginx reading config file /etc/logrotate.d/nginx Allocating hash table for state file, size 15360 B Handling 1 logs rotating pattern: /usr/local/nginx/logs/*log forced from command line (10 rotations) empty log files are not rotated, old logs are removed considering log /usr/local/nginx/logs/access.log log needs rotating considering log /usr/local/nginx/logs/error.log log does not need rotating (log is empty)rotating log /usr/local/nginx/logs/access.log, log->rotateCount is 10 dateext suffix '-20200426' glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' glob finding old rotated logs failed renaming /usr/local/nginx/logs/access.log to /usr/local/nginx/logs/access.log-20200426 creating new /usr/local/nginx/logs/access.log mode = 0664 uid = 80 gid = 0 running postrotate script running script with arg /usr/local/nginx/logs/*log : " /bin/kill -USR1 `cat /usr/local/nginx/logs/nginx.pid 2>/dev/null` 2>/dev/null || true " compressing log with: /bin/gzip 

主要是关注 error ,以上没有任何语法报错信息,接下来就可以手动执行一次看看是否生效:

这样就执行完成了,接下来查看下日志目录是否归档:

可以发现 logrotate执行过程,首先将 access.log 重命名为 access.log-20200426 然后在使用 gzip 归档

这里为什么 error.log 没有做归档呢?这是因为我们在 /etc/logrotate.d/nginx 中配置了参数: notifempty # 如果文件为空,将不会对日志进行归档。

以上就实现了nginx 每天日志的归档验证,比起 shell脚本效率要高很多。以后关于日志归档切割备份的工作,全部可以交给 logrotate 来处理。

码字不易,如果您觉得文章写得不错,您又有闲心的话,请点击广告支持