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

Laravel 10指定日志通道时上下文信息日志无法正常解析

Laravel 10 指定日志通道后上下文占位符不替换的原因

现象复现

正常工作的场景

使用默认日志通道时,上下文数据能正常替换消息中的占位符:

Log::info(
    'User {user} created Thing {id}', 
    [
        'user' => auth()->user()->id,
        'id' => $thing->id
    ]
);

输出日志:

[2024-01-31 08:44:23] local.INFO: User 1 created Thing 3 {"user":1,"id":3} 

指定自定义通道后的异常场景

切换到自定义mychannel通道后,占位符未被替换,仅在日志尾部输出上下文数组:

Log::channel('mychannel')->info(
    'User {user} created Thing {id}',
    [
        'user' => auth()->user()->id,
        'id' => $thing->id
    ]
);

输出日志:

[2024-01-31 08:36:15] local.INFO: User {user} created Thing {id} {"user":1,"id":2} 

核心原因

问题出在自定义日志通道mychannel的格式化器未启用占位符替换功能。

Laravel默认日志通道(如stack、single)使用的Monolog LineFormatter默认开启了占位符替换逻辑,会自动将消息中的{key}匹配上下文数组中的对应值进行替换。但自定义通道如果存在以下情况,就会丢失这个功能:

  • 手动配置格式化器时,未显式设置replacePlaceholders为true;
  • 使用了不支持占位符替换的第三方格式化器;
  • 自定义通道配置未继承默认日志的格式化器设置;

修复方案

检查并修改config/logging.php中mychannel的配置,确保格式化器开启占位符替换:

'channels' => [
    'mychannel' => [
        'driver' => 'single',
        'path' => storage_path('logs/mychannel.log'),
        'level' => 'debug',
        'formatter' => Monolog\Formatter\LineFormatter::class,
        'formatter_with' => [
            'format' => '[%datetime%] %channel%.%level_name%: %message% %context% %extra%',
            'replacePlaceholders' => true, // 必须开启此参数
        ],
    ],
],

如果是通过tap类自定义日志处理器,需要在tap类中手动开启替换:

class CustomizeFormatter
{
    public function __invoke($logger)
    {
        foreach ($logger->getHandlers() as $handler) {
            $formatter = $handler->getFormatter();
            if ($formatter instanceof \Monolog\Formatter\LineFormatter) {
                $formatter->setReplacePlaceholders(true);
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 21:59:57