logrotate
Table of Contents
1. logrotate 简介
logrotate
是日志分割工具。使用 logrotate
,日志文件都可被设置成每日,每周或每月轮转,也能在文件太大时立即轮转。
logrotate
支持的命令行参数如下:
$ logrotate --help Usage: logrotate [OPTION...] <configfile> -d, --debug Don't do anything, just test (implies -v) -f, --force Force file rotation -m, --mail=command Command to send mail (instead of `/bin/mail') -s, --state=statefile Path of state file -v, --verbose Display messages during rotation -l, --log=STRING Log file --version Display version information Help options: -?, --help Show this help message --usage Display brief usage message
一般地, logrotate
使用 cron
来运行,其 cron
配置文件一般为:
$ cat /etc/cron.daily/logrotate #!/bin/sh /usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf EXITVALUE=$? if [ $EXITVALUE != 0 ]; then /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]" fi exit 0
2. logrotate 用法
2.1. logrotate 配置文件实例
logrotate
的配置文件位于 /etc/logrotate.conf,这个配置文件会加载目录 /etc/logrotate.d 中的所有配置文件。
下面以 Nginx 的 logrotate
配置文件为例来进行介绍。
安装 Nginx 后,默认有下面配置文件:
$ cat /etc/logrotate.d/nginx /var/log/nginx/*log { daily # 每天轮转 rotate 14 # 保留14个备份 dateext # 设置备份文件以当前日期为结尾,如xxx.log-20131216,否则是xxx.log-1这种格式 missingok # 如果 /var/log/nginx/*log匹配不到文件的话也不报错,直接跳过 notifempty # 当日志文件为空时,不进行轮转 create 0644 nginx adm # 指定创建的新日志文件的 mode owner group;如果设置了copytruncate,则忽略create compress # 备份时启用压缩,默认使用 sharedscripts # 备份完所有日志文件后,再执行下面脚本。默认是,每处理一个日志文件就执行一次脚本 # postrotate指令用于指定在logrotate转储之后需要执行的指令,以endscript结束 postrotate /bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true endscript }
默认,轮转备份的日志文件和当前日志文件在同一个目录中。下面是 nginx 运行一段时间后,/var/log/nginx 目录的文件列表:
$ sudo ls /var/log/nginx/ access.log error.log access.log-20180429.gz error.log-20180429.gz access.log-20180430.gz error.log-20180430.gz access.log-20180501.gz error.log-20180501.gz access.log-20180502.gz error.log-20180502.gz
2.2. 立刻执行日志轮转
当你等不及 cron
调度 logrotate
,可以通过 -f
或 --force
选项来立刻执行日志轮转:
$ sudo logrotate --force /etc/logrotate.d/your-cfg # 没到时间就强制执行
2.3. 调试 logrotate
使用 -d
或 --debug
选项仅输出执行的详细情况,而不会真正执行命令,以方便调试:
$ sudo logrotate --debug --force /etc/logrotate.d/your-cfg # 不会真正执行
2.4. 应用程序重新打开日志文件
日志文件被轮转后,需要告诉应用程序重新打开日志文件。下面介绍两种方法。
2.4.1. 应用程序自己提供的功能(推荐)
在 postrotate
指令中使用应用程序自己提供的功能,如节 2.1 中就是采用的这种方法。
有些应用程序提供了重新打开日志文件的功能。比如 Nginx,支持使用 USR1 信号来通知 Nginx 重新打开日志文件的;又如,MySQL 可以通过 flush-logs 来重新打开日志文件的。
不过,有很多应用程序没有重新打开日志文件的功能,所以方法一不是万能的。
2.4.2. copytruncate
logrotate
提供的 copytruncate
指令采用的是先拷贝再清空的方式,整个过程中日志文件的操作句柄没有发生改变,所以不需要通知应用程序重新打开日志文件。
下面是使用 copytruncate
的实例:
/home/www/*.log { missingok nocreate daily dateext compress copytruncate # 先拷贝再清空,不会改变文件句柄 rotate 10 }
说明 1:在拷贝和清空之间有一个时间差,所以可能会丢失应用程序的部分日志。
说明 2:如果应用程序写日志文件时,没有用 O_APPEND 方式,会导致文件空洞。这是因为没有采用 O_APPEND 方式的话,当日志文件被清空后,应用程序会接着之前日志文件的偏移位置输出,这个位置之前会被 \0
填充,从而导致空洞。不过,这一点也不用太担心,因为应用程序写日志时一般都会采用 O_APPEND 方式打开文件。