【Laravel】Loggingの設定まわり

出力ログにコンテクスト情報を付与する
LogクラスのRFC5424で定められた各メソッド名(emergency、alert、critical、error、warning、notice、info、debug)は、第2引数にコンテクストを配列で渡すことができる。
例えばユーザーが操作に失敗した場合にそのユーザーのIDを一緒に記録したり、外部APIとの通信においてはアクセス先のURL情報を残すことができる。
また、事前にwithContextメソッドを呼び出しておけば、それ以降のログには全て同じコンテクストを付与することができる。
$user_id = 1;
Log::info('User failed to login.', ['id' => $user_id]);
Log::withContext([
'id' => $user_id
]);
Log::info('User failed to login.');
▼出力結果
[2023-07-02 12:45:02] local.INFO: User failed to login. {"id":1}
[2023-07-02 12:45:02] local.INFO: User failed to login. {"id":1}
2つ目の出力は第2引数にコンテクスト情報を渡していないが、事前にwithContextメソッドを呼び出してコンテクスト情報を定義したことによって、2つ目のログにもコンテクスト情報が付与されている。

出力先ログファイル名を動的に変更する
例えば、複数の外部APIにアクセスするようなアプリケーションを作る際に、接続先ごとに「http://example.com-20xx-xx
」みたいな命名規則でファイルを作りたい。
config/logging.php
で接続先ごとにpathを変えたログチャンネルを定義すれば済む話であるが、プログラム実行中に変数を渡してその変数を元に出力先のパスを動的に変更することはできるのか気になった。
'default' => env('LOG_CHANNEL', 'stack'),
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single'],
'ignore_exceptions' => false,
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
],
]
logging.phpのデフォルト設定は上記のようになっていて、singleチャンネルが使用される場合は/storage/logs/laravel.logファイルにログが追加されていく。
how to customize file name of log in Laravel 8.0? - Stack Overflow
最初はこちらに出てくるようにカスタムなログクラスを作成する必要があるのかと思ったが、調査を継続しているとこちらの回答を見つけた。
Separate log files for each time a job is run laravel - Stack Overflow
Laravelのバージョン8.66.0以降はオンデマンドのログチャンネル機能が追加され、予めlogger.phpで指定しなくてもログ出力時にログの構成を動的に指定できるようになった。
例えば先ほどの呼び出し先URLごとにログを作成したい場合は下記のようになる。
ただし、https://
の文字列など「/」を含めてしまうとパスを認識する妨げとなってエラーとなるので、下記のようにホスト名に留めておく必要がある。
$url = 'example.com';
Log::build([
'driver' => 'single',
'path' => storage_path('logs/' . $url . '_' . date('Y-m') . '.log'),
])->info('Your Log data here !!');
この場合はexample.com_2023-07.log
というファイルが作成され、その中にログが追加されていく。
もう1点の注意としてはdriverは必ず指定しておかないと、ログが出力されないので注意。