由于 nginx 默认的日志文件 access.log 和 error.log
随着使用时间的增长会导致文件大小越来越大,甚至用一些编辑器打开都会直接卡死。想着要是能和程序日志一样能够自动切割、归档该多好。于是在网上搜索一番后,决定采用
linux 自带的 logrotate 和 crontab 来实现这个功能。

本文操作服务器版本:CentOS Linux release 7.6.1810 (Core)

一、 安装 logrotate

查看本机是否已安装 logrotate

which logrotate

如果未安装:

  • 在基于 Debian 的系统上,可以运行:
    sudo apt-get install logrotate
    
  • 在基于Red Hat的系统上,可以运行:
    sudo yum install logrotate
    

二、新建 logrotate 配置文件

安装好后应该会有一个 /etc/logrotate.d 目录,cd 到该目录下,新建一个关于 nginx 日志切割规则的配置文件:

cd /etc/logrotate.d

vim nginx_log_rotate

在新建的文件中输入以下内容:

/usr/local/env/nginx/nginx-1.22.1/logs/*.log {
    daily
    dateext
    minsize 10M
    missingok
    rotate 365
    compress
    delaycompress
    create 0640 root root
    sharedscripts
    postrotate
        /bin/kill -USR1 $(cat /usr/local/env/nginx/nginx-1.22.1/logs/nginx.pid 2>/dev/null) 2>/dev/null || true
    endscript
}

其中,部分常用参数表示的含义:

  • daily:表示每天切割一次日志,还支持 weekly(每周)、monthly(每月)
  • dateext:加上日期作为扩展名。
  • minsize 10M:文件大小达到 10M 才会进行切割。
  • missingok:如果日志文件不存在,不报错。
  • rotate 365:保留最近的 365 个日志文件。
  • compress:压缩旧的日志文件(默认使用 gzip)。
  • delaycompress:压缩的日志文件延迟压缩,以允许 Nginx 重新启动。
  • notifempty:如果日志文件为空,不切割(不推荐)。
  • create:创建新的日志文件时设置文件权限和所有者。
  • sharedscripts:在所有日志文件切割之后执行一次 postrotate 脚本。
  • postrotate:在切割后,需要执行的 shell 脚本,这里是发送 USR1 信号给 Nginx 以重新打开日志文件,以避免日志丢失。

更多更详细的配置可参考:日志 logrotate

三、配置定时任务

打开 crontab 文件:

vim /etc/crontab

写入以下命令:

# 每天 23:59 执行日志轮换操作,不选择 0 点是因为这时候日期已经跨天了,logrotate 归档时的日期就变成第二天了,这样归档出来的日期是不对的。
#  >/dev/null 2>&1 表示输出的信息不显示。
# -f 表示强制切割文件,即使日志文件的大小还不满足配置的最小值也会被切割
59 23 * * * root /usr/sbin/logrotate -f /etc/logrotate.d/nginx_log_rotate > /dev/null 2>&1

然后重启 crontab 即可:

systemctl restart crond