排查Nginx access_log无法写入,核心是确认worker进程对日志路径的完整访问链权限——需逐级检查根目录至目标文件的x(进入)和w(写入)权限,并验证SELinux/AppArmor拦截、logrotate后未发USR1信号导致句柄失效等问题。

排查 Nginx access_log 无法写入,核心是确认“Nginx worker 进程是否具备对日志路径的完整访问链权限”——不是只看文件本身,而是从根目录开始逐级检查可进入(x)、可写(w)能力。
确认 worker 进程实际运行用户
Nginx master 以 root 启动,但真正写日志的是 worker 进程,它的身份由 nginx.conf 中的 user 指令决定(如 user www-data; 或 user nginx;)。若配置缺失或 Nginx 非 root 启动,worker 会退化为启动者身份。
- 运行
ps aux | grep "nginx: worker",看 USER 列(例如www-data) - 对比
nginx -t输出中加载的配置路径,打开该配置查user行
逐级验证日志路径权限
Linux 目录访问需“穿过每一级”,任意一级缺少 x(执行)权限,worker 就无法抵达目标文件。例如日志路径为 /data/logs/nginx/access.log,需确保:
对设计或页面进行 WCAG 2.1 AA 无障碍审计。触发关键词:“audit accessibility”、 “check a11y”、 “is this accessible?” 或在审查设计时使用。
-
/:所有用户默认有 x 权限,通常无需干预 -
/data:www-data用户或其所属组必须有x权限(即目录可进入) -
/data/logs:同上,且还需w权限(才能创建/追加文件) -
/data/logs/nginx:同上,且目录必须存在 -
access.log文件:若已存在,www-data需有w权限;若不存在,依赖父目录w+x权限自动创建
快速检查命令:ls -ld /data /data/logs /data/logs/nginx,重点看权限列第三段(others)或第二段(group),确认对应用户/组有 rwx 中的 x 和 w。
检查 SELinux 或 AppArmor 干预
即使磁盘、权限都正常,安全模块也可能静默拦截写操作,且不记录到 error_log。
- CentOS/RHEL 系统:
ausearch -m avc -ts recent | grep nginx,查看是否有avc: denied拒绝日志 - Ubuntu/Debian 系统:
aa-status | grep nginx查是否受限,再用dmesg | grep -i "avc\|apparmor"辅助确认 - 临时验证:设为 permissive 模式(
setenforce 0或aa-complain /usr/sbin/nginx),观察日志是否恢复
验证日志文件句柄与轮转状态
logrotate 后未发 USR1 信号,worker 仍往已删除文件写入,系统返回 EBADF,Nginx 静默丢弃,error_log 不报错。
- 查当前 worker 打开的日志句柄:
ls -l /proc/$(cat /var/run/nginx.pid)/fd/ | grep access - 若显示
access.log (deleted),说明文件已被删但进程未重载,立即执行kill -USR1 $(cat /var/run/nginx.pid) - 检查 logrotate 配置(如
/etc/logrotate.d/nginx)是否含create 640 nginx adm和postrotate ... kill -USR1 ... endscript

















