Saya mencoba melihat log untuk kueri, tetapi DB::getQueryLog()
hanya mengembalikan array kosong:
$user = User::find(5);
print_r(DB::getQueryLog());
Hasil
Array
(
)
Bagaimana saya bisa melihat log untuk kueri ini?
Saya mencoba melihat log untuk kueri, tetapi DB::getQueryLog()
hanya mengembalikan array kosong:
$user = User::find(5);
print_r(DB::getQueryLog());
Hasil
Array
(
)
Bagaimana saya bisa melihat log untuk kueri ini?
Jawaban:
Secara default, log kueri dinonaktifkan di Laravel 5: https://github.com/laravel/framework/commit/e0abfe5c49d225567cb4dfd56df9ef05cc297448
Anda harus mengaktifkan log kueri dengan menelepon:
DB::enableQueryLog();
atau daftarkan pendengar acara:
DB::listen(
function ($sql, $bindings, $time) {
// $sql - select * from `ncv_users` where `ncv_users`.`id` = ? limit 1
// $bindings - [5]
// $time(in milliseconds) - 0.38
}
);
Jika Anda memiliki lebih dari satu koneksi DB, Anda harus menentukan koneksi mana yang akan dicatat
Untuk mengaktifkan log kueri untuk my_connection
:
DB::connection('my_connection')->enableQueryLog();
Untuk mendapatkan log permintaan untuk my_connection
:
print_r(
DB::connection('my_connection')->getQueryLog()
);
Untuk siklus permintaan HTTP, Anda dapat mengaktifkan log kueri dalam handle
metode beberapa BeforeAnyDbQueryMiddleware
middleware dan kemudian mengambil kueri yang dieksekusi dalam terminate
metode middleware yang sama.
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()
);
}
}
Rantai middleware tidak akan berjalan untuk perintah artisan, jadi untuk eksekusi CLI Anda dapat mengaktifkan log kueri di artisan.start
pendengar acara.
Misalnya Anda bisa memasukkannya ke dalam bootstrap/app.php
file
$app['events']->listen('artisan.start', function(){
\DB::enableQueryLog();
});
Laravel menyimpan semua pertanyaan dalam memori. Jadi dalam beberapa kasus, seperti saat memasukkan banyak baris, atau memiliki pekerjaan yang berjalan lama dengan banyak pertanyaan, ini dapat menyebabkan aplikasi menggunakan memori berlebih.
Dalam kebanyakan kasus, Anda akan memerlukan log kueri hanya untuk debugging, dan jika itu yang saya sarankan Anda mengaktifkannya hanya untuk pengembangan.
if (App::environment('local')) {
// The environment is local
DB::enableQueryLog();
}
Referensi
\DB::connection('myconnection')->enableQueryLog(); print_r(\DB::connection('myconnection')->getQueryLog());
DB::listen
fungsi panggilan balik memiliki tanda tangan yang berbeda. Ini lebih seperti ini: DB::listen(function($query) { $sql = $query->sql; $bindings = $query->bindings; $time = $query->time; ... });
Jika yang Anda benar-benar pedulikan adalah permintaan aktual (yang terakhir kali dijalankan) untuk keperluan debugging cepat:
DB::enableQueryLog();
# your laravel query builder goes here
$laQuery = DB::getQueryLog();
$lcWhatYouWant = $laQuery[0]['query']; # <-------
# optionally disable the query log:
DB::disableQueryLog();
lakukan print_r()
on $laQuery[0]
untuk mendapatkan permintaan penuh, termasuk binding. ( $lcWhatYouWant
variabel di atas akan diganti dengan variabel ??
)
Jika Anda menggunakan sesuatu selain koneksi mysql utama, Anda harus menggunakan ini sebagai gantinya:
DB::connection("mysql2")->enableQueryLog();
DB::connection("mysql2")->getQueryLog();
(dengan nama koneksi Anda di mana "mysql2" berada)
Anda harus terlebih dahulu mengaktifkan pencatatan permintaan
DB::enableQueryLog();
Kemudian Anda bisa mendapatkan log kueri hanya dengan:
dd(DB::getQueryLog());
Akan lebih baik jika Anda mengaktifkan pencatatan log sebelum aplikasi dimulai, yang dapat Anda lakukan di BeforeMiddleware dan kemudian mengambil kueri yang dieksekusi di AfterMiddleware.
Letakkan ini di file 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>';
});
Dikirim oleh msurguy, kode sumber di halaman ini . Anda akan menemukan kode perbaikan ini untuk laravel 5.2 dalam komentar.
Rupanya dengan Laravel 5.2, penutupan DB::listen
hanya menerima parameter tunggal.
Jadi, jika Anda ingin menggunakan DB::listen
Laravel 5.2, Anda harus melakukan sesuatu seperti:
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);
}
);
Untuk laravel 5.8 Anda tinggal menambahkan dd atau dump .
Ex:
DB::table('users')->where('votes', '>', 100)->dd();
atau
DB::table('users')->where('votes', '>', 100)->dump();
Gunakan toSql()
bukannya get()
seperti itu:
$users = User::orderBy('name', 'asc')->toSql();
echo $users;
// Outputs the string:
'select * from `users` order by `name` asc'
Dalam melanjutkan Rupanya dengan Laravel 5.2, penutupan di DB :: listen hanya menerima parameter tunggal ... respons di atas: Anda dapat memasukkan kode ini ke dalam skrip Middleware dan menggunakannya dalam rute.
Selain itu:
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);
Kode ini untuk:
Ini adalah kode yang didasarkan pada jawaban @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();
}
});
Inti adalah if(stripos...
garis, yang mencegah rekursi memasukkan insert into log
pernyataan sql ke dalam basis data.
Saya pikir jawabannya ada di artikel ini: https://arjunphp.com/laravel-5-5-log-eloquent-queries/
cepat dan mudah untuk mencapai pencatatan permintaan.
Anda hanya perlu menambahkan ke AppServiceProvider
dalam boot
metode panggilan balik untuk mendengarkan pertanyaan 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));
});
}
}
Misalkan Anda ingin mencetak query SQL dari pernyataan berikut.
$user = User::find(5);
Anda hanya perlu melakukan hal berikut:
DB::enableQueryLog();//enable query logging
$user = User::find(5);
print_r(DB::getQueryLog());//print sql query
Ini akan mencetak kueri yang terakhir dieksekusi di Laravel.
Untuk laravel 5 dan seterusnya hanya menggunakan DB :: getQueryLog (), tidak akan dilakukan. Secara default dalam hal ini nilai
protected $loggingQueries = false;
ubah ke
protected $loggingQueries = true;
dalam file di bawah ini untuk kueri logging.
/vendor/laravel/framework/src/illuminate/Database/Connection.php
Dan kemudian kita bisa menggunakan DB::getQueryLog()
tempat Anda ingin mencetak kueri.
vendor
file. Mereka harus tetap asli.