nginx 日志轮转与切割实战:服务器日志管理部署

跑了一段时间的 Nginx 站点,磁盘空间经常莫名减少,很多人第一反应是查代码或删备份,其实真正在悄悄吃满磁盘的往往是不断增长的 access.log 和 error.log。这篇指南教你用 logrotate(Linux 自带的日志轮转工具,负责定期切割、压缩并清理旧日志)对 Nginx 日志做轮转与切割,让日志按天归档、自动压缩、超过保留期限自动删除,服务器不再因为日志失控而报警。日志管理看似不起眼,却是服务器稳定运行里最容易被忽视的一环,下面从日志结构讲起,帮助你一次把轮转策略落地。

nginx 日志轮转与切割实战封面图

Nginx 日志结构与为什么需要切割

Nginx 默认把访问日志写到 access.log,把错误日志写到 error.log。access.log 记录每一次客户端请求,包括访问者 IP、请求路径、状态码、响应大小和耗时;error.log 记录 Nginx 运行过程中的异常,比如 404 资源缺失、上游超时、SSL(Secure Sockets Layer,安全套接层,用于加密客户端与服务器之间通信的协议)握手失败等。两者职责不同,排查问题时的价值也不一样。

如果不做任何处理,access.log 会一直追加写。一个日均访问量在几万次的站点,access.log 每天可能增长几十 MB 到上百 MB,一个月就是几个 GB。日志文件越大,除了占用磁盘,还会带来两个麻烦:一是定位问题时用编辑器打开大文件非常卡;二是 Nginx 在写日志时如果磁盘已满,可能会影响正常响应。所以日志必须定期切割——把当前日志文件按周期归档成带时间戳的文件,再让 Nginx 重新打开一个新的日志文件继续写。

以一份典型的 access.log 为例,日志单行格式大致如下:

 # 一行访问日志:IP - 用户 - 时间 - 请求 - 状态码 - 响应字节
127.0.0.1 - - [26/Aug/2026:10:15:30 +0800] "GET /index.html HTTP/1.1" 200 5120

上面的字段依次是客户端 IP、时间、请求行、HTTP 状态码和响应字节数。示例中的 IP 与时间为占位数据,实际以你的日志为准。当这类日志持续累积,就到了需要轮转的时候。

logrotate 基础配置:按天切割

logrotate 配置规则驱动日志切割示意图

logrotate 是绝大多数 Linux 发行版自带的服务,配置放在 /etc/logrotate.conf 以及 /etc/logrotate.d/ 目录下。我们可以在 /etc/logrotate.d/nginx 新建一个针对 Nginx 日志的轮转规则:

 # Nginx 日志轮转规则:每天切割一次,保留 30 天
/var/log/nginx/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    sharedscripts
    postrotate
        nginx -s reopen 2>/dev/null || true
    endscript
}

这段规则的含义逐条解释:daily 表示每天切割一次,rotate 30 表示保留最近 30 份归档,compress 表示用 gzip 压缩旧日志,delaycompress 表示延迟到下一次轮转再压缩(避免压缩正在被 Nginx 写入的当前文件),missingok 表示文件不存在时不报错,notifempty 表示空日志不轮转,sharedscripts 配合 postrotate 在切割完成后统一执行一次 Nginx 日志重开命令。

nginx -s reopen 是 Nginx 提供的信号命令,作用是让 Nginx 重新打开日志文件描述符。因为 Nginx 一直持有旧文件的写句柄,如果只把文件改名而不重开句柄,Nginx 会继续往已经归档的旧文件里写,日志就”切不断”了。这一步是整个轮转能否生效的关键。

按大小切割与触发方式

有些站点的日志流量波动大,按天切割不够及时,更希望日志长到一定大小就自动切割。logrotate 用 size 指令来满足这种需求,它可以和周期指令一起使用,满足任意一个条件就触发:

 # 按大小切割:日志超过 100M 就轮转,同时每天最多检查一次
/var/log/nginx/*.log {
    daily
    size 100M
    rotate 14
    compress
    missingok
    notifempty
    sharedscripts
    postrotate
        nginx -s reopen 2>/dev/null || true
    endscript
}

size 100M 表示当日志文件超过 100MB 时,即使还没到每天的执行点也会触发轮转。这里的 100M 是一个典型区间,你可以根据磁盘空间和日志增长速度调整成 50M 或 200M。

需要提醒的是,logrotate 本身是一个由 cron 定时触发的任务,默认每天执行一次。也就是说,size 的判断是在每天那次 cron 运行时进行的,而不是实时的。如果你的站点日志增长极快,希望更频繁的检查,可以把 logrotate 的执行周期从 daily 改成 hourly,或在 crontab 里手动安排执行时间。示例中数值均为占位,请按实际流量调整。

压缩与保留策略

归档日志建议启用压缩,文本日志的压缩率通常非常高。一个 500MB 的 access.log 用 gzip 压缩后往往只剩 30 到 50MB,能节省大量磁盘。这也是上面配置里 compress 的意义。如果希望压缩后更省空间,可以设置 compresscmd 为 bzip2 或 xz,但要注意解压速度会变慢,一般 gzip 就够用。

保留策略要结合业务对日志的审计需求来决定。常见做法是保留 14 到 30 天,满足日常排障和访问量统计即可。如果站点有合规要求需要留更久,可以把 rotate 调大,但要同步评估磁盘空间。一个简单评估方法:先看当前 access.log 一天增长多少,乘以保留天数,再加上压缩收益,就是日志占用的预估空间。

下面用一个脚本快速统计当前日志的增长情况,帮助你估算需要预留多少磁盘:

 # 查看最近 24 小时内 access.log 增长了多少(示例,按实际路径调整)
ls -lh /var/log/nginx/access.log
 # 用 du 查看日志目录总占用
du -sh /var/log/nginx/

示例中,如果 access.log 显示为 200M 而目录总共 1.2G,说明归档累积明显,需要检查轮转是否真的生效。如果磁盘持续紧张,可以参考 Redis 持久化与恢复,把日志存储与缓存数据分开规划,避免相互挤占。

验证轮转是否生效

日志轮转验证与检查流程示意图

配置写好后不能只看配置内容,要实际验证轮转是否按预期工作。logrotate 提供了试运行模式,不会真正改文件,只打印将要执行的操作:

 # 试运行:只预览将要执行的轮转动作,不实际切割
logrotate -d /etc/logrotate.d/nginx
 # 强制运行一次:立即切割并归档,忽略周期判断
logrotate -f /etc/logrotate.d/nginx

-d 是 debug 模式,-f 是 force 强制模式。验证时先跑 -d 确认规则解析正确,再跑一次 -f 看实际的切割结果。强制运行后到日志目录确认是否生成了带日期后缀的归档文件,以及 Nginx 是否重新打开了新的 access.log:

 # 列出日志目录,查看归档文件与当前日志(示例路径)
ls -lh /var/log/nginx/
 # 确认 Nginx 进程持有的是新日志句柄
head -1 /var/log/nginx/access.log

示例中,如果目录里出现类似 access.log-20260826.gz 的压缩归档,同时新的 access.log 只有少量新写入,说明轮转正常。如果归档文件没有按预期生成,多半是路径写错、postrotate 命令失败,或 cron 没有运行 logrotate。

如果日志排查时还想同时掌握站点整体访问与性能趋势,可以借助可视化监控把日志里的关键指标长期沉淀下来,Grafana 服务器部署实践 提供了一套完整的监控方案,能帮你把日志与性能数据统一看板。

常见问题与避坑

日志轮转的坑大多集中在”切了但没完全切”这一类,整理几个高频问题:

  • 归档后日志仍在增长:几乎都是 postrotate 里的 nginx -s reopen 没生效,确认 Nginx 主进程名与命令路径正确
  • 磁盘依然吃紧:检查 compress 是否开启,以及 rotate 保留天数是否过多
  • 轮转把 error.log 漏掉:确认配置里的通配符 *.log 覆盖了 error.log,或单独为它写规则
  • 日志权限被改:切割后如果新日志文件属主变了,Nginx 可能无法写入,注意 create 指令保证属主为 nginx
  • 定时任务没跑:确认 crontab 或 systemd timer 里 logrotate 是否被禁用

如果你的服务器还同时用 Nginx 做限流和反代,日志里大量 429 或 503 往往来自限流规则,排查时可结合 Nginx 请求限流配置 一起分析,避免把限流误判成日志系统故障。

总结

Nginx 日志轮转与切割是服务器日志管理的核心环节,配置简单但收益直接:日志按天归档、自动压缩、到期删除,磁盘空间可预测,排障时也不用面对几个 GB 的大文件。落地的步骤很清晰:在 /etc/logrotate.d/nginx 写好轮转规则,用 logrotate -d 试运行检查语法,再用 logrotate -f 强制跑一次验证切割结果,最后确认 nginx -s reopen 让新日志生效。记住按天和按大小两种触发方式、合理设置保留天数与压缩、定期检查定时任务是否存活,就能让日志管理长期稳定。如果你需要一台磁盘配置灵活、性能稳定的海外服务器来承载高并发日志写入,Hostease 的 VPS(Virtual Private Server,虚拟专用服务器,通过虚拟化技术划分出的独立服务器环境)与独立服务器方案都能满足需求,但日志轮转策略仍建议按本文清单结合自身流量调整。

日志只是运维的一环,把日志、限流、数据库和证书一起纳入巡检,才能让站点更稳定。比如数据库侧的慢查询也会影响整体体验,可参考 MySQL 慢查询分析与优化,或结合 Certbot 证书续期排障 把 TLS 稳定性一并纳入日常检查。

发表评论