首页 >后端开发 >php教程 >与Laravel之间的Stdout和Stderr之间的分组日志级别

与Laravel之间的Stdout和Stderr之间的分组日志级别

Emily Anne Brown
Emily Anne Brown原创
2025-03-06 02:06:14750浏览

Split Log Levels Between Stdout and Stderr With Laravel

您是否想过在 Laravel 中记录特定级别的日志?当然,您可以使用 level 配置选项来指定要记录的最低级别,但是如果您只想将 DebugInfo 日志记录到特定的日志记录器中怎么办?

假设您正在编写一个 CLI 命令,并希望将日志记录拆分为 stdoutstderr。使用 Laravel Zero 或 Artisan 等工具,您可能会有以下命令来演示仅将 stderr 日志发送到某个位置:

php artisan my-command 2> storage/logs/stderr.log

然后,stderr 日志可能如下所示:

<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>

stdout 日志中则包含 INFODEBUG 级别的日志信息。

配置 Laravel 以过滤日志级别

配置 Laravel 日志记录器以拆分日志的技巧是使用 Monolog 的 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]
);

为了说明如何在 Laravel 的 logging.php 配置文件中配置 FilterHandler,这里使用了具名参数。我们可以使用以下配置更改 stderrstdout 日志通道(或创建新的通道),使用 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],
        ],
    ],
];

请注意,with 键如何与 FilterLogger 构造函数的具名参数匹配?stdout 日志记录器将记录调试和信息日志,而 stderr 日志记录器的 level 设置为 notice,以捕获任何通知或更高级别的 CLI 错误。

我还想指出,Monolog 接受 FilterHandler 处理程序的闭包,以便只有在使用日志通道时才会创建包装的 StreamHandler 实例:

'handler' => fn () => new StreamHandler('php://stdout'),

以这种方式捕获日志在将日志从容器发送到日志服务时,对于无头/守护进程 CLI 命令非常有用。例如,使用 JSON 格式化错误日志,以便像 DataDog 这样的服务可以使用。这是一个您可能拥有的环境设置示例,在一个 docker-compose.yaml 文件中进行了说明:

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"

Monolog 提供了许多可用于在 Laravel 中配置的处理程序、格式化程序和处理器,并且 logging.php 配置文件中已经涵盖了所有常见用例。

您可以在官方文档中了解有关 Laravel 应用程序中日志记录的更多信息。

以上是与Laravel之间的Stdout和Stderr之间的分组日志级别的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn