主题
nginx 日志轮转未重载排查与修复记录
记录日期: 2026-10-19
影响范围: 正式服务器 47.121.197.139 的系统 nginx 访问/错误日志轮转; 不涉及应用服务、数据库、正式流量与蓝绿实例。时间为北京时间(CST)。
1. 事件概述
在排查正式环境用户使用情况时发现:/var/log/nginx/access.log 为 0 字节 (创建于 10/13 00:00),而实际流量持续写入 access.log.1(10/12 15:43 起, 已 4.5MB)。说明日志轮转后 nginx 没有重新打开日志文件,此后每天的轮转被 notifempty 跳过,新的日志将一直堆积在 .1 文件中,不再滚动。
同机还存在第二个独立缺陷:logrotate 每天以 exit 1 结束(重复条目报错), 掩盖了上述 postrotate 失败。
两个问题均已在正式服务器修复并完成端到端验证;开发服务器不受影响。
2. 现象与初步排查
access.log0 字节(10/13 创建),error.log0 字节(10/13 创建)。access.log.14.5MB 且 mtime 持续更新;error.log.1同理。- nginx master(当时 PID 623777)的打开句柄指向
.1文件:/proc/623777/fd/4 -> /var/log/nginx/access.log.1。 /var/lib/logrotate/status中 nginx 两个日志的最近轮转日期停留在2026-10-13,与"轮转后未重开、随后被 notifempty 跳过"一致。
3. 排查证据
轮转配置依赖已丢失的 init 脚本:
bashgrep -A2 postrotate /etc/logrotate.d/nginx # postrotate # invoke-rc.d nginx rotate >/dev/null 2>&1 dpkg --verify nginx nginx-common # missing c /etc/init.d/nginx ← 包文件缺失 invoke-rc.d nginx rotate; echo rc=$? # /usr/sbin/invoke-rc.d: ... No such file or directory # rc=127syslog 保留窗口内(2026-09-23 起)每天 00:00 出现:
logrotate[...]: error: error running shared postrotate script for '/var/log/nginx/*.log '包升级记录与故障时间吻合:
2026-09-15 06:28 upgrade nginx:amd64 1.24.0-2ubuntu7.17 → 7.18 (unattended-upgrades)重复条目(独立缺陷):
logrotate[...]: error: xiedao-dev-dns-watch:1 duplicate log entry for /var/log/nginx/xiedao-dev-dns-watch.log logrotate[...]: error: found error in file xiedao-dev-dns-watch, skipping systemd: logrotate.service: Failed with result 'exit-code'来源:
/etc/logrotate.d/xiedao-dev-dns-watch(2026-09-09 DNS 切换时按仓库Deploy/docker-dev/config/cutover-logrotate.conf安装)与该机/etc/logrotate.d/nginx的/var/log/nginx/*.log通配重复声明同一文件。
4. 根因判断
主因(日志未重载): /etc/logrotate.d/nginx 的 postrotate 调用 invoke-rc.d nginx rotate,它依赖 /etc/init.d/nginx;该脚本已不存在 (dpkg --verify 标记 missing),postrotate 从未成功执行。nginx 收不到 USR1,继续写已改名的旧 inode;create 出来的新 access.log 一直为 0 字节,notifempty 使之后每天的轮转直接跳过。
次要(logrotate.service 每天失败): 重复条目使 logrotate 整体以 exit 1 结束。nginx 条目按文件名顺序(nginx 在 xiedao-dev-dns-watch 之前)仍会被 处理,但整次运行被标记失败,真实错误被掩盖。
易混淆点: systemctl reload nginx 是 HUP(重载配置),不会重开日志; 日志重开必须向 master 发送 USR1(或 nginx -s reopen)。
5. 已执行的正式服务器修复
备份(改动前原文件):
/root/backup-logrotate-20261019-093644/
├── nginx.conf.orig (329B, 2023-12-01)
└── xiedao-dev-dns-watch.orig (219B, 2026-09-09)修改
/etc/logrotate.d/nginx的 postrotate:diffpostrotate - invoke-rc.d nginx rotate >/dev/null 2>&1 + if [ -s /run/nginx.pid ]; then kill -USR1 "$(cat /run/nginx.pid)"; fi endscript删除
/etc/logrotate.d/xiedao-dev-dns-watch。该日志此后由 nginx 通配条目 继续轮转(保留策略由 3 天变为 14 天);该文件自 2026-09-15 起无写入, 属已完成的切换任务遗留。立即向 nginx master 发送
USR1完成重开(不重启、无中断、不丢日志), 随后执行一次真实轮转做端到端验证。
6. 验证结果
- nginx 打开句柄指向
access.log/error.log,不再指向.1文件; 实测请求(GET /200)写入新access.log。 - 真实轮转输出包含
renaming ... access.log to access.log.1、creating new access.log、running postrotate script(无报错),rotate 14的链式滚动与超期删除正常。 - 堆积的 4.5MB 日志压缩为
access.log.2.gz(281KB),无数据丢失。 /var/lib/logrotate/status更新为2026-10-19。- 全局
logrotate -d /etc/logrotate.conf无 error、无 duplicate。 logrotate.timer下次运行:2026-10-20 00:00。
7. 影响范围确认
- 开发服务器
8.134.105.163:宝塔 nginx + 自带/etc/logrotate.d/xiedao-dev-nginx(使用nginx -s reopen),/etc/init.d/nginx存在,logrotate 无失败记录,不受影响。 - 同机 MySQL(每日)、Redis(每周)日志轮转正常。
- 事件期间应用可用性未受影响;日志中 502 均来自扫描器访问不存在的路径, 与本次问题无关。
8. 防复发与后续
仓库
Deploy/docker-dev/config/cutover-logrotate.conf已加注释:目标主机 若已有/var/log/nginx/*.log通配配置,不要安装该重复条目。/etc/logrotate.d/nginx是 dpkg conffile:当前系统 apt 未设置Dpkg::Options,dpkg 默认保留本地版本,后续 nginx 包升级一般不会覆盖。 若升级后复发,按第 3 节证据(dpkg --verify+ syslog 关键字)定位, 并恢复第 5 节的 postrotate。次日复核(应显示
status=0/SUCCESS):bashssh -i ~/.ssh/XieDao.pem root@47.121.197.139 \ 'systemctl status logrotate.service --no-pager | head -5'遗留清理(可选,需另行确认):本机仍保留切换期产物
/etc/nginx/conf.d/xiedao-dev-dns-watch.conf、xiedao-dev-im-forward.log等;切换任务status=complete且 timer 已禁用,相关日志自 9/15 起为空。 确认无引用后可清理 vhost 与日志文件,缩小轮转面。