初出ではMonologのログ書式でしたが、laravel.logと同じログ書式にするため、tapオプションを利用するよう改稿しました。
laravel.log に何でもいれるな
原則として laravel.log はエラーログだけにしたい。エラーが発生しないなら常に空っぽの状態というのが心休まる。
開発時に Debug ログの出力を仕込んだなら、コミットするときに削除(せめてコメントアウト)してもらいたい。
デバックが必要な事態が起きたときに Debug ログを仕込んで laravel.log を監視しても、全然関係ないデバッグ情報が延々と流れてきては辟易する。
定期実行タスクの実行ログや特定機能のデバッグログは、それぞれの機能や目的に応じてログファイル名を変えて保存したい。……ということで、ログファイル名を指定できるカスタムヘルパー logger_to を作ってみた。
カスタムログの設定
まずは config/logging.php にカスタムログ用のチャンネルを追加する。
ドライバーが single なのは、ログローテションは logrotate でおこなうので、Laravel 側で日付毎ログにするのは余計なお世話だから。
'channels' => [
// logger_to 用カスタムチャンネル
'custom_file' => [
'driver' => 'single',
'path' => storage_path('logs/custom.log'),
'level' => 'debug',
'tap' => [App\Logging\CustomizeLogFormat::class], // カスタムフォーマッタ
],
aa/Logging/CustomizeLogFormat.php
<?php
namespace App\Logging;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;
class CustomizeLogFormat
{
/**
* カスタムログの設定
*
* @param \Monolog\Logger $logger
* @return void
*/
public function __invoke($logger)
{
foreach ($logger->getHandlers() as $handler) {
if ($handler instanceof StreamHandler) {
$handler->setFormatter(new LineFormatter(
null, // デフォルトのフォーマット
null, // デフォルトの日付フォーマット
true, // マルチラインサポート
true // 末尾の改行を削除しない
));
}
}
}
}
カスタムヘルパーを作成
app/Helpers/custom.php
<?php
use Illuminate\Support\Facades\Log;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
if (!function_exists('logger_to')) {
/**
* 名前をつけてログを保存
*
* @param string $fileName : ファイル名(拡張子不要): 区切りでログレベルを指定可
* ログレベル(debug (default), info, notice, warning, error, critical, alert, emergency)
* @param string $message : ログメッセージ
* @param array $context : コンテキスト情報
* @return void
*/
function logger_to(string $fileName, string $message, array $context = []): void
{
if (preg_match('/(.+):(.+)/', $fileName, $m)) {
$fileName = $m[1];
$level = $m[2];
}
$level = $level ?? 'debug';
// ファイル名に拡張子があれば削除して .log に置換
$fileName = preg_replace(['/\.[^.]+$/', '/$/'], ['', '.log'], $fileName);
// カスタムログチャネルを一時的に構築
$logger = Log::build([
'driver' => 'single',
'path' => storage_path('logs/'. $fileName),
'level' => $level,
'tap' => [App\Logging\CustomizeLogFormat::class],
]);
// 指定されたログレベルでメッセージを出力
$logger->{$level}($message, $context);
}
}
オートロード設定
composer.json に追加
// composer.json
"autoload": {
"psr-4": {
"App\\": "app/"
},
"files": [
"app/Helpers/custom.php"
]
}
オートロードのリフレッシュ
composer dump-autoload
使用例
- mydebug.logに変数$userの配列をDEBUG出力
logger_to('mydebug', 'user', $user->toArray())
- mytask.logにタスクの開始をINFO出力
logger_to('mytask:info', 'start task command');