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
相关产品推荐
相关产品推荐

