在Coreos中如何通过logrotate切割Nginx日志

因为coreos系统不建议用户自己安装二进制工具,因此在其他系统中可以使用的文件切割方案在coreos中都无法通过。 但coreos自带logrotate,因此使用logrotate则不失为一个很不错的方案。

前提条件

  • nginx 日志目录(/hdd1/nginx/log)

创建Logrotate 目录

因为后续准备将切割后的nginx文件存入HDFS,所以需要准备一个目录专门来保存logrotate 切割后的文件。

mkdir /hdd1/logs  

创建logrotate 配置文件

编辑 /hdd1/logrotate/logrotate.conf

/hdd1/nginx/log/error.log {
    olddir /hdd1/log
    rotate 1
    nocopytruncate
    sharedscripts
    size 0
    postrotate
            day=$(date +%Y-%m-%d-%H-%M-%S)
            mv /hdd1/log/error.log.1 /hdd1/logs/error.log.$day
        endscript
}
# /hdd1/nginx/log/error.log 指定nginx 日志文件名称. 本案例中,所有日志都输出到error.log,因此这里是error.log。
# olddir /hdd1/log 设定临时转储目录,因为后续会使用Flume发送文件,为了唯一标示文件,所以首先落地到临时转储目录,然后再添加日期作为后缀。
# rotate 1 只保留一份文件
# postrotate
#    day=$(date +%Y-%m-%d-%H-%M-%S)
#    mv /hdd1/log/error.log.1 /hdd1/logs/error.log.$day
# endscript
落地到临时转储目录之后,在文件后面添加日期,作为唯一标示。同时Flume可以根据此后缀判断出是否已经处理。

# nocopytruncate 如果源程序不是通过O_APPEND的方式打开的,那么建议使用copytruncate,但理论上会存在丢数据的风险

####################################
#copytruncate 用于还在打开中的日志文件,把当前日志备份并截断
#nocopytruncate 备份日志文件但是不截断
####################################

创建logrotate.service

在coreos系统中,推荐使用systemd来管理和配置服务。因此编辑/etc/systemd/system/logrotate.service

[Unit]
Description=Hourly excute logrotate for truncate nginx logs  
[Service]

TimeoutStartSec=0

ExecStart=/sbin/logrotate /hdd1/logrotate/logrotate.conf

[Install]

WantedBy=multi-user.targeti  

创建logrotate.timer

通过系统内置的定时器,定时执行logrotate.service。 编辑/etc/systemd/system/logrotate.timer

[Unit]
Description=Hourly excute logrotate for truncate nginx logs

[Timer]
# 在每个半点执行对应服务
OnCalendar=*-*-* *:30:00

[Install]
WantedBy=multi-user.target  

启动定时器

systemctl enable logrotate.timer

# 验证定时器是否启动成功
systemctl list-timers  

验证日志切割是否成功

当第一次启动定时器之后,对应的logrotate.service就会启动。 因此查看/hdd1/logs是否已经存在文件。如果已经有文件存在,则说明logrotate配置成功。 如果没有文件,通过执行:

journalctl -fu logrotate.service  

排查错误。