Laravel 5.3 - 如何记录页面上的所有查询?

Posted

技术标签:

【中文标题】Laravel 5.3 - 如何记录页面上的所有查询?【英文标题】:Laravel 5.3 - How to log all queries on a page? 【发布时间】:2017-04-30 23:58:43 【问题描述】:

我和我的团队正在开展一个相当大的项目。到处都有查询——在控制器中,在视图中的视图作曲家(延迟加载)中,可能在其他一些服务中也是如此。跟踪这一切变得越来越困难,目前页面加载速度相当慢。

我应该把 \DB::enableQueryLog() 和 \DB::getQueryLog() 放在哪里来记录所有查询并转储它们?基本上我正在寻找在任何查询发生之前发生的代码中的某个地方(放置 enableQueryLog()),并且我正在寻找在视图呈现之后发生的地方(转储 getQueryLog())。

什么是解决这个问题的好方法?

提前致谢。

【问题讨论】:

也许您可以使用 getQueryLog() 方法将查询放在单独的表中 How to get the query executed in Laravel 5 ? DB::getQueryLog returning empty array的可能重复 【参考方案1】:

添加一个在请求完成后执行并记录您的查询的中间件...参见Terminable Middlwares

【讨论】:

到那时查询已经完成,因为在请求完成时会调用可终止的中间件。【参考方案2】:

完美的例子来了:

https://laravel.com/docs/5.3/database#listening-for-query-events

打开 app\Providers\AppServiceProvider.php 并将以下内容添加到Boot() 函数中:

DB::listen(function ($query) 
    var_dump([
        $query->sql,
        $query->bindings,
        $query->time
    ]);
);

【讨论】:

据我了解,这开始监听查询,但我会在哪里转储它们?我看到链接到可终止中间件的其他答案。那么一个好方法是在中间件中实现 terminate() 方法并将其转储到那里? 你可以只记录::info($query->sql) 是的。需要时易于实施。使用\Log::debug('query', [...]),我能够将所有内容记录到 laravel 日志中,并发现正在执行的查询效率低下,而我可以在其中急切加载。谢谢。 它不显示数据库事务在哪里启动和提交。【参考方案3】:

你在使用 mysql 吗?你可以直接跟踪日志。

How to show the last queries executed on MySQL?

或者使用 Laravel 调试栏?

【讨论】:

【参考方案4】:

你可以将它添加到 Providers/AppServiceProvider.php 文件中,并在 laravel 日志文件中使用 tail 进行检查:

tail -f storage/logs/laravel.log

您甚至可以过滤您想要记录的查询。例如,这里我使用的是 Laravel Passport,并且不想记录所有的 oauth 查询。

use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Log;

public function register() 
    if (App::environment('local') && env('APP_URL') == 'http://localhost') 
        Event::listen('Illuminate\Database\Events\QueryExecuted', function ($query) 
            // filter oauth ones
            if (!str_contains($query->sql, 'oauth')) 
                Log::debug($query->sql . ' - ' . serialize($query->bindings));
            
        );
    

【讨论】:

感谢Event::listen,我在DB::listen 的测试环境中遇到错误【参考方案5】:

如果您想打印在您的应用上执行的查询,请执行以下步骤。

第 1 步:转到您的 AppServiceProvider.php 文件。 // 文件路径 App\Providers\AppServiceProvider.php

Step2:制作 boot() 方法并粘贴以下代码。

public function boot() 
        // Log queries
        if (true) 
            \DB::listen(function ($query) 
                \Log::info(
                    $query->sql, $query->bindings, $query->time
                );
            );
        
    

Step3:现在您可以在 lumen.log 或 laravel.log 文件中看到您的查询。文件路径为 laravel_app\storage\logs\laravel.log 或 lumen.log。

享受....

【讨论】:

【参考方案6】:

将此代码放在执行查询的代码上方

\DB::listen(function($sql) 
  die(\Illuminate\Support\Str::replaceArray('?', $sql->bindings, $sql->sql));
);

刚刚修改为可执行查询:

\DB::listen(function ($query) 
   // Enclose in single quotes for string params.
   $bindings = collect($query->bindings)->map(function ($param) 
      if(is_numeric($param)) 
        return $param;
       else 
        return "'$param'";
      
   );

   \Log::info(\Illuminate\Support\Str::replaceArray('?', $bindings->toArray(), $query->sql));
);

【讨论】:

【参考方案7】:

另外还有包:

记录我的查询

https://packagist.org/packages/technoknol/log-my-queries

只需安装并将其添加到中间件即可。它会将所有查询记录在laravel.log 默认日志文件中。

【讨论】:

以上是关于Laravel 5.3 - 如何记录页面上的所有查询?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Laravel 5.3 注销并重定向到登录页面?

在 laravel 5.3 中添加 css 和 js 文件

如何设置 laravel 5.3 注销重定向路径?

我将如何覆盖 Laravel 5.3 sql 语法

找不到路线返回页面 Laravel 5.3

从 Laravel 5.2 更新到 5.3 后,调用数组上的成员函数 all()