9

I want my laravel applications to run as well mannered 12 factor apps. Right now I'm struggling to get their to logs to and from stdout (stderr is also fine by me) under php-fpm. The php version is 7.2.1, the laravel version is 5.6.3.

I configured laravel to use the single driver to write to stdout:

<?php

return [
    'default' => env('LOG_CHANNEL', 'stack'),
    'channels' => [
        'stack' => [
            'driver' => 'stack',
            'channels' => ['single'],
        ],

        'single' => [
            'driver' => 'single',
            'path' => 'php://stdout',
            'tap' => [App\Logging\UseJsonFormatter::class],
            'level' => 'debug',
        ],
];

This works well with the test server, but fpm prefixes this with with dates and a warning: [19-Feb-2018 09:43:41] WARNING: [pool www] child 12 said into stdout: every ~1000 characters. The problem seems to be known as issue 71880 (prefix) and issue 69031 (truncation). A Pull Request saw last action in June / November last year. Does anybody have a workaround that doesn't chunk or truncate the log messages (I'm logging json objects, and I like them complete)?

Why PHP-FPM prefixes a warning when writing to stdout? is related to this, but is still not solved either.

This is UseJsonFormatter.php if anyone is interested:

<?php    
namespace App\Logging;


use Monolog\Formatter\JsonFormatter;

class UseJsonFormatter
{
    /**
     * Customize the given Monolog instance.
     *
     * @param  \Monolog\Logger  $monolog
     * @return void
     */
    public function __invoke($monolog)
    {
        $jsonFormatter = new JsonFormatter();
        foreach ($monolog->getHandlers() as $handler) {
            $handler->setFormatter($jsonFormatter);
        }
    }
}
tback
  • 11,138
  • 7
  • 47
  • 71
  • Have you tried writing logs to `/dev/stdout` and `/dev/stderr` instead? – Mike Doe Feb 19 '18 at 10:16
  • @Mike I have and laravel reports both as missing: `The stream or file "/dev/stderr" could not be opened: failed to open stream: No such file or directory` – tback Feb 19 '18 at 10:29

2 Answers2

7

This is fixed in PHP 7.3. The config directive for the pool is decorate_workers_output = no as documented in the pull request.

tback
  • 11,138
  • 7
  • 47
  • 71
3

With Monolog in general, if you want to keep for instance DEBUG to INFO messages in STDOUT and higher levels to STDERR, you could do something like this.

$log->pushHandler(
    new \Monolog\Handler\FilterHandler(
        new \Monolog\Handler\StreamHandler('php://stdout'),
            \Monolog\Logger::DEBUG,
            \Monolog\Logger::NOTICE
    )
);

$log->pushHandler(
    new \Monolog\Handler\FilterHandler(
        new \Monolog\Handler\StreamHandler('php://stderr'),
            \Monolog\Logger::WARNING,
            \Monolog\Logger::EMERGENCY
    )
);
Arash Hatami
  • 5,297
  • 5
  • 39
  • 59
inquam
  • 12,664
  • 15
  • 61
  • 101
  • Where do I need to place this? – Kaymaz Feb 06 '20 at 12:29
  • @Kaymaz: Anywhere you have access to the logger object, but preferable close to where you instantiate your logger object so you have it setup this way as early as possible. – inquam Feb 06 '20 at 19:11