Laravel自定义JSON日志通道如何正确设置action字段?
实现自定义
withAction日志方法的正确方式 方法一:注册日志宏实现链式调用
在App\Providers\AppServiceProvider的boot方法里添加自定义宏,让Log facade支持withAction链式调用:
use Illuminate\Support\Facades\Log; public function boot() { Log::macro('withAction', function (string $action) { return $this->withContext(['action' => $action]); }); }
方法二:修复JSON格式化的嵌套问题
如果用withContext后action被嵌套在context节点里,调整events通道的格式化配置,让上下文字段直接平级输出到JSON根节点:
打开config/logging.php,修改events通道的formatter_with参数:
'events' => [ 'driver' => 'single', 'path' => storage_path('logs/events.log'), 'level' => 'debug', 'formatter' => Monolog\Formatter\JsonFormatter::class, 'formatter_with' => [ 'includeStacktraces' => false, 'appendNewline' => true, // 关键设置:取消context和extra的嵌套键,直接展开字段 'contextKey' => null, 'extraKey' => null, ], ],
方法三:自定义格式化器(更灵活)
如果需要更精细的字段控制,可创建自定义格式化器:
- 创建
app/Logging/CustomJsonFormatter.php:
namespace App\Logging; use Monolog\Formatter\JsonFormatter; class CustomJsonFormatter extends JsonFormatter { public function format(array $record): string { // 把context里的action提取到根节点 if (isset($record['context']['action'])) { $record['action'] = $record['context']['action']; unset($record['context']['action']); } // 移除空的context/extra字段,精简日志结构 if (empty($record['context'])) unset($record['context']); if (empty($record['extra'])) unset($record['extra']); return parent::format($record); } }
- 在
config/logging.php的events通道中使用这个自定义格式化器:
'events' => [ 'driver' => 'single', 'path' => storage_path('logs/events.log'), 'level' => 'debug', 'formatter' => App\Logging\CustomJsonFormatter::class, 'formatter_with' => [ 'includeStacktraces' => false, 'appendNewline' => true, ], ],
使用示例
现在可以直接按需求链式调用:
Log::channel('events')->withAction('用户登录')->alert('用户admin成功登录系统');
生成的JSON日志会包含平级的action字段,不会出现嵌套问题。
内容的提问来源于stack exchange,提问作者silvered.dragon
相关产品推荐
相关产品推荐

