「Laravel」のログ保存は、通常はテキスト形式となっております。
ただログの解析を行う場合に、JSON形式で読み取る必要のあるケースが存在します。
そこで「Laravel」が出力するログをJSON形式にする方法をまとめます。
「JSON」形式で保存するフォーマッターの実装
まずは「app/Logging/JsonLogFormatter.php」を作成します。
このケースでは通常のログの他に「Exception」発生時に内容をJSONで保存する事ができます。
<?php
namespace App\Logging;
use Monolog\Formatter\NormalizerFormatter;
/**
* ログファイルをJSON形式で出力するための形式を定義する
* Class JsonLogFormatter
* @package App\Logging
*/
class JsonLogFormatter extends NormalizerFormatter
{
/**
* @var array
*/
private $keys = [
'exception',
];
/**
* JsonLogFormatter constructor.
*
* @param array|\Monolog\LogRecord $record
*
* @return ?string
*/
public function format(array|\Monolog\LogRecord $record): ?string
{
$formatted = parent::format($record);
// Set the default values
$segments = [
'datetime' => $formatted['datetime'],
'level' => $formatted['level_name'],
'message' => $formatted['message']
];
// Set the context values
foreach ($this->keys as $key)
{
if (isset($formatted['context'][$key]))
{
$segments[$key] = $formatted['context'][$key];
}
}
// Set the extra values
$segments['env'] = $formatted['channel'];
$segments['extra'] = $formatted['extra'];
// Return the JSON encoded string
return json_encode($segments).PHP_EOL;
}
}
次に「app/Logging/JsonLogApply.php」を実装します。
<?php
namespace App\Logging;
/**
* ログファイルをJSON形式で出力するためのフォーマッター
* Class JsonLogApply
*
* @package App\Logging
*/
class JsonLogApply
{
public function __invoke($logging): void
{
$jsonFormatter = new JsonLogFormatter();
foreach ($logging->getHandlers() as $handler)
{
$handler->setFormatter($jsonFormatter);
}
}
}
次に「config/logging.php」にある「channels」に以下の内容を追加します。
<?php
use Monolog\Handler\NullHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogUdpHandler;
return [
...省略
'channels' => [
...省略
// For json log
'json' => [
'driver' => 'stack',
'path' => storage_path('logs/' . env("LOG_FILE_NAME", "laravel.log")),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 14,
'channels' => ['bugsnag', 'daily'],
'tap' => [App\Logging\JsonLogApply::class],
],
],
];
上記のファイルの修正が終わりましたら「.env」の「LOG_CHANNEL」を「json」に設定しましょう。
LOG_CHANNEL=json
LOG_SLACK_WEBHOOK_URL=
LOG_FILE_NAME=laravel.log
「Lumen」の場合
なお「Lumen」でプロジェクトを作成している場合、「config/logging.php」はデフォルトで存在しないため、「vendor/laravel/lumen-framework/config」に各種configファイルがあるので、それをコピーして使用しましょう。