第一篇实验,Laravel 中写一个记录 SQL 日志的 mini 调试工具

偶尔会用 Laravel 开发一些小东西玩,不过每次做相关数据库查询代码的时候,看不到某个接口或者页面执行了那些 SQL 会没有安全感(laravel-debugbar 还是有点重),所以一般我都会写一个小工具来实时查看,下面就是小工具的完整代码(在 Laravel5.6 版本之上)。

第一件事是需要写一个 SQL 的日志服务提供者:

<?php

namespace App\Providers;

use App;
use Log;
use DB;
use Illuminate\Support\ServiceProvider;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger;

class SqlLogServiceProvider extends ServiceProvider
{
    public function boot()
    {
        if (App::environment() == 'local') {

            $log = new Logger('sql-log');

            //默认保留十天的sql日志
            $log->pushHandler((new RotatingFileHandler(
                $this->app->storagePath().'/logs/sql.log', 10, Logger::INFO
            ))->setFormatter(new LineFormatter("[%datetime%] %channel%.%level_name%: %message%\n")));

            DB::listen(function ($query) use ($log) {
                $log->info(sprintf("SQL: %s Bindings: %s Time: %f",
                    $query->sql, json_encode($query->bindings), $query->time
                ));
            });
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

注册服务提供者:

'providers' => [
     //...
     App\Providers\SqlLogServiceProvider::class,
],
1
2
3
4

再写一个日志 tail 命令:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App;
use Monolog\Handler\RotatingFileHandler;

class SqlLog extends Command
{
    protected $signature = 'command:sql-log';

    protected $description = 'debug sql log';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        $file = App::storagePath() . '/logs/sql-'. date(RotatingFileHandler::FILE_PER_DAY) . '.log';
        if (file_exists($file)) {
            echo "file: ". $file . "\n";
            echo "sql log: \n\n";
            system("tail -f " . $file);
        } else {
            echo "请运行一次有数据库查询的操作。\n";
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

Kernel.php文件中注册命令:

protected $commands = [
    SqlLog::class,
];
1
2
3

在 Laravel 项目为 local 环境的时候,请求一次带有 SQL 查询的路由,在执行以下命令就可以 tail 日志了:

php artisan command:sql-log
1

效果如下:

Laravel