Skip to main content

Nginx 日志分割方案

Nginx 默认不会自动分割日志文件,随着时间推移日志文件会变得非常大,影响系统性能和管理。以下是几种常用的 Nginx 日志分割方法:

1. 使用 logrotate (推荐)

logrotate 是 Linux 系统自带的日志管理工具,非常适合用于 Nginx 日志分割。

配置步骤

  1. 创建 logrotate 配置文件 (通常放在 /etc/logrotate.d/nginx)
sudo nano /etc/logrotate.d/nginx
  1. 添加以下内容:
/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}

参数说明

  • daily: 每天轮转
  • missingok: 如果日志文件不存在也不报错
  • rotate 14: 保留14个旧日志文件
  • compress: 使用 gzip 压缩旧日志
  • delaycompress: 延迟压缩前一个日志文件
  • notifempty: 如果日志为空则不轮转
  • create 0640 www-data adm: 创建新日志文件的权限和所有者
  • sharedscripts: 所有日志处理完后才运行 postrotate 脚本
  • postrotate: 通知 Nginx 重新打开日志文件
  1. 测试配置是否正确
sudo logrotate -d /etc/logrotate.d/nginx
  1. 手动运行 logrotate
sudo logrotate -f /etc/logrotate.d/nginx

2. 使用 cron 脚本手动分割

  1. 创建日志分割脚本 /usr/local/bin/nginx_logrotate.sh:
#!/bin/bash
# Nginx 日志目录
LOGS_PATH=/var/log/nginx
# 获取昨天日期
YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)
# 重命名日志文件
mv ${LOGS_PATH}/access.log ${LOGS_PATH}/access_${YESTERDAY}.log
mv ${LOGS_PATH}/error.log ${LOGS_PATH}/error_${YESTERDAY}.log
# 向 Nginx 主进程发送 USR1 信号,重新打开日志文件
kill -USR1 $(cat /var/run/nginx.pid)
  1. 给脚本执行权限
chmod +x /usr/local/bin/nginx_logrotate.sh
  1. 设置 cron 任务每天执行
crontab -e

添加以下内容(每天午夜执行):

0 0 * * * /usr/local/bin/nginx_logrotate.sh

3. 使用系统自带的时间戳日志 (Nginx 1.19.6+)

Nginx 1.19.6 及以上版本支持在日志文件名中使用变量:

http {
    log_format custom '$remote_addr - $remote_user [$time_local] '
                      '"$request" $status $body_bytes_sent '
                      '"$http_referer" "$http_user_agent"';
    
    access_log /var/log/nginx/access-${year}${month}${day}.log custom;
}

然后使用 map 指令定义时间变量:

map $time_iso8601 $year {
    default '0000';
    '~^(?<yyyy>\d{4})-' $yyyy;
}

map $time_iso8601 $month {
    default '00';
    '~^\d{4}-(?<mm>\d{2})-' $mm;
}

map $time_iso8601 $day {
    default '00';
    '~^\d{4}-\d{2}-(?<dd>\d{2})' $dd;
}

日志分割后的管理

  1. 删除旧日志:定期清理过期的日志文件
  2. 日志分析:使用工具如 GoAccess、AWStats 分析分割后的日志
  3. 日志备份:重要的日志文件可以备份到远程存储

注意事项

  1. 确保 Nginx 进程有权限写入新的日志文件
  2. 分割日志时确保磁盘空间充足
  3. 生产环境建议使用 logrotate 方案,它更可靠且功能完善
  4. 对于高流量网站,可以考虑按小时分割日志

以上方法可以根据实际需求选择或组合使用,logrotate 通常是大多数 Linux 发行版的首选方案。