nginx 记录 php-fpm 的 stderr 输出在看似随机的位置被切断

Sei*_*Sys 5 nginx logging php-fpm stderr php-fastcgi

自从我开始使用产生长调用链的 PHP 库以来,调试由它引起的问题变得越来越困难,因为我的错误日志最终包含如下输出:(某些值已使用 被清空*

2017/08/23 10:47:26 [error] 13057#13057: *206119 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught ActiveRecord\DatabaseException: PDOException: SQLSTATE[22P02]: Invalid text representation: 7 ERROR:  invalid input syntax for integer: "" in /var/www/********/vendor/php-activerecord/php-activerecord/lib/Connection.php:337
Stack trace:
#0 /var/www/********/vendor/php-activerecord/php-activerecord/lib/Connection.php(337): PDOStatement->execute(Array)
#1 /var/www/********/vendor/php-activerecord/php-activerecord/lib/Table.php(237): ActiveRecord\Connection->query('SELECT * FROM "...', Array)
#2 /var/www/********/vendor/php-activerecord/php-activerecord/lib/Table.php(219): ActiveRecord\Table->find_by_sql('SELECT * FROM "...', Array, false, NULL)
#3 /var/www/********/vendor/php-activerecord/php-activerecord/lib/Model.php(1666): ActiveRecord\Table->find(Array)
#4 /var/www/********/vendor/php-activerecord/php-activerecord/lib/Model.php(1605): ActiveRecord\Model::find_by_pk('', Array)
#5 /var/www/********/includes/classes/Models/NSModel.php(11): ActiveRecord\Model::find(''" while reading response header from upstream, client: **.***.***.***, server: ***********, request: "POST /************************************ HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.1-fpm.sock:", host: "***********", referrer: "************************************************************"
Run Code Online (Sandbox Code Playgroud)

请注意最后一行 FastCGI stderr 输出如何在ActiveRecord\Model::find(''". 另一个例子:

2017/08/22 17:20:53 [error] 13057#13057: *193907 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught TypeError: Argument 1 passed to App\DeviantArt::isImageAvailable() must be of the type string, null given, called in /var/www/********/includes/classes/ImageProvider.php on line 138 and defined in /var/www/********/includes/classes/DeviantArt.php:357
Stack trace:
#0 /var/www/********/includes/classes/ImageProvider.php(138): App\DeviantArt::isImageAvailable(NULL)
#1 /var/www/********/includes/classes/ImageProvider.php(21): App\ImageProvider->setUrls('*******')
#2 /var/www/********/includes/classes/Posts.php(207): App\ImageProvider->__construct('******************', Array)
#3 /var/www/********/includes/classes/Controllers/PostController.php(334): App\Posts::checkRequestFinishingImage('***************...')
#4 /var/www/********/includes/classes/RouteHelper.php(11): App\Controllers\PostController->action(Array)
#5 /var/www/********/includes/do.php(27): App\RouteHelper::App\{closure}(Array)
#6 /var/www/********/www/index.php(1): require('/var/www/******...')
#7 {main}
  t" while reading response header from upstream, client: **.***.***.***, server: ***********, request: "POST /*************************** HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.1-fpm.sock:", host: "***********"
Run Code Online (Sandbox Code Playgroud)

这里,stderr 输出在 后被切断t,这留下了足够的信息来查找问题,但它仍然不是完整的消息。我找不到输出长度和被切断时间之间的任何模式。

我在 Debian Stretch 上使用 nginx 版本 1.10.3 和 PHP 版本 7.1.8。我还尝试设置以下值nginx.conf(因为我过去查找过此问题的解决方案),但上面的示例是在这些设置已经生效的情况下生成的。

fastcgi_buffers 256 4k;
client_max_body_size 20M;
Run Code Online (Sandbox Code Playgroud)

Sei*_*Sys -1

根据类似问题下找到的答案,即使我以某种方式绕过 php-fpm 的字符限制,nginx 也会截断输出,可能导致信息丢失。

为了完全消除这种风险,我选择使用Monolog来处理应用程序级别的日志记录,它可以与文件输出一起使用来写入任意长的错误消息和堆栈跟踪。这个问题可能对任何想要做同样事情的人有帮助。