😸
Laravel SQLログを別ファイルに出力する
SQLのログを出力するチェネルの設定を作る
config/logging.phpに設定を書く
// SQLクエリのログチャンネル
'sqlQueryLog' => [
'driver' => 'custom',
'via' => App\Logging\CreateSqlQueryLogger::class,
'path' => storage_path('logs/sql.log'),
'level' => 'debug', // ログレベル debug 以上だけ出力
'days' => 7, // 7日分のログを保持する
],
SQLクエリ用Monologインスタンスの生成とログの書き込み
$config には、config/logging.php で sqlQueryLog に設定した値が連想配列で入ってきます。
<?php
namespace App\Logging;
use Monolog\Logger;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Formatter\LineFormatter;
class CreateSqlQueryLogger
{
/**
* SQLクエリ用Monologインスタンス生成
* @param array $config
* @return \Monolog\Logger
*/
public function __invoke(array $config)
{
// 引数の $config には、config/logging.php で sqlQueryLog に設定した値が連想配列で入ってくる
/*
'sqlQueryLog' => [
'driver' => 'custom',
'via' => App\Logging\CreateSqlQueryLogger::class,
'path' => storage_path('logs/sql.log'),
'level' => 'debug', // ログレベル debug 以上だけ出力
'days' => 7, // 7日分のログを保持する
],
*/
// 'debug'とかの文字列をMonologが使えるログレベルに変換
$level = Logger::toMonologLevel($config['level']);
// 日ごとにログローテートするハンドラ作成
$hander = new RotatingFileHandler($config['path'], $config['days'], $level);
// 改行コードを出力する&カラのコンテキストを出力しないフォーマッタを設定
$hander->setFormatter(new LineFormatter(null, null, true, true));
// Monologインスタンス作成してハンドラ設定して返却
$logger = new Logger('SQL'); // ロガー名は 'SQL' にした。これはログに出力される
$logger->pushHandler($hander);
return $logger;
}
}
AppServiceProviderに登録
アプリケーション全体で利用したいので、AppServiceProviderに登録
config/logging.phpでログの出力設定の有無をできるようにしておく。
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
// クエリーイベントのリッスン
\DB::listen(function($query) {
// コンフィグでSQLログを出力する設定
if (config('logging.sql.enable') !== true) {
return;
}
// ログに出力するクエリーのログをまとめる
$queryLog = $query->time.' ms -> '.' SQL: '.$query->sql;
if ($query->bindings) {
$queryLog .= "\n".'bindings: '.var_export($query->bindings, true);
}
// sqlQueryLogのチャンネルでSQLを別のログファイルに出力する
\Log::channel('sqlQueryLog')->debug($queryLog);
});
}
}
まとめ
SQLのログファイルを別にする場合
- config/logging.phpに、SQLログ出力設定を書く
- SQLクエリ用のMonologの生成と処理をクラスファイルを作る
- AppServiceProviderに登録する
Discussion