排查问题时开着 tail -f /var/log/nginx/access.log,零点切割之后终端再也不输出新行,文件被 rename 成了 .gz 之外的轮转名,tail 还停在旧 inode 上。
原因不止一个,得分开看。tail -f 跟着 inode 走,文件被 rename 后仍然指向旧句柄;logrotate 用的是 rename 加 create,不是 copytruncate;终端里的 tail 没有加 -F 参数,不会重新打开路径;切割脚本没有给应用发 reopen 信号,新文件一直是空的。
先确认自己跟的是哪个 inode
ls -li /var/log/nginx/access.log && lsof -p $(pgrep -n nginx) | grep access.log
再往下改用 -F 跟随文件名重新打开
tail -F /var/log/nginx/access.log
临时跟轮转后的旧文件
tail -f /var/log/nginx/access.log-20240101
等前面都确认过,再确认切割后新文件有写入
logrotate -f /etc/logrotate.d/nginx && sleep 2 && wc -l /var/log/nginx/access.log
报错是间歇性的,我蹲守了半小时才抓到一次完整现场。
白天有业务在跑,能验证的部分都压到了晚上做。
改完先别撤,确认这几项。tail -F 在切割后能继续输出新内容,新文件的行数持续增长,旧文件保留到压缩完成。
补一句。tail -f 跟 inode,tail -F 跟文件名,排查线上日志一律用 -F;用 copytruncate 虽然能保住句柄,但会丢一小段日志。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
