Nginx日志切割自动归档配置从零开始

为什么要做 Nginx 日志切割与归档

Nginx 默认会把所有访问日志写到同一个文件(如 access.log),时间一长这个文件会变得非常大,不仅占用磁盘,还会拖慢日志查询速度。
通过日志切割自动归档,我们可以按天(或小时)把旧日志切分成小文件并压缩存储,同时让 Nginx 继续写入新文件。
整个过程可以完全自动化,无需人工干预。

配置前的准备

在动手之前,你需要确认以下几点:

  • Nginx 已正确安装,且知道日志存放目录(通常是 /var/log/nginx/)。
  • 服务器系统:本文以 CentOS 7 / Ubuntu 20.04 为例,命令几乎通用。
  • 拥有 root 或 sudo 权限,因为要修改系统计划任务和日志文件。

查看当前日志位置的方法:

# 查看 Nginx 主配置中的日志路径
grep -E 'access_log|error_log' /etc/nginx/nginx.conf

如果 Nginx 配置里没有写绝对路径,默认日志在 /var/log/nginx/ 下。

使用 logrotate 自动切割 Nginx 日志

系统自带的 logrotate 工具是完成这项工作的首选,配置简单且稳定。

第一步:创建 logrotate 配置文件

/etc/logrotate.d/ 目录下新建一个名为 nginx 的文件:

sudo vim /etc/logrotate.d/nginx

粘贴以下内容(请根据你的实际日志路径和需求调整):

/var/log/nginx/*.log {
    daily                    # 每天轮转一次
    missingok                # 如果日志文件丢失则跳过,不报错
    rotate 30                # 保留最近 30 个归档文件
    compress                 # 压缩归档文件(gzip)
    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
}

关键说明

  • create 的属主和属组要与你的 Nginx 工作进程一致。如果 Nginx 以 nginx 用户运行,改为 create 0640 nginx adm
  • postrotate 里的 kill -USR1 是平滑通知 Nginx 重新打开日志文件,不会中断服务。

第二步:测试配置并手动执行一次

# 测试配置语法
debug logrotate -d /etc/logrotate.d/nginx

# 强制立即执行一次轮转(不等待定时任务)
sudo logrotate -f /etc/logrotate.d/nginx

如果输出没有报错,检查 /var/log/nginx/ 目录,你应该能看到类似 access.log-20250410.gz 的归档文件。

第三步:确认定时任务已启用

logrotate 默认由 cron 每天执行一次,一般配置在 /etc/cron.daily/logrotate 里。
你可以手动运行这个脚本或者直接检查:

ls -l /etc/cron.daily/logrotate

如果需要按小时切割,可以使用 hourly 并放入 /etc/cron.hourly/ 目录,但日常使用 daily 已足够。

手动切割脚本(备选方案)

如果 logrotate 不满足你的定制需求,也可以自己写一个 Shell 脚本配合 crontab:

#!/bin/bash
# /usr/local/bin/nginx-logrotate.sh
LOG_DIR="/var/log/nginx"
YESTERDAY=$(date -d "yesterday" +"%Y%m%d")

cd $LOG_DIR
for log in *.log; do
    [ -f "$log" ] || continue
    mv "$log" "${log}.${YESTERDAY}"
done

gzip *.log.* 2>/dev/null
kill -USR1 $(cat /var/run/nginx.pid)

赋予执行权限,并添加 crontab:

chmod +x /usr/local/bin/nginx-logrotate.sh
crontab -e
# 每天凌晨 0 点执行
0 0 * * * /usr/local/bin/nginx-logrotate.sh

效果验证与常见问题

验证步骤

  1. 执行轮转后,访问站点生成一些日志。
  2. 查看日志目录:ls -lh /var/log/nginx/,确认有新生成的 access.log 和打包的旧文件。
  3. 检查 Nginx 是否正常:curl -I http://localhost 或查看 error.log 有无异常。

高频问题

Q:轮转后 Nginx 还在往旧文件写日志?

A:通常是因为 postrotate 中的 kill -USR1 没有生效。
检查 Nginx PID 文件路径是否正确,或者手动执行 sudo nginx -s reopen 替代。

Q:新日志文件属主错误导致无法写入?

A:确认 create 指令中的用户和组与 Nginx 运行用户一致。
可以用 ps aux | grep nginx 查看 worker 进程的用户。

Q:日志文件没有压缩?

A:检查 compressdelaycompress 是否同时使用。
如果 delaycompress 开启,上一轮的文件会在下一轮才压缩,属于正常行为。

避坑要点

  • 不要手动删除日志文件,使用 logrotate 自动管理,避免 Nginx 句柄失效。
  • 日志目录磁盘空间监控:建议配合 df -h 或告警工具,防止日志暴增撑爆磁盘。
  • 配置修改后先 debug 测试,避免生产环境直接跑出问题。

总结

通过 logrotate 或脚本 + crontab,你可以轻松实现 Nginx 日志切割自动归档
推荐优先使用 logrotate,因为它更成熟、配置声明式,且与系统日志管理无缝集成。
按照本文步骤,从准备到验证,一个小时内就能搞定。
后续遇到异常时,优先检查 postrotate 执行状态和文件权限,大部分问题都能快速定位。

分享到:
上一篇
容器资源限制防止恶意抢占:Docker容器资源限制防恶意抢占
下一篇
MySQL慢日志分析优化数据库实战教程:从开启到调优
1
系统公告

高考专属福利来袭|凭准考证免费领香港 CN2 云服务器

值高考落幕之际,泽御云开启考生专属回馈 + 产品限时特惠双重活动,助力学子暑期学习建站 高考 考生专属福利 全体应届高考生,凭高考准考证即可免费申领【香港 CN2 轻量云服务器,4 核 4G AMD 处理器】,免费使用周期 30 天,可用于搭建个人站点、编程实操、技术实训,祝各位考生金榜题名,前程似锦! 泽御云资质齐全合规自营机房,线路覆盖香港 CN2、国内 BGP、内蒙电信、美国精品线路,售后全天候技术支持。 官方网站:www.zeyuyun.com,活动限时有效,优惠逾期不再保留。
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意