首页 / 51CTO / 正文

相关推荐

51CTO 2020-05-23 08:04:07
Linux自带神器logrotate详解
佚名  马哥Linux运维  2020-05-22

相关推荐

周一上班,就被开发组那哥们儿拉进电话会议,说他们的服务又挂了,估计磁盘又爆掉了。登录到web服务上,上来 df -h 一把,果然,挂的一个共享又被撑爆。 

 

上次是因为liferay的log太大,这次再看看liferay的log 

 

我列个去,尼玛,一个liferay log文件,能增长到90G,这也太扯了 吧。果断删掉,不知道为什么,每当我要敲rm -rf的时候,心里就莫名的紧张。。。 

 

重启一下服务 

 

随后通知了一下开发组那哥们儿,服务器磁盘已经清理,服务已经重启,那边也确认了web服务又活了,可以用了。随后,又检查了一下其它文件夹,结果发现catalina.out这个日志文件,又是超级无敌大:89G,我也是醉了。 

 

问题虽然解决了,但是这个问题本来就不应该发生啊!难道之前做运维的同事都没有做脚本来监控和限制日志大小嘛?这可是生产系统啊!这样可不行,既然没人搞,我就来搞搞。于是网上搜了一把,原来Linux系统就自带了一个日志切割神器——>logrotate

man了一下logrotate,看到了以下描述:logrotate is designed to ease administration of systems that generate large numbers of log files. It allows automatic rotation, compression, removal, and mailing of log files. Each log file may be handled daily, weekly, monthly, or when it grows too large.

Normally, logrotate is run as a daily cron job. It will not modify a log more than once in one day unless the criterion for that log is based on the log's size and logrotate is being run more than once each day, or unless the -f or --force option is used.

原来这个神器是为了方便管理系统大量日志文件而设计的,对日志文件可实现自动rotation(字面意思是旋转,觉得理解成日志循环更好一些),压缩,删除和通过email发送log文件。颗粒度控制很好,可以针对每一个log文件进行每天,每周,每个月或者当log文件过大时进行rotate。

一般情况下呢,logrotate是基于每天的cron job来执行的,所以对某个log文件的rotae每天执行一次,除非rotate的执行标准是基于log文件大小,并且你logrotate这个命令每天被执行了多次,也就是你自定义了定时任务,让logrotate每x分钟或者每x小时执行一次,再或者你手动执行这个命令添加了-f/--force这个选项。

另外,我发现这个神器是系统自带的,可想而知这个工具是多么的重要,否则Linux也不会默认就安装了这个工具。

那接下来,我们来看看logrotate的相关配置以及如何执行logrotate。

logrotate的conf文件在 /etc/下: 

 

那我们来看看logrotate.conf文件里面的内容: 

 

关于rotate规则的配置,从上面的logrotate.conf文件里可以看到,有两个地方可以配置:

  • 一种是直接在logrotate.conf里配置,不过一般适用于非RPM包的系统日志文件。
  • 另外一种是如果你要做rotate的日志文件是由第三方RPM包软件产生的,需要在/etc/logrotate.d这个文件夹下新建一个配置文件,配置相关rotate规则。(UnleBen发现,其实如果你安装了第三方的软件包之后,在/etc/logrotate.d这个文件夹下就会自动创建了对应软件的rotate配置文件。)

相关推荐

UncleBen这里准备了一台干净的CentOS7,在安装httpd这个服务之前,我们来看一下/etc/logrotate.d这个文件夹下面都有哪些配置文件 

 

我们现在安装一下httpd服务: 

 

再去/etc/logrotate.d这个文件夹下看一下: 

 

可以看到,安装httpd之后,自动创建好了针对httpd服务的log rotate配置文件,打开看看: 

 

这就是一个标准的,针对第三方软件的一个logrotate配置文件,简单说明一下:

格式:

  • log文件的路径(支持通配符*),再加上一对花括号{}
  • 花括号里面的内容就是logrotate的规则参数,需要单独成行。

参数解读:

missingok: 如果日志不存在,不产生错误信息

notifempty:如果日志文件为空,不做rotate,这个跟你ifempty互斥

sharedscripts:配合prerotate and postrotate 使用,sharedscripts 开启的话,如果使用了对需要做rotate的log文件使用了

通配符,那么*

prerotate** and postrotate 的脚本只会执行一次。没有sharedscripts 的话,每个需要log文件做rotate的时候都会执行一遍prerotate and postrotate 的脚本

delaycompress:延迟压缩旧的日志文件,先rotate,不进行压缩,等到下次rotate时,才会压缩上次rotate的文件。这个需要跟compress一起使用,单独使用不生效。

postrotate/endscript:rotate之后想要执行的脚本,需要放在postrotate 与 endscript中间,这两个选项要单独成行。

除了上面的参数外,还有以下常见参数: 

 

rotate的规则是配置好了,但是怎么来执行呢?我们来help一下。 

 

这里着重说一下-d和-f两个选项:

-d:debug模式,就是先演练一遍,不是真干。

-f:强制模式,实打实的执行。

从上面我们man logrotate的信息可以了解到:一般情况下呢,logrotate是基于每天的cron job来执行的,所以对某个log文件的rotae每天执行一次,除非rotate的执行标准是基于log文件大小,并且你logrotate这个命令每天被执行了多次,也就是你自定义了定时任务,让logrotate每x分钟或者每x小时执行一次,再或者你手动执行这个命令添加了-f/--force这个选项。

为什么是每天执行一次呢?我们去/etc/cron.daily/,/etc/cron.weekly/,/etc/cron.monthly/,/etc/cron.hourly/可以看到,在/etc/cron.daily/这个文件夹下有一个logrotate可执行脚本,那每天就会跑一次啦! 

 

那我们来看看logrotate脚本里写的什么内容: 

 

简单理解就是执行logrotate命令,并且指定执行logrotate时状态文件和执行的conf文件:/etc/logrotate.conf。大家还记不记得在这个文件里,有一行:include /etc/logrotate.d,也就是说在执行logrotate.conf这个文件时,一并执行/etc/logrotate.d文件夹下的配置文件。下面几行就是执行出错时,logger一下。

所以,我们执行logrotate时,可以直接运行:logrotate + confi文件名 

 

如果一切顺利,那么logrotate命令会执行成功,httpd的日志文件会被按照你配置的规则进行rotate。但是如果没有达到你的期望结果,你就需要来debug了。其实推荐大家在放到生产环境之前,最好好是用-d选项来测试一下你写的配置文件是否可以达到你的预期。我们来看一下加上-d选项的运行结果: 

 

现在我们把httpd这个logrotate的流程梳理一下:

  • httpd这个logrotate的配置文件会每天被执行一次,因为logrotate脚本默认放置在/etc/cron.daily/下,脚本会根据/etc/logrotate.conf配置文件来执行logrotate命令,而针对httpd服务的logrotate配置文件在/etc/logrotate.d/下,此文件夹被包含在了/etc/logrotate.conf配置文件里。
  • 如果/var/log/httpd/下没有以log结尾的文件也不会记录错误信息。
  • 如果/var/log/httpd/下的log文件是空文件,那么不会执行rotate操作。
  • 在执行logrotate之后,httpd服务会被重新加载

对于大多数情况下,每天把日志备份一下已经足够了。但是像UncleBen周一遇到的这种case:一天之内,log日志把磁盘给撑爆了。那这种case,用logrotate该如何解决呢?

首先我们来捋一下需求:

  • 要解决log文件一天之内增长过快,撑爆磁盘的问题。所以关键词就是:一天之内->时间,撑爆磁盘->文件大小

执行周期

logrotate默认是每天,我们的需求是一天之内,所以可以让logrotate每半天(每12小时)、每8个小时、每4个小时、每2个小时,甚至是每小时执行一次,都可以。这个看各位心情。

文件大小

超过多大才执行logrotate,这个也是根据实际环境来确定。UncleBen遇到这个case,日志竟然暴涨到89G,我这里就设置成超过1G大小就进行rotate。

为了能让各位客官老爷们看到真是的效果,我这里做了一点小小的改动,话不多说了,上demo:

httpd logrotate的配置文件更改如下:

version1:在原来基础上增加了一行:rotate 3 

 

然后我来创建一个cron job,每分钟执行一次: 

 

然后创建一个监控httpd文件夹下log文件的脚本: 

 

我们来执行一下monitorlog.sh,来观察一下httpd的日志文件。注意:我这里是访问了Apache默认的站点,然后手动刷新Apache站点,来产生点access log,然后停止刷新页面。 

 

我们可以看到:

  • 由于我设定的是每分钟执行一次logrotate,并且指定了httpd这个logrotate配置文件,所以我们配置的规则会每分钟被执行一次。
  • /var/log/httpd/这个文件夹下:
    • 只有access_log和error_log这两个文件。
    • Apr 24 14:09时,access_log文件大小是79K, error_log文件大小是12K。
  • 停止刷新页面,等待一分钟之后
  • /var/log/httpd/这个文件夹下:
    • 增加了两个文件:access_log.1和error_log.1
    • Apr 24 14:10时,access_log文件被清空,大小为0;而error_log不是空的,证明一直有error信息产生。
  • 为了验证notifempty这个参数是否生效,我们不刷新页面,再多等两分钟,然后从monitorlog.sh执行的结果来看:
  • access_log没有被rotate,因为在第一次access log文件被rotate之后,没有访问日志产生,它的大小为0,我们在配置文件里加了notifempty这个参数,意思就是如果为空,不做rotate。

Apr 24 14:13 /var/log/httpd/文件夹下信息: 

 

rotate 3这个参数:

  • 始终保留3份rotate的文件,那我们多等几分钟,再看看/var/log/httpd/这个文件夹下有哪些文件,即可验证。
  • rotate后的文件名:是以.数字结尾。

Apr 24 14:14 /var/log/httpd/文件夹下信息: 

 

Apr 24 14:15 /var/log/httpd/文件夹下信息: 

 

delaycompress这个参数:

  • 是必须要和compress一起使用的,单独使用无效,可以看到没有任何log文件被压缩处理,rotate前和rotate后的文件大小保持一致。

postrotate/endscript这个参数里的脚本:/bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true endscript

就是在log日志被rotate之后,需要重新reload httpd service,如果没有这个脚本会怎么样呢?我们来到/etc/logrotate.d/httpd里,把这3行注释掉。再到monitorlog.sh执行的结果来看看: 

 

注释掉postrotate/endscript脚本后,我们发现:

  • error_log文件在执行rotate之后,新的error_log并没有被创建出来。
  • 我们来刷新一下页面,尝试产生新的access log,发现可以正常写入,大小有变化。 
 
  • 但是我们等待文件被rotate之后,再来观察一下,我们发现,access_log在被rotate之后,新的access_log文件同样没有被创建出来。 
 
  • 如果我们继续尝试刷新页面,发现access_log.1和error_log.1日志大小都会增长。这个就可以说明postrotate/endscript中间脚本的作用了,如果没有这个脚本,也就是在执行logrotate之后,没有reload httpd service,那么httpd服务会继续往旧的log日志中写信息,那么针对/var/log/httpd/*log后续的logrotate命令都不会被执行。为什么?
  • 配置文件里的文件路径写了:/var/log/httpd/*log,你是针对以log结尾的文件名。
  • 现在被rotate之后的文件名全都是以 . 数字结尾的。 
 

记不记得我们还有一个参数叫copytruncate,我们来试试,在没有postrotate/endscript脚本时,加上这个参数是什么效果。

version2:删除postrotate/endscript脚本,增加copytruncate 

 

我们先stop httpd service,然后删除所有的access_log和error_log, 最后start httpd service,可以看到,httpd的日志文件正常产生了。 

 

接下来我们再刷新一下页面,产生一些access log和error log,等待几分钟,执行mornitorlog.sh来看一下:

  • access_log和error_log都可以正常rotate。
  • 新的access_log和error_log文件都可以被创建出来,并且可以正常写入log日志。 
 

所以,比起放在postrotate/endscript中间的reload httpd service脚本,我更喜欢用copytruncate这个参数。

version3:在version2的基础上,增加dateext参数 

 

我们尝试访问页面,刷新,产生一些access log和error log。等待几分钟,我们执行monitorlog.sh来看一下,可以发现:

  • 最近一次被rotate log文件时以日期格式结尾的。
  • 我们的cron job规定每分钟执行一次logrotate,但是在添加dateext参数之后失效了。所以:
    • 如果你想要logrotate每天执行多次(大于一次),就不要添加dateext参数。
    • 如果你既想要logrotate每天执行多次(大于一次),还想rotate之后的文件以日期格式结尾,有一种方法就是添加dateformat .%s参数。 
 

version4:在version3的基础上,增加dateformat -%Y%m%d%H.%s参数 

 

我们再次尝试访问页面,刷新,产生一些access log和error log。等待几分钟,我们执行monitorlog.sh来看一下,可以发现:

  • 我们的cron job现在执行正常了,当log文件非空并且有更新时,可以被执行多次。
  • 被rotate之后的文件是以日期格式结尾的:
    • -横杠开头,接着时年月日时,然后句点. 最后是秒,但是最后的.s%是从1970年1月1日00:00:00到目前经历的秒数。 
 

给大家留个问题:如果dateformat定义的格式是:-%Y%m%d%H,那么在日志文件非空并且持续更新的情况下,access_log和error_log会多久被rotate一次?

version5:在version4的基础上,增加size 50K参数 

 

这一次,我们先执行monitorlog.sh来看一下access_log和error_log的大小,再尝试访问页面,刷新,产生一些access log和error log,注意一下,因为我配置的size大小是50K,所以让access_log文件大小<50K,然后等待几分钟,观察monitorlog.sh输出,可以发现:

  • access_log和error_log文件都没有被rotate,因为他们的大小都没有超过50K,从下面的结果可以看出:
  • access_log大小是49K
  • error_log大小是6.6K 
 
  • 现在我们继续刷新页面,让access_log大小>50K,观察monitorlog.sh输出,可以发现:
  • Apr 24 18:12时
    • logrotate被执行了一次,由于access_log文件大小>50K,所以就被rotate了。并保存为:access_log-2020042418.1587723121
    • 由于error_log文件大小<50K,所以此次logrotate忽略了这个文件。 
 

version6:在version5的基础上,增加compress参数 

 

我们继续刷新页面,让access_log大小>50K,观察monitorlog.sh输出,可以发现:

  • Apr 24 17:59时
    • logrotate被执行了一次,由于access_log文件大小>50K,所以就被rotate了,并且被做了压缩处理,保存为:access_log-2020042417.1587722341.gz
    • 被压缩之前大小是7.5K,被压缩后是398,不到1k,所以强烈推荐添加这个参数,节省空间啊!!!
    • 由于error_log文件大小<50K,所以此次logrotate忽略了这个文件。 
 

好了,以上就是关于logrotate这个神器的用法介绍,如有不同理解或者UncleBen有理解错误的地方,还请指正。也希望这个介绍能帮到大家。 

【责任编辑:庞桂玉 TEL:(010)68476606】

 

分享到朋友圈 分享到微博
相关推荐
相关推荐

时讯快报

5.5亿用户的选择

立即打开