PHP Slowlog 为空,尽管 PHP-FPM 说它正在记录

Bra*_*ley 3 php php-fpm docker php7

我让 PHP-FPM 监听 Unix 域套接字,并www使用以下值配置了池(唯一存在的):

slowlog = /$pool.log.slow
request_slowlog_timeout = 10s
Run Code Online (Sandbox Code Playgroud)

为了测试,我将 max_execution_time 设置php.ini为 20 秒。然后我创建了一个测试脚本:

<?php

while(1){
  $i++;
}

?>
Run Code Online (Sandbox Code Playgroud)

然后通过网络浏览器访问它。脚本最终超时,原因是max_execution_time但日志仍为空:

root@b7e4a919c988:/var/www/html# ll /www.log.slow 
-rw-rw-rw-. 1 www-data root 0 Jan  4 21:31 /www.log.slow
Run Code Online (Sandbox Code Playgroud)

不过,PHP-FPM 日志似乎表明它期望记录缓慢的运行:

[04-Jan-2018 21:37:28] WARNING: [pool www] child 9382, script '/var/www/html/test.php' (request: "GET /test.php") executing too slow (13.061999 sec), logging
Run Code Online (Sandbox Code Playgroud)

我尝试了各种方法,例如使用循环sleep(10000)或将while循环放入函数中(以防万一它无法构建堆栈跟踪),但似乎没有什么可以让它将回溯打印到日志中。日志文件本身的存在似乎也表明 FPM 预计会写入缓慢的请求。

此时我只是不知道还要检查什么。

Bra*_*ley 5

经过一番努力,我终于找到了问题所在。问题是,在 Linux 上,PHP-FPM 用于SYS_PTRACE跟踪工作进程(我猜这就是它检索跟踪数据的方式),但docker容器默认情况下不允许此功能。

一旦我使用该选项运行 docker 容器并配置了OP 中提到的--cap-add=SYS_PTRACE两个设置(和)。www.confslowlogrequest_slowlog_timeout

与我见过的其他答案相反,我从来不需要启用catch_workers_output它才能工作。

上面的脚本生成以下输出到 Slowlog:

[09-Jan-2018 17:30:39]  [pool www] pid 9382                
script_filename = /var/www/html/work.php 
Run Code Online (Sandbox Code Playgroud)

但为了生成更真实的函数跟踪,我写了这个小数字:

<?php

function callsSlowFunc(){

  for ($i=0; $i<=10; $i++){
    slowFunc();
  }

}

function slowFunc(){

  for ($j=0; $j <= 50000000; $j++){
    $hey="there";
  }

}

callsSlowFunc();
Run Code Online (Sandbox Code Playgroud)

这会导致生成此函数跟踪:

[09-Jan-2018 17:40:49]  [pool www] pid 9382
script_filename = /var/www/html/work.php
[0x00007fee53613150] slowFunc() /var/www/html/work.php:6
[0x00007fee536130a0] callsSlowFunc() /var/www/html/work.php:19
Run Code Online (Sandbox Code Playgroud)