Я пытаюсь просмотреть журнал для запроса, но DB::getQueryLog()
просто возвращает пустой массив:
$user = User::find(5);
print_r(DB::getQueryLog());
Результат
Array
(
)
Как я могу просмотреть журнал для этого запроса?
Я пытаюсь просмотреть журнал для запроса, но DB::getQueryLog()
просто возвращает пустой массив:
$user = User::find(5);
print_r(DB::getQueryLog());
Результат
Array
(
)
Как я могу просмотреть журнал для этого запроса?
По умолчанию журнал запросов отключен в Laravel 5: https://github.com/laravel/framework/commit/e0abfe5c49d225567cb4dfd56df9ef05cc297448
Вам нужно включить журнал запросов, вызвав:
DB::enableQueryLog();
или зарегистрировать прослушиватель событий:
DB::listen(
function ($sql, $bindings, $time) {
// $sql - select * from `ncv_users` where `ncv_users`.`id` = ? limit 1
// $bindings - [5]
// $time(in milliseconds) - 0.38
}
);
Если у вас более одного соединения с БД, вы должны указать, какое соединение с журналом
Чтобы включить журнал запросов для my_connection
:
DB::connection('my_connection')->enableQueryLog();
Чтобы получить журнал запросов для my_connection
:
print_r(
DB::connection('my_connection')->getQueryLog()
);
Для жизненного цикла HTTP-запроса вы можете включить журнал запросов в методе handle
для некоторого BeforeAnyDbQueryMiddleware
middleware, а затем восстановить выполненные запросы в методе terminate
одного и того же промежуточного программного обеспечения.
class BeforeAnyDbQueryMiddleware
{
public function handle($request, Closure $next)
{
DB::enableQueryLog();
return $next($request);
}
public function terminate($request, $response)
{
// Store or dump the log data...
dd(
DB::getQueryLog()
);
}
}
Цепочка промежуточного слоя не будет выполняться для команд artisan, поэтому для выполнения CLI вы можете включить журнал запросов в прослушивателе событий artisan.start
.
Например, вы можете поместить его в файл bootstrap/app.php
$app['events']->listen('artisan.start', function(){
\DB::enableQueryLog();
});
Laravel сохраняет все запросы в памяти. Поэтому в некоторых случаях, например, при вставке большого количества строк или при длительном запуске задания с большим количеством запросов, это может привести к тому, что приложение будет использовать избыточную память.
В большинстве случаев вам понадобится журнал запросов только для отладки, и если это так, я бы рекомендовал вам включить его только для разработки.
if (App::environment('local')) {
// The environment is local
DB::enableQueryLog();
}
Ссылки
Если все, что вас действительно волнует, это фактический запрос (последний запущенный) для целей быстрой отладки:
DB::enableQueryLog();
# your laravel query builder goes here
$laQuery = DB::getQueryLog();
$lcWhatYouWant = $laQuery[0]['query']; # <-------
# optionally disable the query log:
DB::disableQueryLog();
выполните print_r()
на $laQuery[0]
, чтобы получить полный запрос, включая привязки. (в приведенной выше переменной $lcWhatYouWant
переменные будут заменены на ??
)
Если вы используете что-то отличное от основного подключения mysql, вам нужно использовать это вместо:
DB::connection("mysql2")->enableQueryLog();
DB::connection("mysql2")->getQueryLog();
(с вашим именем подключения, где "mysql2")
Поместите это на файл route.php:
\Event::listen('Illuminate\Database\Events\QueryExecuted', function ($query) {
echo'<pre>';
var_dump($query->sql);
var_dump($query->bindings);
var_dump($query->time);
echo'</pre>';
});
Представлено msurguy, исходный код в этой странице. Вы найдете этот исправление для laravel 5.2 в комментариях.
По-видимому, с Laravel 5.2 замыкание в DB::listen
получает только один параметр.
Итак, если вы хотите использовать DB::listen
в Laravel 5.2, вы должны сделать что-то вроде:
DB::listen(
function ($sql) {
// $sql is an object with the properties:
// sql: The query
// bindings: the sql query variables
// time: The execution time for the query
// connectionName: The name of the connection
// To save the executed queries to file:
// Process the sql and the bindings:
foreach ($sql->bindings as $i => $binding) {
if ($binding instanceof \DateTime) {
$sql->bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
} else {
if (is_string($binding)) {
$sql->bindings[$i] = "'$binding'";
}
}
}
// Insert bindings into query
$query = str_replace(array('%', '?'), array('%%', '%s'), $sql->sql);
$query = vsprintf($query, $sql->bindings);
// Save the query to file
$logFile = fopen(
storage_path('logs' . DIRECTORY_SEPARATOR . date('Y-m-d') . '_query.log'),
'a+'
);
fwrite($logFile, date('Y-m-d H:i:s') . ': ' . $query . PHP_EOL);
fclose($logFile);
}
);
Сначала необходимо включить ведение журнала запросов
DB::enableQueryLog();
Было бы лучше, если вы включите ведение журнала запросов перед запуском приложения, что вы можете сделать в BeforeMiddleware, а затем получить выполненные запросы в AfterMiddleware.
Для laravel 5.8 вы просто добавляете dd или дамп.
Пример:
DB::table('users')->where('votes', '>', 100)->dd();
или
DB::table('users')->where('votes', '>', 100)->dump();
Используйте toSql()
вместо get()
следующим образом:
$users = User::orderBy('name', 'asc')->toSql();
echo $users;
// Outputs the string:
'select * from 'users' order by 'name' asc'
(Laravel 5.2) Я считаю, что самый простой способ - просто добавить одну строку кода для мониторинга SQL-запросов:
\DB::listen(function($sql) {var_dump($sql); });
Продолжая По-видимому, с Laravel 5.2 закрытие в DB:: listen получает только один параметр..., ответ выше: вы можете поместить этот код в промежуточное ПО script и использовать его в маршрутах.
Дополнительно:
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$log = new Logger('sql');
$log->pushHandler(new StreamHandler(storage_path().'/logs/sql-' . date('Y-m-d') . '.log', Logger::INFO));
// add records to the log
$log->addInfo($query, $data);
Этот код предназначен для:
Вот код, основанный на ответе @milz:
DB::listen(function($sql) {
$LOG_TABLE_NAME = 'log';
foreach ($sql->bindings as $i => $binding) {
if ($binding instanceof \DateTime) {
$sql->bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
} else {
if (is_string($binding)) {
$sql->bindings[$i] = "'$binding'";
}
}
}
// Insert bindings into query
$query = str_replace(array('%', '?'), array('%%', '%s'), $sql->sql);
$query = vsprintf($query, $sql->bindings);
if(stripos($query, 'insert into `'.$LOG_TABLE_NAME.'`')===false){
$toLog = new LogModel();
$toLog->uId = 100;
$toLog->sql = $query;
$toLog->save();
}
});
Ядро - это строка if(stripos...
, которая предотвращает рекурсию вставки инструкции insert into log
sql в базу данных.
Вы просто выполните следующие шаги, если хотите распечатать запрос, перейдите к поставщику \laravel\framework\src\Illuminate\Database\connection.php
protected $loggingQueries = false;
включить его, поставив true
protected $loggingQueries = true;
и в контроллере u необходимо выполнить
dd(DB::getQueryLog());
вы получите желаемый результат
Я думаю, что ответ находится в этой статье: https://arjunphp.com/laravel-5-5-log-eloquent-queries/
быстро и просто добиться регистрации запросов.
Вам просто нужно добавить к AppServiceProvider
в методе boot
обратный вызов для прослушивания запросов БД:
namespace App\Providers;
use DB;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
DB::listen(function($query) {
logger()->info($query->sql . print_r($query->bindings, true));
});
}
}
Для laravel 5 и далее, используя только DB :: getQueryLog(), не подойдет. По умолчанию в этом значение
protected $loggingQueries = false;
измените его на
protected $loggingQueries = true;
в приведенном ниже файле для регистрации запросов.
/vendor/laravel/framework/src/illuminate/Database/Connection.php
И тогда мы можем использовать DB::getQueryLog()
, где вы хотите напечатать запрос.