Estou tentando visualizar o log para uma consulta, mas DB::getQueryLog()
está retornando uma matriz vazia:
$user = User::find(5);
print_r(DB::getQueryLog());
Resultado
Array
(
)
Como posso visualizar o log desta consulta?
Estou tentando visualizar o log para uma consulta, mas DB::getQueryLog()
está retornando uma matriz vazia:
$user = User::find(5);
print_r(DB::getQueryLog());
Resultado
Array
(
)
Como posso visualizar o log desta consulta?
Respostas:
Por padrão, o log de consulta está desativado no Laravel 5: https://github.com/laravel/framework/commit/e0abfe5c49d225567cb4dfd56df9ef05cc297448
Você precisará habilitar o log de consulta chamando:
DB::enableQueryLog();
ou registre um ouvinte de evento:
DB::listen(
function ($sql, $bindings, $time) {
// $sql - select * from `ncv_users` where `ncv_users`.`id` = ? limit 1
// $bindings - [5]
// $time(in milliseconds) - 0.38
}
);
Se você tiver mais de uma conexão com o banco de dados, deverá especificar qual conexão registrar
Para habilitar o log de consulta para my_connection
:
DB::connection('my_connection')->enableQueryLog();
Para obter o log de consultas para my_connection
:
print_r(
DB::connection('my_connection')->getQueryLog()
);
Para um ciclo de vida de solicitação HTTP, é possível ativar o log de consultas no handle
método de algum BeforeAnyDbQueryMiddleware
middleware e, em seguida, recuperar as consultas executadas no terminate
método do mesmo middleware.
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()
);
}
}
A cadeia de um middleware não será executada para comandos artesanais; portanto, para a execução da CLI, você pode ativar o log de consulta no diretório artisan.start
ouvinte de eventos.
Por exemplo, você pode colocá-lo no bootstrap/app.php
arquivo
$app['events']->listen('artisan.start', function(){
\DB::enableQueryLog();
});
O Laravel mantém todas as consultas na memória. Portanto, em alguns casos, como ao inserir um grande número de linhas ou ter um trabalho de longa execução com muitas consultas, isso pode fazer com que o aplicativo use excesso de memória.
Na maioria dos casos, você precisará do log de consulta apenas para depuração e, se for esse o caso, recomendo que você o habilite apenas para desenvolvimento.
if (App::environment('local')) {
// The environment is local
DB::enableQueryLog();
}
Referências
\DB::connection('myconnection')->enableQueryLog(); print_r(\DB::connection('myconnection')->getQueryLog());
DB::listen
função de retorno de chamada possui uma assinatura diferente. É mais parecido com isto: DB::listen(function($query) { $sql = $query->sql; $bindings = $query->bindings; $time = $query->time; ... });
Se você realmente se importa com a consulta real (a última executada) para fins de depuração rápida:
DB::enableQueryLog();
# your laravel query builder goes here
$laQuery = DB::getQueryLog();
$lcWhatYouWant = $laQuery[0]['query']; # <-------
# optionally disable the query log:
DB::disableQueryLog();
fazer um print_r()
on $laQuery[0]
para obter a consulta completa, incluindo as ligações. (a $lcWhatYouWant
variável acima terá as variáveis substituídas por??
)
Se você estiver usando algo diferente da conexão principal do mysql, precisará usá-los:
DB::connection("mysql2")->enableQueryLog();
DB::connection("mysql2")->getQueryLog();
(com o nome da sua conexão onde "mysql2" está)
Coloque isso no arquivo routes.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>';
});
Enviado por msurguy, código-fonte nesta página . Você encontrará este código de correção para o laravel 5.2 nos comentários.
Você precisa primeiro habilitar o log de consultas
DB::enableQueryLog();
Então você pode obter logs de consulta simplesmente:
dd(DB::getQueryLog());
Seria melhor se você habilitar o log de consultas antes do aplicativo iniciar, o que você pode fazer no BeforeMiddleware e recuperar as consultas executadas no AfterMiddleware.
Aparentemente, com o Laravel 5.2, o fechamento DB::listen
recebe apenas um único parâmetro.
Portanto, se você deseja usar DB::listen
no Laravel 5.2, faça algo como:
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);
}
);
Para o laravel 5.8, basta adicionar dd ou dump .
Ex:
DB::table('users')->where('votes', '>', 100)->dd();
ou
DB::table('users')->where('votes', '>', 100)->dump();
referência: https://laravel.com/docs/5.8/queries#debugging
Use em toSql()
vez de get()
:
$users = User::orderBy('name', 'asc')->toSql();
echo $users;
// Outputs the string:
'select * from `users` order by `name` asc'
Continuando o Aparentemente com o Laravel 5.2, o fechamento no DB :: listen recebe apenas um único parâmetro ... resposta acima: você pode colocar esse código no script Middleware e usá-lo nas rotas.
Além disso:
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);
Este código é para:
Aqui está o código, que é baseado na resposta de @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();
}
});
O núcleo é a if(stripos...
linha, que impede a recursão da inserção da insert into log
instrução sql no banco de dados.
Eu acho que a resposta localizada neste artigo: https://arjunphp.com/laravel-5-5-log-eloquent-queries/
é rápido e simples para obter o log de consultas.
Você apenas tem que adicionar ao AppServiceProvider
no boot
método de uma chamada de retorno para ouvir consultas DB:
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));
});
}
}
Suponha que você deseje imprimir a consulta SQL das seguintes instruções.
$user = User::find(5);
Você só precisa fazer o seguinte:
DB::enableQueryLog();//enable query logging
$user = User::find(5);
print_r(DB::getQueryLog());//print sql query
Isso imprimirá a última consulta executada no Laravel.
Para o laravel 5 em diante, usando apenas DB :: getQueryLog (), não funcionará. Por padrão, o valor de
protected $loggingQueries = false;
mude para
protected $loggingQueries = true;
no arquivo abaixo para registrar a consulta.
/vendor/laravel/framework/src/illuminate/Database/Connection.php
E então podemos usar o DB::getQueryLog()
local em que você deseja imprimir a consulta.
vendor
arquivos. Eles devem ser mantidos originais.