搜索全站
报错排查 9 分钟阅读

PHP 错误日志配置与查看:Nginx、PHP-FPM 日志在哪儿怎么读

WordPress 出问题却看不到任何报错时,服务器日志是唯一线索。本文讲清 Nginx 访问日志与错误日志、PHP-FPM 错误日志与慢日志的默认位置、如何开启与轮转,以及如何从日志特征快速判断 502、504、404、超时、内存耗尽等不同故障类型。

U
UFO_PF 2017-05-25 · 阅读 9 分钟
PH 报错排查
阅读提示
本文约 3,230 字,预计阅读 9 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:看不到报错,不代表没报错

WordPress 层面关闭调试后,很多错误只存在于服务器日志里:502 是 PHP-FPM 挂了、504 是执行超时、403 是权限或 SELinux、内存耗尽则是 PHP fatal。

这些都不会在浏览器里显示原因。会看日志,是从”重启试试”进阶到”定位修复”的分水岭。

原理分析:三层日志各记什么

日志 记录内容 典型用途
Nginx access.log 每条请求:IP、URL、状态码、耗时 看访问量、扫描行为、异常请求
Nginx error.log Nginx 层错误:连接失败、超时、权限 502/504 定位
PHP-FPM error.log PHP 进程错误:启动失败、达到最大子进程 进程池耗尽
PHP-FPM slow.log 执行超过阈值的请求及堆栈 慢查询、慢插件定位
MySQL error.log 数据库错误、崩溃、启动失败 数据库故障

保姆级实操

一、确认日志位置

# Nginx
nginx -V 2>&1 | grep -o 'error-log-path=[^ ]*'
ls /var/log/nginx/

# PHP-FPM
php-fpm8.2 -i | grep -i error_log
ls /var/log/php8.2-fpm.log

# 或者直接看 systemd 日志
journalctl -u php8.2-fpm -n 100 --no-pager
journalctl -u nginx -n 100 --no-pager

二、开启 PHP-FPM 错误与慢日志

/etc/php/8.2/fpm/pool.d/www.conf:

php_admin_flag[log_errors] = on
php_admin_value[error_log] = /var/log/php8.2-fpm/site-error.log
slowlog = /var/log/php8.2-fpm/site-slow.log
request_slowlog_timeout = 5s
catch_workers_output = yes

catch_workers_output = yes 很关键:它把 worker 进程的 stdout/stderr 也收进主日志,否则部分 PHP 错误会丢失。

sudo systemctl restart php8.2-fpm

三、常用查看命令

# 实时跟踪错误日志
tail -f /var/log/nginx/error.log

# 只看最近 200 条并按时间过滤
tail -n 200 /var/log/nginx/error.log | grep '2026/10/10'

# 统计 502 数量
grep -c ' 502 ' /var/log/nginx/access.log

# 找出最慢的请求(需配置 $request_time 日志格式)
awk '{print $NF, $7}' /var/log/nginx/access.log | sort -rn | head -20

# 找被频繁访问的异常 URL
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

四、从日志特征判断故障类型

日志特征 故障 处理
connect() to unix:/run/php/php8.2-fpm.sock failed (111: Connection refused) PHP-FPM 没启动 启动服务,看启动失败原因
upstream timed out (110: Connection timed out) while reading response header PHP 执行超时 调 fastcgi_read_timeout 与 max_execution_time
server reached pm.max_children setting 进程池耗尽 调大 max_children 或加缓存
recv() failed (104: Connection reset by peer) PHP 进程崩溃 看 PHP-FPM 日志的 fatal error
open() "/xxx" failed (13: Permission denied) 文件权限或 SELinux 检查属主与上下文
FastCGI sent in stderr: "PHP message: PHP Fatal error: Allowed memory size exhausted" PHP 内存不足 调 memory_limit 或定位内存泄漏插件
大量 POST /wp-login.php 且 200 但无结果 暴力破解 加登录保护、封 IP

五、配置访问日志格式(含耗时)

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent" rt=$request_time urt=$upstream_response_time';

access_log /var/log/nginx/access.log main;

$upstream_response_time 能直接看出是 PHP 慢还是 Nginx 慢。

六、日志轮转

Ubuntu/Debian 默认已配 logrotate,检查:

cat /etc/logrotate.d/nginx
cat /etc/logrotate.d/php8.2-fpm

自定义 PHP 日志的话要自己加配置, otherwise 日志会无限增长。

常见踩坑与失败案例

  1. 日志里什么都没有 —— 可能 Nginx 用了默认站点配置,日志写到了 /var/log/nginx/error.log 之外的文件。用 nginx -T | grep error_log 全量查看。
  2. 案例:某站每天凌晨 502,白天正常。查 error.log 发现是每日备份脚本执行时 PHP 进程被占满,同时触发 pm.max_children。解决办法是把备份改到低峰并提高进程数。
  3. 磁盘被日志写满 —— 没有 logrotate 或轮转后没压缩。用 df -h 与 du -sh /var/log/* | sort -rh | head 排查。
  4. 慢日志没生成 —— request_slowlog_timeout 设成了 0(关闭),或者 slowlog 路径 PHP-FPM 无写权限。
  5. ** SELinux 阻止写日志** —— 错误日志里出现 permission denied 但文件权限正常,用 ausearch -m AVC 确认。

总结

看日志的能力可以拆成三步:知道日志在哪(nginx -V / php-fpm -i / journalctl)、会过滤(grep 状态码、按耗时排序、统计高频 URL)、能对应故障类型(上面那张特征表基本覆盖了 90% 场景)。建议给自己的服务器做一份”日志速查表”文档,把路径和常用命令记下来,出事故时不用现查。另外,日志轮转一定要配,否则排查工具本身会变成故障源。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。