Posted at

【Laravel】ログファイルのフォーマットを LTSV に変更する


この記事について

Willgate Advent Calendar 2018」4日目の記事です。

記事が投稿された日付は気にしてはいけない。いいね?


背景

Laravel 5.6 以降 config/logging.php という設定ファイルが追加され、ログまわりの設定方法が変わりました。

Laravel のロギングには内部で Monolog が使われており、目的に応じて Handler(ログ出力先)、Processor(ログに含める情報)、Formatter(ログフォーマット)を設定することができます。

LTSV に関する説明は割愛。


LTSV に整形する Formatter をセットするクラスの作成

今回、LTSV に整形する Formatter には hikaeme/monolog-ltsv-formatter を使用。

composer require hikaeme/monolog-ltsv-formatter

この Formatter を Handler にセットするクラスを作成します。

Formatter をセットする処理を __invoke() メソッドに書きます。

<?php

namespace App\Logging;

use Illuminate\Log\Logger;
use Hikaeme\Monolog\Formatter\LtsvFormatter;

class SetLtsvFormatter
{
public function __invoke(Logger $logger): void
{
foreach ($logger->getHandlers() as $handler) {
/** @see \Hikaeme\Monolog\Formatter\LtsvFormatter::__construct() */
$handler->setFormatter(new LtsvFormatter(
'Y-m-d H:i:s.u',
[
'datetime' => 'datetime',
'level_name' => 'level_name',
'message' => 'message',
'channel' => 'channel',
]
));
}
}
}

LtsvFormatter のコンストラクタの引数は必須ではないのですが、デフォルトの挙動ではいくらか都合が悪かった1ので明示的に指定しています。

参考:


Formatter をセットするクラスを任意の チャンネル に設定

config/logging.phpchannels.*.tap キーを追加して配列形式でクラス名を記述します。

下記の例では single チャンネルに設定しています。


config/logging.php

<?php

use Monolog\Handler\StreamHandler;

return [
// 略
'channels' => [
// 略
'single' => [
'driver' => 'single',
'tap' => [App\Logging\SetLtsvFormatter::class], // この行を追加
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],
// 略
],

];


これで、ログのフォーマットが LTSV になりました。


tinker

>>> Log::channel('single')->info('hoge')

=> null


storage\logs\laravel.log

datetime:2018-12-24 23:50:45.723073 level_name:INFO message:hoge    channel:local






  1. 特にラベル名。 datetimetimelevel_namelevel のように変更されるので混乱を生みました。