Home > Backend Development > PHP Tutorial > Split Log Levels Between Stdout and Stderr With Laravel

Split Log Levels Between Stdout and Stderr With Laravel

Emily Anne Brown
Release: 2025-03-06 02:06:14
Original
747 people have browsed it

Split Log Levels Between Stdout and Stderr With Laravel

Have you ever thought about logging a specific level in Laravel? Of course, you can use the level configuration option to specify the minimum level to log, but what if you just want to log the and Debug logs into a specific logger? Info

Suppose you are writing a CLI command and want to split the logging into

and stdout. Using tools like Laravel Zero or Artisan, you may have the following command to demonstrate that only sending stderr logs to a location: stderr

php artisan my-command 2> storage/logs/stderr.log
Copy after login
Then, the

log might look like this: stderr

The
<code>[2024-10-01 02:48:49] development.ERROR: The daemon has run too many times. (6 times now, come on!)
[2024-10-01 02:48:52] development.ERROR: The daemon has run too many times. (7 times now, come on!)
...</code>
Copy after login

log contains log information at the stdout and INFO levels. DEBUG

Configure Laravel to filter log levels

The trick to configure Laravel loggers to split logs is to use Monolog's

, which allows only the given level of records to pass through the wrapped handler. A direct example is as follows: FilterHandler

use Monolog\Handler\FilterHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Level;

// 使用最小和最大级别参数
$handler = new FilterHandler(
    handler: new StreamHandler('php://stdout'),
    minLevelOrList: Level::Debug,
    maxLevel: Level::Info,
);

// 使用列表
$handler = new FilterHandler(
    handler: new StreamHandler('php://stdout'),
    minLevelOrList: [Level::Debug, Level::Info]
);
Copy after login
To illustrate how to configure

in the logging.php configuration file of Laravel, a named parameter is used here. We can use the following configuration changes to the FilterHandler and stderr log channels (or create new channels), using the stdout driver: stack

<?php return [
    'channels' => [
        'stack' => [
            'driver' => 'stack',
            'channels' => explode(',', env('LOG_STACK', 'stdout,stderr')),
            'ignore_exceptions' => false,
        ],

        'stdout' => [
            'driver' => 'monolog',
            'handler' => \Monolog\Handler\FilterHandler::class,
            'formatter' => env('LOG_STDOUT_FORMATTER'),
            'with' => [
                'handler' => fn () => new StreamHandler('php://stdout'),
                'minLevelOrList' => [Monolog\Level::Debug, Monolog\Level::Info],
            ],
            'processors' => [PsrLogMessageProcessor::class],
        ],

        'stderr' => [
            'driver' => 'monolog',
            'handler' => StreamHandler::class,
            'formatter' => env('LOG_STDERR_FORMATTER'),
            'with' => [
                'stream' => 'php://stderr',
            ],
            'level' => 'notice',
            'processors' => [PsrLogMessageProcessor::class],
        ],
    ],
];
Copy after login
Please note, how does the

key match the named parameters of the with constructor? FilterLogger The logger will record debug and information logs, while the stdout logger is set to stderr to catch any notification or higher CLI errors. level noticeI also want to point out that Monolog accepts closures of the

handler so that wrapping

instances are created only when using the log channel: FilterHandler StreamHandler

Catching logs in this way It is useful for headless/daemon CLI commands when sending logs from containers to log services. For example, use JSON to format the error logs so that services like DataDog can be used. Here is an example of the environment setup you might have, explained in a
'handler' => fn () => new StreamHandler('php://stdout'),
Copy after login
file:

docker-compose.yaml

Monolog provides many handlers, formatters, and processors that can be used to configure in Laravel, and all common use cases are already covered in the
services:
  cli:
    build:
      context: .
      dockerfile: build/Dockerfile
    # 不要将任何消息输出到控制台。
    # 只会发送日志。
    command: ["daemon", "--quiet"]
    environment:
      LOG_CHANNEL: "stack"
      LOG_LEVEL: "info"
      LOG_STACK: "stdout,stderr"
      LOG_STDOUT_FORMATTER: "\Monolog\Formatter\JsonFormatter"
      LOG_STDERR_FORMATTER: "\Monolog\Formatter\JsonFormatter"
Copy after login
configuration file.

logging.phpYou can learn more about logging in the Laravel application in the official documentation.

The above is the detailed content of Split Log Levels Between Stdout and Stderr With Laravel. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template