SQL が発行されるたびに Log ファサードを利用して SQLログを書き出してみます。
Laravel のLogファサードの仕様は以下を参照してください。
https://readouble.com/laravel/7.x/ja/logging.html
プロバイダは、AppServiceProvider に登録しても良いですが、今回はカスタムで LogSqlServiceProvider を作成します。
$ php artisan make:provider LogSqlServiceProvider
app/Providers/LogSqlServiceProvider.php が作成されているのを確認します。
config/app.php の providers に LogSqlServiceProvider を登録します。
'providers' => [
...
App\Providers\LogSqlServiceProvider::class,
...
],
app/Providers/LogSqlServiceProvider.php の register() に記述します。
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class AppServiceProvider extends ServiceProvider
{
const SQL_LOG_ENVIROMENT = [
'local',
'development',
];
....
public function register()
{
if (in_array(App::environment(), self::SQL_LOG_ENVIROMENT)) {
DB::listen(function ($query) {
$sql = $query->sql;
for ($i = 0; $i < count($query->bindings); $i++) {
$sql = preg_replace("/\?/", $query->bindings[$i], $sql, 1);
}
Log::channel('sql')->debug("SQL", ["time" => sprintf("%.2f ms", $query->time), "sql" => $sql]);
});
}
}
App::environment() で現在の環境を取得し、任意に設定した SQL_LOG_ENVIROMENT の場合に、ログを書き出します。
環境による設定は、.env の boolean で設定しても良いかも知れません。
config/logging.php で設定でき、デフォルト「storage/logs/larave.log」となります。
Log::debug() の場合、デフォルトで single チャンネルで書き出されるため、Log::channel('チャンネル名')で、SQL用のログを設定します。
(内部的に、Illuminate\Log\LogManagerクラスで、driver() に設定される模様)
'channels' => [
...
'sql' => [
'driver' => 'sql',
'path' => storage_path('logs/sql.log'),
'level' => 'debug',
],
...
],
またロガーは RFC 5424 の以下の8つのログレベルを提供しています。
Logファサードは、最終的にPsr\Log\LoggerInterface を実装した Monolog\Logger を利用しています。