You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel终端/stdout日志莫名添加WARN关键字致JSON格式异常

Laravel自定义日志通道输出到stdout时自动添加WARN关键字的解决办法

我在使用Laravel内置日志通道和自定义日志通道时发现,将日志输出到终端/stdout时,每条日志前会自动追加WARN关键字,但输出到日志文件时显示正常。我的需求是在终端输出JSON格式日志,这个额外的关键字导致日志变成了字符串格式,无法被正确解析。

相关配置代码

日志通道配置

'methodlog' => [
    'driver' => 'custom',
    'via' => App\Logging\MethodLogChannel::class,
    'formatter' => App\Logging\CustomJsonFormatter::class,
    'name' => 'methodlog',
    'with' => [
        'path' => storage_path('logs/laravel.log'),//'php://stdout',
        'level' => env('LOG_LEVEL', 'debug'),
    ],
],        

CustomJsonFormatter.php

class CustomJsonFormatter extends JsonFormatter
{
    private $DEFAULT_JSON_FLAGS = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION | JSON_INVALID_UTF8_SUBSTITUTE | JSON_PARTIAL_OUTPUT_ON_ERROR ;
    public function format(LogRecord $record): string
    {
        $formatted = $record['context'];

        if ($this->includeStacktraces) {
            $formatted['stack_trace'] = $record['formatted']['exception'];
        }

        return $this->toJson($formatted, true) . ($this->appendNewline ? "\n" : '');
    }
}

MethodLogChannel.php

class MethodLogChannel
{
    public function __invoke(array $config)
    {
        $log = new Logger($config['name']);
        $handler = new StreamHandler($config['with']['path'], $config['with']['level']);
        $handler->setFormatter(new CustomJsonFormatter());
        $log->pushHandler($handler);
        $log->pushProcessor(new IntrospectionProcessor());
        $log->pushProcessor(new WebProcessor($_SERVER));
        return $log;
    }
}

日志调用代码

Log::channel('methodlog')->info('', $log_message);

问题原因

核心问题在于自定义日志通道中,直接将字符串类型的日志级别(如'debug')传递给Monolog的StreamHandler,而StreamHandler需要的是整数类型的Monolog级别常量(如Logger::DEBUG)。当传入字符串时,Monolog无法正确解析级别,默认使用了WARNING级别,导致输出时自动添加WARN前缀。

同时,自定义Formatter中JSON flags的设置方式不符合父类设计,可能引发潜在的格式化问题。

解决方案

1. 修复日志级别转换

修改MethodLogChannel.php,使用Monolog的toMonologLevel方法将字符串级别转换为对应的常量:

<?php

namespace App\Logging;

use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Monolog\Processor\IntrospectionProcessor;
use Monolog\Processor\WebProcessor;

class MethodLogChannel
{
    public function __invoke(array $config)
    {
        $log = new Logger($config['name']);
        // 将字符串级别转换为Monolog常量
        $level = Logger::toMonologLevel($config['with']['level']);
        $handler = new StreamHandler($config['with']['path'], $level);
        $handler->setFormatter(new CustomJsonFormatter());
        $log->pushHandler($handler);
        $log->pushProcessor(new IntrospectionProcessor());
        $log->pushProcessor(new WebProcessor($_SERVER));
        return $log;
    }
}

2. 调整Formatter的JSON flags设置方式

修改CustomJsonFormatter.php,通过构造函数设置JSON flags,遵循父类的属性设计:

<?php

namespace App\Logging;

use Monolog\Formatter\JsonFormatter;
use Monolog\LogRecord;

class CustomJsonFormatter extends JsonFormatter
{
    public function __construct(int $batchMode = self::BATCH_MODE_NEWLINES, bool $appendNewline = true)
    {
        parent::__construct($batchMode, $appendNewline);
        $this->jsonFlags = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION | JSON_INVALID_UTF8_SUBSTITUTE | JSON_PARTIAL_OUTPUT_ON_ERROR;
    }

    public function format(LogRecord $record): string
    {
        $formatted = $record['context'];

        if ($this->includeStacktraces && isset($record['formatted']['exception'])) {
            $formatted['stack_trace'] = $record['formatted']['exception'];
        }

        return $this->toJson($formatted, true) . ($this->appendNewline ? "\n" : '');
    }
}

3. (可选)使用Laravel内置通道简化配置

如果不需要复杂的自定义处理器逻辑,可以直接使用Laravel内置的single通道,避免手动创建通道的潜在问题:

'methodlog' => [
    'driver' => 'single',
    'path' => 'php://stdout',
    'level' => env('LOG_LEVEL', 'debug'),
    'formatter' => App\Logging\CustomJsonFormatter::class,
],

完成以上修改后,终端输出的日志将不再包含WARN前缀,保持纯JSON格式。

内容的提问来源于stack exchange,提问作者Priyam Sinha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 07:32:17