はじめに
Laravel 5.8のstackドライバを使ったら、Monologコンストラクタの第3引数に指定するProcessorが無視されるので、
コード読んでやり方調べたので残しとく。
どーなってんのか
Illuminate\Log\LogManager::createStackDriver
protected function createStackDriver(array $config)
{
$handlers = collect($config['channels'])->flatMap(function ($channel) {
return $this->channel($channel)->getHandlers();
})->all();
if ($config['ignore_exceptions'] ?? false) {
$handlers = [new WhatFailureGroupHandler($handlers)];
}
return new Monolog($this->parseChannel($config), $handlers);
}
Processor全く使ってない・・・以上
やること
方針
- LogServiceProvider自前で準備。
- LogManager継承して自前のLogManager作成してそこに必要なモノを放り込む
LogServiceProviderの実装
動機は、自前のLogManagerのインスタンスから生成したいからってだけ
LogServiceProvider
class LogServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton('log', function () {
return new LogManager($this->app); // ← これが自分で作ったLogManagerになるだけ
});
}
}
LogManagerの実装
stackドライバの生成方法をマネしてチョット変えるだけ
log channelからProcessorも取って返して、そのままMonologコンストラクタの引数に渡すだけ。
extraとして全部吐かれるから、ログチャンネルごとに細かく出し分けるとかできないけど、
自分の中ではこれで十分なので、この実装。
class LogManager extends \Illuminate\Log\LogManager
{
public function createCustomStackDriver(array $config)
{
$channels = collect($config['channels'])->map(function ($channel) {
$channel = $this->channel($channel);
return [
'handlers' => $channel->getHandlers(),
'processors' => $channel->getProcessors()
];
})->all();
$handlers = Arr::flatten(array_column($channels, 'handlers'));
if ($config['ignore_exceptions'] ?? false) {
$handlers = [new WhatFailureGroupHandler($handlers)];
}
return new Monolog($this->parseChannel($config), $handlers, Arr::flatten(array_column($channels, 'processors')));
}
}
ちなみにここでProcessorを自分で生成すると、思った出力にならないヤツが居たりするので、
Processorの生成自体はカスタムログクラスで生成したものである必要がある。
Arr::flatten(array_column($channels, 'handlers'));
は書き方が周りくどいから何か良い書き方教えて欲しいです。
for文ぐるぐるしてもいいんだけど・・・。
使い方
config/logging.php
以下を追加する
'customStack' => [
'driver' => 'customStack',
'channels' => env('LOG_SLACK_WEBHOOK_URL', '') !== '' ? ['custom', 'slack'] : ['custom'],
],
'custom' => [
'driver' => 'custom',
'via' => \Oga\Logger::class,
'path' => env('LOG_FILE_PATH') ?? storage_path('logs/app.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 14,
],
あとは.envのLOG_CHANNELにcustomStackを指定しとくだけ
おわりに
stackドライバでProcessorの指定を有効にする方法でした。