排查Nginx日志写入失败需先区分“写不进去”与“根本没尝试写”:确认error_log/access_log真实路径,检查目录存在性、Nginx工作用户(如nginx或www-data)对各级路径的x/w权限,用df -h和df -i查磁盘块与Inode是否耗尽,通过nginx -e stderr、strace或ausearch定位系统层错误,并验证logrotate及USR1重载机制是否生效。

排查 Nginx 日志磁盘写入失败,核心是区分“写不进去”和“根本没尝试写”——前者通常有错误日志可查,后者往往静默卡住,需从系统层切入。
先确认日志是否真在写、写到哪了
别默认看 /var/log/nginx/error.log。打开 nginx.conf,找 error_log 和 access_log 指令,确认实际路径。常见误区是配置写了 /data/logs/nginx/error.log,但目录不存在或权限不对,Nginx 启动时连日志模块都初始化失败,自然无日志可查。
快速验证方法:
- 运行
ps aux | grep nginx,看 worker 进程用的是哪个用户(如nginx或www-data) - 检查该用户对日志路径的父目录是否有写权限:
ls -ld /data/logs/nginx/,确保属主或属组匹配且有w权限 - 若路径含多级目录(如
/data/logs/nginx/a/b),每一级都要存在且可进入(x权限)
检查磁盘空间与 Inode 是否耗尽
磁盘块(block)或 Inode 耗尽都会导致写入失败,但表现不同:
-
df -h:看日志所在分区的Use%是否为 100%,Avail是否为 0 -
df -i:重点看IUse%,达 100% 表示无法新建文件(常见于 logrotate 生成大量.log.1、.log.2.gz后未清理) - 用
lsof +L1 | grep nginx查是否有已删除但进程仍占用的“deleted”日志文件——这是典型删了日志却没释放空间的信号
抓取实时写入行为与失败原因
日志静默时,error.log 可能为空。这时要绕过日志本身,直接看系统反馈:
- 强制终端输出启动错误:
nginx -c /etc/nginx/nginx.conf -e stderr,可捕获模块加载失败、路径不可写等早期错误 - 跟踪 worker 进程写操作:
strace -p $(pgrep -f "nginx: worker") -e trace=write,openat,fsync -s 256 2>&1 | grep -E "(log|denied|No space)",直接看到 write 系统调用返回-1 ENOSPC(空间满)或-1 EACCES(权限拒绝) - 查 SELinux/AppArmor 干预:
ausearch -m avc -ts recent | grep nginx(CentOS/RHEL)或aa-status | grep nginx(Ubuntu)
验证并修复日志机制本身
即使磁盘和权限正常,日志也可能因配置不当而失效:
- 检查
access_log是否启用了缓冲:access_log /path/to/access.log main buffer=64k flush=5s;;若缺失buffer或设flush=0,高并发下易触发 I/O 尖峰甚至阻塞 - 确认 logrotate 配置是否生效:
logrotate -d /etc/logrotate.d/nginx(调试模式),看是否报路径不存在或权限不足 - 手动触发日志 reopen:
kill -USR1 $(cat /var/run/nginx.pid),再立刻tail -f观察是否开始写新内容,验证句柄是否恢复


















