参考文章: Linux 日志切割神器 logrotate 原理介绍和配置详解
logrotate 简介
logrotate 是一个 linux 系统日志的管理工具。可以对单个日志文件或者某个目录下的文件按 时间/大小
进行切割,压缩操作;指定日志保存数量;还可以在切割之后运行自定义命令。
logrotate 是基于 crontab 运行的,所以这个时间点是由 crontab 控制的,具体可以查询 crontab 的配置文件 /etc/anacrontab
。系统会按照计划的频率运行 logrotate,通常是每天。在大多数的 Linux 发行版本上,计划每天运行的脚本位于 /etc/cron.daily/logrotate
。
主流 Linux 发行版上都默认安装有 logrotate 包,如果你的 linux 系统中找不到 logrotate, 可以使用 apt-get 或 yum 命令来安装。
logrotate 运行机制
logrotate 在很多 Linux 发行版上都是默认安装的。系统会定时运行 logrotate,一般是每天一次。系统是这么实现按天执行的,crontab 会每天定时执行 /etc/cron.daily
目录下的脚本,而这个目录下有个文件叫 logrotate。在 centos 上脚本内容是这样的
1 |
|
可以看到这个脚本主要做的事就是以 /etc/logrotate.conf
为配置文件执行了 logrotate。就是这样实现了每天执行一次 logrotate。
很多程序的会用到 logrotate 滚动日志,比如 nginx。它们安装后,会在 /etc/logrotate.d
这个目录下增加自己的 logrotate 的配置文件。logrotate 什么时候执行 /etc/logrotate.d
下的配置呢?看到 /etc/logrotate.conf
里这行,一切就不言而喻了。
1 | include /etc/logrotate.d |
logrotate 原理
logrotate 是怎么做到滚动日志时不影响程序正常的日志输出呢?logrotate 提供了两种解决方案。
- create: 重命名原日志文件,创建新的日志文件
- copytruncate: 把正在输出的日志复制一份出来,再清空原来的日志
create
默认的方案,可以通过 create
命令配置文件的权限和属组设置;这个方案的思路是重命名原日志文件,创建新的日志文件。详细步骤如下:
- 重命名正在输出日志文件,因为重命名只修改目录以及文件的名称,而进程操作文件使用的是 inode,所以并不影响原程序继续输出日志。
- 创建新的日志文件,文件名和原日志文件一样,注意,此时只是文件名称一样,而 inode 编号不同,原程序输出的日志还是往原日志文件输出。
- 最后通过某些方式通知程序,重新打开日志文件;由于重新打开日志文件会用到文件路径而非 inode 编号,所以打开的是新的日志文件。
copytruncate
该方案是把正在输出的日志拷 (copy) 一份出来,再清空 (trucate) 原来的日志;详细步骤如下:
- 将当前正在输出的日志文件复制为目标文件,此时程序仍然将日志输出到原来文件中,此时,原文件名也没有变。
- 清空日志文件,原程序仍然还是输出到预案日志文件中,因为清空文件只把文件的内容删除了,而 inode 并没改变,后续日志的输出仍然写入该文件中。
配置 logrotate
由于 logrotate 实际上只是一个可执行文件,不是以 daemon 运行。所以修改配置文件后,并不需要重启服务。
- 执行文件:
/usr/sbin/logrotate
- 主配置文件:
/etc/logrotate.conf
- 自定义配置文件目录:
/etc/logrotate.d
以下是主配置文件
/etc/logrotate.conf
的内容1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35# see "man logrotate" for details
# rotate log files weekly
weekly # 配置日志转储周期按周来转储
# keep 4 weeks worth of backlogs
rotate 4 # 配置日志保留备份数为 4
# create new (empty) log files after rotating old ones
create # 创建新文件
# use date as a suffix of the rotated file
dateext # 使用日期作为新文件名后缀
# uncomment this if you want your log files compressed
#compress # 是否压缩日志文件
# RPM packages drop log rotation information 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 be configured here./etc/logrotate.d/
通常一些第三方软件包,会把自己私有的配置文件,也放到这个目录下。如 yum,zabbix-agent,syslog,nginx 等。
运行 logrotate
具体 logrotate 命令格式如下:
1 | logrotate [OPTION...] <configfile> |
执行方式
通常惯用的做法是配合 crontab 来定时调用。
1
*/30 * * * * /usr/sbin/logrotate /etc/logrotate.d/rsyslog > /dev/null 2>&1 &
手动运行
1
2
3
4
5# Debug 模式,指定 [-d|--debug],并不会真正进行 rotate 或者 compress 操作,但是会打印出整个执行的流程,和调用的脚本等详细信息。
logrotate -d <configfile>
# verbose 模式,指定 [-v|--verbose],会真正执行操作,打印出详细信息(debug 模式,默认是开启 verbose)
logrotate -v <configfile>
logrotate 参数
这里主要介绍完成常用需求会用到的一些参数。详细介绍请自行 man logrotate
, 或者 在线 man page
一个典型的配置文件如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14# cat /etc/logrotate.d/log_file
/var/log/log_file {
monthly
rotate 5
compress
delaycompress
missingok
notifempty
create 644 root root
postrotate
/usr/bin/killall -HUP rsyslogd
endscript
}- monthly: 日志文件将按月轮循。其它可用值为
daily
,weekly
或者yearly
。 - rotate 5: 只存储 5 个归档日志。对于第六个归档,时间最久的归档将被删除。
- compress: 在轮循任务完成后,已轮循的归档将使用 gzip 进行压缩。
- delaycompress: 总是与 compress 选项一起用,delaycompress 选项指示 logrotate 不要将最近的归档压缩,压缩将在下一次轮循周期进行。
- missingok: 在日志轮循期间,任何错误将被忽略,例如 “文件无法找到” 之类的错误。
- notifempty: 如果日志文件为空,轮循不会进行。
- create 644 root root: 以指定的权限创建全新的日志文件,同时 logrotate 也会重命名原始日志文件。
- postrotate/endscript: 在所有其它指令完成后,
postrotate
和endscript
里面指定的命令将被执行。在这种情况下,rsyslogd
进程将立即再次读取其配置并继续运行。
- monthly: 日志文件将按月轮循。其它可用值为
以下配置文件中,我们只想要轮询一个日志文件,
size=50M
指定日志文件大小可以增长到 50MB, dateext 指示让旧日志文件以创建日期命名。1
2
3
4
5
6
7
8
9/var/log/log_file {
size=50M
rotate 5
dateext
create 644 root root
postrotate
/usr/bin/killall -HUP rsyslogd
endscript
}
常见的参数说明
- daily :指定转储周期为每天
- weekly :指定转储周期为每周
- monthly :指定转储周期为每月
- rotate count :指定日志文件删除之前转储的次数,0 指没有备份,5 指保留 5 个备份
- tabooext [+] list:让 logrotate 不转储指定扩展名的文件,缺省的扩展名是:.rpm-orig, .rpmsave, v, 和~
- missingok:在日志轮循期间,任何错误将被忽略,例如 “文件无法找到” 之类的错误。
- size size:当日志文件到达指定的大小时才转储,bytes (缺省) 及 KB (sizek) 或 MB (sizem)
- compress: 通过 gzip 压缩转储以后的日志
- nocompress: 不压缩
- copytruncate:用于还在打开中的日志文件,把当前日志备份并截断
- nocopytruncate: 备份日志文件但是不截断
- create mode owner group : 转储文件,使用指定的文件模式创建新的日志文件
- nocreate: 不建立新的日志文件
- delaycompress: 和 compress 一起使用时,转储的日志文件到下一次转储时才压缩
- nodelaycompress: 覆盖 delaycompress 选项,转储同时压缩。
- errors address : 专储时的错误信息发送到指定的 Email 地址
- ifempty :即使是空文件也转储,这个是 logrotate 的缺省选项。
- notifempty :如果是空文件的话,不转储
- mail address : 把转储的日志文件发送到指定的 E-mail 地址
- nomail : 转储时不发送日志文件
- olddir directory:储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统
- noolddir: 转储后的日志文件和当前日志文件放在同一个目录下
- prerotate/endscript: 在转储以前需要执行的命令可以放入这个对,这两个关键字必须单独成行
示例
这里以 pur 应用为示例,配置日志切割,由于 pur 应用不支持重新打开日志文件,所以需要使用 copytruncate 模式进行切割,pur 应用的日志文件存放位置为 /var/log/pur/pur.log
,以下是详细的步骤。
创建 pur 自定义的日志切割配置文件 /etc/logrotate.d/pur,文件内容如下:
1
2
3
4
5
6
7
8
9
10
11/var/log/pur/pur.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
copytruncate
dateext
create 0644 deployer deployer
}使用
-d
参数测试配置文件1
2
3
4
5
6
7
8
9
10[root@pur-pre ~]# logrotate -d /etc/logrotate.d/pur
reading config file /etc/logrotate.d/pur
Allocating hash table for state file, size 15360 B
Handling 1 logs
rotating pattern: /var/log/pur/pur.log after 1 days (7 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/pur/pur.log
log does not need rotating (log has been rotated at 2021-8-17 21:38, that is not day ago yet)使用
-f
参数强制执行日志切割,-v
显示详细信息1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17[root@pur-pre ~]# logrotate -fv /etc/logrotate.d/pur
reading config file /etc/logrotate.d/pur
Allocating hash table for state file, size 15360 B
Handling 1 logs
rotating pattern: /var/log/pur/pur.log forced from command line (7 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/pur/pur.log
log needs rotating
rotating log /var/log/pur/pur.log, log->rotateCount is 7
dateext suffix '-20210817'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
glob finding logs to compress failed
glob finding old rotated logs failed
copying /var/log/pur/pur.log to /var/log/pur/pur.log-20210817
truncating /var/log/pur/pur.log查看新生成的日志
1
2
3
4[root@pur-pre ~]# ll /var/log/pur/
total 4
-rw-r--r-- 1 root root 0 Aug 17 22:27 pur.log
-rw-r--r-- 1 root root 1987 Aug 17 22:27 pur.log-20210817