slowlog 并非漏记,而是仅记录 PHP 执行阶段超阈值的请求;若未记录,常见原因为 request_slowlog_timeout 未生效、request_terminate_timeout 提前终止进程、日志路径权限不足或单位错误(如误用 ms)。

slowlog 为什么只记录部分请求
不是日志“漏了”,而是 request_slowlog_timeout 触发机制本身是确定性的:只要单个请求在 PHP-FPM worker 进程内执行时间 ≥ 阈值,就必记一条。所谓“只记录部分”,通常是因为实际卡顿未达阈值、或超时被更高层截断(如 request_terminate_timeout 先触发 kill),导致根本没走到 slowlog 记录环节。
如何确认 slowlog 是否全量生效
别只看日志有没有内容,先验证配置是否真正加载到 pool 级别:
-
php-fpm -t能过不代表 pool 段配置生效;必须用php-fpm -z /var/run/php/php7.2-fpm.status(需提前配好pm.status_path)或ps aux | grep php-fpm查看实际运行的 pool 配置路径 - 检查
slowlog文件权限:PHP-FPM worker 用户(如www-data)必须对日志目录有w权限,否则静默失败——常见于手动创建目录但忘了chown www-data:www-data /var/log/php-fpm/ - 确认
request_slowlog_timeout单位正确:PHP 7.2 只支持s(秒),不识别ms;写成500ms会被当 0 处理,等效关闭
PHP 7.2 下没有采样率控制,只有阈值调节
PHP 7.2 的 slowlog 不支持类似 “每 10 个慢请求记 1 个” 的采样配置。它本质是全量触发,但受两个现实约束:
-
request_terminate_timeout若设为非 0 值(如30s),且小于request_slowlog_timeout(如60s),那所有超 30s 的请求都会被强制终止,never reach slowlog 记录点 - 高并发下,若大量请求同时超时,
slowlog文件 I/O 可能成为瓶颈,部分记录被内核丢弃(无报错);此时应降低阈值(如从5s改为2s),让问题更早暴露、分散写入压力 - PHP 7.2 不支持
slowlog的条件过滤(如按 URL 或 method 排除),只能靠后续日志分析工具做 post-filter
验证 slowlog 是否真在工作
最直接的方法:在测试脚本里插一句 sleep(3),并确保该请求走的是你改过的 pool(比如访问 /test-slow.php):
立即学习“PHP免费学习笔记(深入)”;
echo "start"; sleep(3); echo "done";
然后观察 slowlog 是否出现对应 backtrace。如果没出现,说明要么配置没 reload(systemctl reload php7.2-fpm),要么 request_slowlog_timeout 实际值仍是 0(用 php-fpm -i | grep request_slowlog_timeout 确认)。
注意:slowlog 记录的是 PHP 执行阶段耗时,不包括 Nginx 解析头、TLS 握手、网络传输这些——如果 access.log 显示耗时长但 slowlog 空,问题大概率不在 PHP 层。



















