はじめに
Laravelでログフォーマットにリクエストが定義されているルーティングの区分を追加したかったので、調査しました。
今回はその実装例を共有したいと思います。
ルーティングが定義されているファイルに沿って、”WEB”、”API”、”CONSOLE”の文字列をログフォーマットに追加する想定です。
- routes/web.phpに定義されているルーティングへのリクエスト ⇒ WEB
- routes/api.phpに定義されているルーティングへのリクエスト ⇒ API
- その他 ⇒ CONSOLE
環境
- PHP 8.3.7
- Laravel 11.16.0
プログラムの作成
ルーティングの区分を判定するクラスを作成する
app/Log/RoutingTypeProcessor.phpを作成して下記の内容を記載します。
<?php
declare(strict_types=1);
namespace App\Log;
use Illuminate\Support\Facades\Route;
use Monolog\LogRecord;
use Monolog\Processor\ProcessorInterface;
/**
* Class RoutingTypeProcessor ルーティング区分ログ出力
* @package App\Log
*/
class RoutingTypeProcessor implements ProcessorInterface
{
/**
* @param LogRecord $record
* @return LogRecord
*/
public function __invoke(LogRecord $record): LogRecord
{
$middleware = Route::current()?->gatherMiddleware() ?? [];
$record->extra['routingType'] = match (true) {
in_array('web', $middleware) => 'WEB',
in_array('api', $middleware) => 'API',
default => 'CONSOLE'
};
return $record;
}
}
ログフォーマットのカスタマイズ用クラスを作成する
app/Log/CustomFormatter.phpを作成して下記の内容を記載します。
<?php
declare(strict_types=1);
namespace App\Log;
use Illuminate\Log\Logger;
use Monolog\Formatter\LineFormatter;
/**
* Class CustomFormatter ログフォーマットのカスタマイズ
* @package App\Log
*/
class CustomFormatter
{
public function __invoke(Logger $logger): void
{
foreach ($logger->getHandlers() as $handler) {
$handler->setFormatter(
new LineFormatter(
'[%datetime%][%extra.routingType%]'
. ' %channel%.%level_name%: %message%'
. PHP_EOL,
'Y-m-d H:i:s',
true,
true
)
);
$handler->pushProcessor(new RoutingTypeProcessor());
}
}
}
作成したログフォーマットのカスタマイズ用クラスをログ設定に追加する
さきほど作成したCustomFormatterクラスをconfig/logging.phpの設定に追加します。
例)dailyセクションに追加
'daily' => [
'tap' => [App\Log\CustomFormatter::class], // ★追加
],
動作確認
routes/web.phpに定義されているルーティングへのリクエスト
[2024-10-25 16:23:56][WEB] local.DEBUG: ログメッセージ
routes/api.phpに定義されているルーティングへのリクエスト
[2024-10-25 16:27:34][API] local.DEBUG: ログメッセージ
その他
[2024-10-25 16:28:27][CONSOLE] local.DEBUG: ログメッセージ
まとめ
今回はログフォーマットをカスタマイズしてルーティングの区分を追加する方法を紹介しましたが、
Laravelでログ出力に使われているMonologにはデフォルトでログフォーマットに追加できる情報がいくつかあります。(IPアドレスやメモリの使用量など)
まずは用意されている機能で対応できるか確認するのが良さそうです。
参考:Monologにデフォルトで用意されているログの追加情報