使用工具logrotate实现大日志文件的分割和转储

为什么需要用logrotate

通常情况下,系统运行时所产生的日志文件,会记录系统中已发生的一些重要的事件信息,经常被用于系统排障或系统性能分析。而对于比较忙碌的服务器,其日志文件大小会快速增长,大量消耗服务器的磁盘空间,造成磁盘空间不足,这也就成了一个不可忽视的问题。除此之外,查阅和处理一个体积庞大的日志文件也常常是件十分棘手的事情。

为了解决以上问题,自然而然的就想到了logrotate,它是linux系统自带的日志文件管理工具,它可以自动对日志进行截断(或轮循)、压缩以及删除旧的日志文件。例如,你可以设置logrotate,让/var/log/foo日志文件每30天轮循一次,并删除超过6个月的日志。配置完成后,logrotate的运作完全自动化,不必进行任何进一步的人为干预。另外,旧日志也可以通过电子邮件的方式发送到指定邮箱中。

安装logrotate(一般系统都会默认自动安装)

主流Linux发行版上都默认安装有logrotate包。如果出于某种原因,logrotate没有被系统自动安装,那么你可以使用apt-get或yum命令来手动安装。

在Debian或Ubuntu上:

apt-get install logrotate cron

在Fedora、CentOS或RHEL上:

yum install logrotate crontabs

logrotate的配置文件是/etc/logrotate.conf,我们通常不需要对它进行修改。每个应用程序的日志文件,其轮循策略被设置在独立的配置文件中,这些配置文件都会放在/etc/logrotate.d/目录下。

logrotate实现日志文件转储的工作原理

针对文章开头提出的因单个日志文件内容过大而导致的一系列问题,可以通过linux系统自带的logrotate来对系统生成的日志文件按照日期、大小等进行转储,让logrotate定期转储日志文件,并且保留指定数量的日志转储文件,以满足线上运维的需求。

其实logrotate转储日志文件的工作机制比较简单,即在linux系统下,Crontab每天都会执行logrotate,而logrotate每执行一次,就可以把我们的日志文件转储一次。

logrotate通过与定时任务Crontab结合来工作,就能满足定期,例如每天对日志文件进行转储的功能,其原理是:

Crontab在linux系统的/etc目录中有几个定时执行的脚本目录,例如:/etc/cron.daily,在该文件夹下保存了Crontab每天都会定时执行的脚本;目录/etc/cron.weekly下则是记录了Crontab每周都会定时执行的脚本。

我们可以看到在目录/etc/cron.daily中有个脚本文件:logrotate,这个脚本的内容为:

#!/bin/sh
/usr/sbin/logrotate /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERTexited abnormally with [$EXITVALUE]"
fi
exit 0

从上面的脚本内容可以看出,它主要是执行程序logrotate,并且启动logrotate的时候加载了配置文件/etc/logrotate.conf。

下面就是对这个配置文件 logrotate.conf 的内容进行简要说明:

# see "man logrotate" fordetails
# rotate log files weekly
weekly
# keep 4 weeks worth of backlogs
rotate 4
# create new (empty) log files afterrotating old ones
create
# use date as a suffix of the rotated file
dateext
# uncomment this if you want your logfiles compressed
#compress

# RPM packages drop log rotationinformation 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
minsize 1M
rotate 1
}
/var/log/btmp {
missingok
monthly
create 0600 root utmp
rotate 1
}
# system-specific logs may be also beconfigured here.

该文件的前半部分内容都是默认配置项,这些配置项可以被后续的配置所覆盖,这里需要关注的是配置项:include /etc/logrotate.d,它表示logrotate在启动的时候还要把目录/etc/logrotate.d中的配置文件都执行一遍。

实际上,为了便于使用,每个应用程序都可以编写自己的logrotate配置文件,然后把编写好的配置文件放在目录/etc/logrotate.d下,这样每个程序自己的配置项就会把上面的默认配置项给覆盖掉。

覆盖默认配置项的具体过程如下:

(1)logrotate的启动脚本被放在了Crontab每天执行的脚本目录中/etc/cron.daily,这样Crontab每天都会执行一次logrotate;

(2)logrotate启动的时候,加载了配置文件/etc/logrotate.conf;

(3)配置文件/etc/logrotate.conf 又引入了目录:/etc/logrotate.d;

(4)我们在/etc/logrotate.d目录下新建了一个自己的logrotate配置文件;

(5)这样,当logrotate每次启动的时候就会执行加载我们自己新建的logrotate配置文件,从而按照我们设定的配置项来转储我们指定的日志文件。

以mosquitto日志文件为例说明

(1)在目录/etc/logrotate.d/下创建一个日志转储的配置文件(名字可以自己定义,只要在该目录下就会被执行):mosquitto

(2)配置文件mosquitto的内容如下:

/home/logs/mosquitto/mosquitto.log {
daily
dateext
copytruncate
nocompress
rotate 15
}

以下是该配置文件的内容说明:

  • 第一行左大括号之前的/home/logs/mosquitto/mosquitto.log 指出了要转储的日志文件的具体位置和文件名;

  • daily:按天去转储;

  • dateext:表示转储后的日志文件会附加上日期信息

  • copytruncate:对于正在open中的日志文件,会把当前日志备份并截断

  • nocompress:表示不要对转储的日志压缩

  • rotate 15:表示最多保留多少个转储之后的日志文件

(3)确保刚才新建的mosquitto配置文件的权限为:-rw-r–r–

注意:该配置文件的权限不能错,如果你修改为其他的,例如:-rwxrwxrwx,虽然你放开了权限,但是logrotate在运行时仍会报错:

/usr/sbin/logrotate -vf /etc/logrotate.d/

Ignoring mosquitto because of bad filemode.

进而造成logrotate读取你的配置文件失败!!!!

(4)查看log文件所在父目录的权限,确保group权限和other权限中没有“w”权限,否则在执行logrotate转储命令时会报错:

logrotate执行轮询异常,“considering log /home/logs/mosquitto/mosquitto.log
error: skipping “/home/logs/mosquitto/mosquitto.log” because parent directory has insecure permissions (It’s world writable or writable by group which is not “root”) Set “su” directive in config file to tell logrotate which user/group should be used for rotation.”

如果发现group权限和other权限中含有“w”权限,则需使用chmod命令删除“w”权限,具体命令如下:

chmod go-w /home/logs/mosquitto

(5)最后测试一下配置文件的配置内容是否有误。执行logrotate转储命令:

/usr/sbin/logrotate -vf /etc/logrotate.conf

可以看到新生成的转储文件与原日志文件在同一个目录下,如下所示:

-rwxrwxrwx. 1 root root 482 5月  18 15:36 mosquitto.log
-rwxrwxrwx. 1 root root 950 5月 18 15:25 mosquitto.log-20210518

这样后续每天原始日志文件的内容都会自动备份和截断,在当前目录下自动生成一个带有日期标签的日志转储文件。