Nginx access_log写不进去是因worker进程无路径权限,静默丢弃日志且不报错;需确认实际日志路径、逐级检查x/w权限、排查磁盘/Inode耗尽、用strace或ausearch定位系统级拒绝原因,并启用buffer+flush或syslog队列加固。

Linux 上 Nginx access_log 写不进去,不是配置没生效,而是 worker 进程压根没权限往那个路径里写——它静默丢弃日志,不报错、不重试、也不记录到 error.log,所以你查日志可能发现“什么都没写”,但 error.log 也空空如也。
看错误日志确认是否真在写
别默认相信 /var/log/nginx/access.log 是目标路径。先打开 nginx.conf,找到 access_log 指令,确认实际路径(比如是 /data/logs/nginx/access.log)。再检查这个路径是否存在、父目录是否完整:
- 运行
ps aux | grep "nginx: worker"查出 worker 使用的用户(常见为nginx或www-data) - 对路径逐级执行
ls -ld /data /data/logs /data/logs/nginx,确保每一级都有该用户的 x(进入)权限,最后一级目录还要有 w(写入)权限 - 如果某一级是
drwxr-x--- 1 root root,而 worker 是nginx用户,那它连/data/logs都进不去,自然写不了
查磁盘与 Inode 是否卡死
空间满或 Inode 耗尽,系统会直接拒绝 write() 系统调用,Nginx 就静默跳过:
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
-
df -h:看 access_log 所在分区的Use%是否 100%,Avail是否为 0 -
df -i:重点看IUse%,100% 表示无法新建文件(logrotate 生成大量.log.1、.log.2.gz后未清理就容易触发) -
lsof +L1 | grep nginx:检查是否有已删除但 worker 仍占用的 “deleted” 日志文件,这是典型删了日志却没释放空间的信号
绕过日志本身,抓系统级失败原因
当 error.log 也空白时,就得从系统调用层面看它到底被谁拦住了:
- 启动时强制输出错误:
nginx -c /etc/nginx/nginx.conf -e stderr,能捕获初始化阶段 open 失败(如路径不可写) - 跟踪 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 干预:
ausearch -m avc -ts recent | grep nginx(CentOS/RHEL),若有 AVC denied 记录,说明安全策略阻止了写入
加固配置,避免反复踩坑
靠默认机制扛不住生产环境波动,得主动加防护:
- 启用带刷盘的缓冲:
access_log /var/log/nginx/access.log main buffer=32k flush=1s;,减少 I/O 频次 - 改用 syslog 并开启磁盘队列(推荐):
access_log syslog:server=127.0.0.1:514,facility=local7 main;,配合 rsyslog 的$ActionQueueFileName和$ActionQueueMaxDiskSpace设置持久化队列 - 低价值路径关日志:
location = /healthz { access_log off; },避免心跳请求挤占 I/O - 关键路径监控脚本:定期检查
stat /var/log/nginx/access.log修改时间 +ls -l /proc/$(cat /run/nginx.pid)/fd/ | grep access是否还指向有效文件句柄

















