Linux 学习与进阶之日志切割 Logrotate

 Technique  comment

Linux 上的日志切割工具 logrotate 是最方便、最高效的日志综合管理工具。

前言

日志文件是系统最重要的数据其一,可用来统计、分析、溯源等操作。但日志的产生一般很快且每条的数据量不一,因此很容易导致日志文件占用过大,日志切割工具此时就展现了其作用,可以切割日志并进行归档。

安装

常见 Linux 发行版都已经内置,无需手动安装,但部分精简系统或定制模板没有,需要自行安装。

RadHat / CentOS / Fedora

# yum -y install logrotate crontabs

小贴士:日志切割功能需要定时任务组件才能正常工作。

在新版本系统上,如 RedHat/Fedora 上

# dnf -y install logrotate crontabs

Debian / Ubuntu

# apt -y install logrotate cron

包内容(以 CentOS7 为例),其他发行版的内容大致相同。

# rpm -ql logrotate
/etc/cron.daily/logrotate               # 每日定时切割
/etc/logrotate.conf                     # 主配置文件
/etc/logrotate.d                        # 配置文件夹
/etc/rwtab.d/logrotate                  # 定义了工作目录
/usr/sbin/logrotate                     # 二进制可执行文件
/usr/share/doc/logrotate-3.8.6          # 文档
/usr/share/doc/logrotate-3.8.6/CHANGES  # 更新说明
/usr/share/doc/logrotate-3.8.6/COPYING  # 版权
/usr/share/man/man5/logrotate.conf.5.gz # 帮助手册
/usr/share/man/man8/logrotate.8.gz      # 帮助手册
/var/lib/logrotate                      # 工作目录
/var/lib/logrotate/logrotate.status     # 工作进度记录

配置

若使用 RPM 或者 Yum 安装过某些软件,例如 NGINX ,则会在 /etc/logrotate.d 下写入 NGINX 的日志切割配置,以此配置为例说明。

/var/log/nginx/*.log {
        daily
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 640 nginx adm
        sharedscripts
        postrotate
                if [ -f /var/run/nginx.pid ]; then
                        kill -USR1 `cat /var/run/nginx.pid`
                fi
        endscript
}

参数说明

参数 说明
daily 轮询周期。日志文件将按{天}轮询,其他可用参数 weekly {周}、 mounthly {月}、 yearly {年}。
missingok 忽略轮询期间的错误,例如日志文件不存在等。
rotate 52 归档周期。最多保留 {52} 个轮询周期 {天} 的日志,过期日志将自动删除。与第一个参数相关。
compress 压缩轮询后的日志。
delaycompress 与上一个参数连用,不压缩最近一个轮询周期的日志。仅压缩之前的日志。
notifempty 日志为空不进行轮询。
create 640 nginx adm 轮询完成后以指定权限、属主、属组创建新日志文件。
sharedscripts 运行 postrotate 脚本,作用是在所有日志都轮询后统一执行一次脚本。如果无此选项,那么每个日志轮转后都会执行一次脚本。
postrotate 脚本开始标记
endscript 脚本结束标记

主配置参数

参数 说明
dateext 使用日期来代替自然数列。
dateformat format_string 与上一参数配合使用,指定日期格式,支持 %Y {年} %m {月} %d {日} %s {秒} 四个参数
size log-size 日志达到指定大小就进行轮询,默认 bytes {字节} 支持 k {千字} M {兆字} G {吉字} 单位。

小贴士:此处仅展示常用参数,更多详细描述请参见 man logrotate

轮询工作日志

# cat /var/lib/logrotate/status 

小贴士:可以看到此文件是记录工作日志的轮询时间,用于进行下一次轮询。

实践

轮询工作流程

查看日志轮询结果

root@vvave:/var/log/nginx# ll
total 100
-rw-r----- 1 nginx adm  6967 Apr  5 16:02 access.log
-rw-r----- 1 nginx adm  5866 Mar 29 06:19 access.log-20190329.gz
-rw-r----- 1 nginx adm  5942 Mar 30 05:41 access.log-20190330.gz
-rw-r----- 1 nginx adm  8662 Mar 31 06:00 access.log-20190331.gz
-rw-r----- 1 nginx adm  3043 Apr  1 06:23 access.log-20190401.gz
-rw-r----- 1 nginx adm  3537 Apr  2 06:18 access.log-20190402.gz
-rw-r----- 1 nginx adm  3414 Apr  3 06:11 access.log-20190403.gz
-rw-r----- 1 nginx adm 10217 Apr  4 06:24 access.log-20190404.gz
-rw-r----- 1 nginx adm 26484 Apr  5 06:21 access.log-20190405
-rw-r----- 1 nginx adm     0 Mar 31 06:25 error.log
-rw-r----- 1 nginx adm    74 Mar 29 14:35 error.log-20190330.gz
-rw-r----- 1 nginx adm   235 Mar 30 19:10 error.log-20190331

可以观察到每日切割的时间点都不同,这是因为 logrotate 程序并不是自动执行工作的,而是与 cron {定时任务} 协同工作的。

cron.daily/ 中可以看到 logrotate 的调用脚本

#!/bin/sh

test -x /usr/sbin/logrotate || exit 0
/usr/sbin/logrotate /etc/logrotate.conf

手动轮询

除了系统调用自动执行外,也可以手动进行轮询。

创建配置文件

cat > /etc/logrotate.d/log-file-test <<'EOF'
/var/log/log-file {
    monthly
    rotate 5
    compress
    delaycompress
    missingok
    notifempty
    create 644 root root
    postrotate
        /usr/bin/killall -HUP rsyslogd
    endscript
}
EOF

创建日志文件

# touch /var/log/log-file && head -c 10M < /dev/urandom > /var/log/log-file 

手动执行

# ll /var/log/log-file 
-rw-r--r-- 1 root root 10485760 Feb  7 18:50 /var/log/log-file
# logrotate -vf /etc/logrotate.d/log-file 
# ll /var/log/log-file* 
-rw-r--r-- 1 root root        0 Feb  7 19:17 /var/log/log-file
-rw-r--r-- 1 root root 10485760 Feb  7 18:50 /var/log/log-file.1

小贴士:可以看到已经将日志文件切割完毕。

附录

关于 NGINX 切割日志配置文件中的

kill -USR1 `cat /var/run/nginx.pid`

参见维基百科
在 POSIX 兼容的平台上,SIGUSR1 和 SIGUSR2 是发送给一个进程的信号,在 NGINX 与 APACHE 中 USER1 信号表示暂停接受连接请求,重载进程,重新写入日志等(实际上就是相当于平滑重启)。

相关链接

参考链接

回复