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 方式打开文件。