С тех пор, как я начал использовать библиотеку 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: "************************************************************"
Обратите внимание, как в последней строке вывод 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: "***********"
Здесь вывод stderr отключается после t
, который оставляет достаточно информации, чтобы найти проблему, но это все еще не полное сообщение. Я не могу найти никакой закономерности между длиной вывода и моментом его обрезки.
Я использую nginx версии 1.10.3 и PHP версии 7.1.8 в Debian Stretch. Я также попытался установить следующие значения в nginx.conf
(потому что я уже искал решения этой проблемы в прошлом), но приведенные выше примеры были созданы с этими настройками, которые уже действуют.
fastcgi_buffers 256 4k;
client_max_body_size 20M;
Согласно ответам, найденным в аналогичный вопрос даже если я каким-то образом обойду ограничения на количество символов в php-fpm, nginx также обрежет вывод, что может привести к потере информации.
Чтобы полностью устранить этот риск, я решил использовать Монолог для обработки журнала на уровне приложения, который можно использовать с выходным файлом для записи произвольно длинных сообщений об ошибках и трассировки стека. Этот вопрос может быть полезным для всех, кто хочет сделать то же самое.