记录 Nginx 日志因为 Logrotate 失效而爆盘
TLDR: 更新后发现 Nginx 写入 access.log.1 而 Logrotate 逻辑只覆盖 /var/log/nginx/*.log 导致轮转失效。
Warning:
本篇文章不完整,仅记录,无验证、诊断
本篇记录于 2026-05-21 更新,之前推断已废弃,事实性描述保留作为参考
将 cron 执行 logrotate 的频率降低到半小时一次后(之前为五分钟),不再出现写入 access.log.1,同时 journalctl -u logrotate 也没有报错了(之前观察到会和写入 access.log.1 同时出现 logrotate 的报错,但没有存留日志,但时间上应该一致)
后续 3 天再未触发,也许是过于频繁的 logrotate 导致,并非 Nginx 更新。
此外重新安装后发现官方的 Logrotate 配置和我之前不知道从哪抄来/旧版本的配置不同,如下
1 | ❯ cat /etc/logrotate.d/nginx.dpkg-dist |
其中直接 kill -USR1 `cat /run/nginx.pid` ,而不是 invoke-rc.d nginx rotate,也可能是不再出错的变量之一。
仍未为
*\.log\.[0-9]+$的情况做处理…先观望 😐
以下推断内容已废弃,事实性描述保留作为参考
最近由于 Nginx CVE-2026-42945 (NGINX Rift) 的影响,需要更新 Nginx,然后触发了一个奇怪的 corner case,导致日志挤满硬盘,在此记录推测的原因。
前言:周四执行了 apt update && apt install --only-upgrade nginx 来更新 Nginx,更新完成后确认了 nginx -v 显示的版本号确实更新了,之后就没处理了。
表现在于每几十个小时之后就会因为 /var/log/nginx 目录占用过大而挤满硬盘,MongoDB Down 了。但第一次触发我没仔细看,发现 /var/log/nginx/access.log.1 和 /var/log/nginx/error.log.1 占了十多G,直接 echo "" > /var/log/nginx/access.log.1 和 echo "" > /var/log/nginx/error.log.1 就恢复了。
其实我此时就该发现的,为什么是
*.log.1而不是*.log
第二次是周日早上 8 点,一看报警 524,再看怎么又满了,先紧急清理了,一顿捣鼓(检查 /etc/logrotate.d/nginx 配置、检查 crontab -l)后注意到 /var/log/nginx/access.log 和 /var/log/nginx/error.log 都是 0 字节的空文件,而 *.log.1 却占了十多G,意识到可能是更新导致的。(但此时还怀疑过是新版本的轮转日志覆盖了我之前的日志,还是不够敏锐=-=)
遂试着 systemctl restart nginx,然后 access.log 和 error.log 终于开始正常记录了。
参考 Logrotate 的配置文件:
1 | z0z0r4@z0z0r41:~$ cat /etc/logrotate.d/nginx |
肯定是 postrotate 失败了,但是到底是不是因为更新导致的失败,我试了下没法复现=-=
这是 Nginx 的包更新时的脚本:
1 | z0z0r4@z0z0r41:~$ cat /var/lib/dpkg/info/nginx.prerm |
里面更新后会调用 invoke-rc.d nginx upgrade。
这是 /etc/init.d/nginx:
1 | z0z0r4@z0z0r41:~$ cat /etc/init.d/nginx |
里面 rotate 函数是通过向 Nginx 发送 USR1 信号来让它重新打开日志文件的,但是都是静默发生,一直返回 0 的,如果失败了确实无法得知。
肯定是 rotate 失败了,但我没法复现出来,在此记录,下次遇到再跟踪下=-=。
说些什么吧!