답변:
기본적으로 쿼리 로그는 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
}
);
DB 연결이 둘 이상인 경우 로깅 할 연결을 지정해야합니다
하려면에 대한 쿼리 로그를 할 수 있습니다 my_connection
:
DB::connection('my_connection')->enableQueryLog();
쿼리 로그를 얻을하려면 my_connection
:
print_r(
DB::connection('my_connection')->getQueryLog()
);
HTTP 요청 라이프 사이클 handle
의 경우 일부 BeforeAnyDbQueryMiddleware
미들웨어 의 메소드 에서 쿼리 로그를 사용 가능하게 한 다음 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()
);
}
}
미들웨어 체인은 장인 명령에 대해 실행되지 않으므로 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::connection('myconnection')->enableQueryLog(); print_r(\DB::connection('myconnection')->getQueryLog());
DB::listen
콜백 함수의 서명이 다릅니다. : 그것은 더이처럼 DB::listen(function($query) { $sql = $query->sql; $bindings = $query->bindings; $time = $query->time; ... });
당신이 정말로 신경 쓰는 것은 빠른 디버깅 목적의 실제 쿼리 (마지막 실행)입니다.
DB::enableQueryLog();
# your laravel query builder goes here
$laQuery = DB::getQueryLog();
$lcWhatYouWant = $laQuery[0]['query']; # <-------
# optionally disable the query log:
DB::disableQueryLog();
바인딩을 포함하여 전체 쿼리를 얻으려면 print_r()
on $laQuery[0]
을 수행하십시오 . ( $lcWhatYouWant
위 의 변수는 변수를로 대체합니다 ??
)
기본 mysql 연결 이외의 것을 사용하는 경우 대신 다음을 사용해야합니다.
DB::connection("mysql2")->enableQueryLog();
DB::connection("mysql2")->getQueryLog();
( "mysql2"가있는 연결 이름으로)
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>';
});
이 페이지의 소스 코드 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);
}
);
laravel 5.8의 경우 dd 또는 dump 만 추가하십시오 .
전의:
DB::table('users')->where('votes', '>', 100)->dd();
또는
DB::table('users')->where('votes', '>', 100)->dump();
Laravel 5.2로 명백히 계속해서 DB :: listen의 클로저는 단일 매개 변수 만받습니다. 위 응답 .이 코드를 미들웨어 스크립트에 넣고 경로에서 사용할 수 있습니다.
또한 :
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();
}
});
핵심은 sql 문을 데이터베이스 if(stripos...
에 삽입하는 재귀를 방지 하는 줄 insert into log
입니다.
나는이 기사에있는 대답을 생각한다 : https://arjunphp.com/laravel-5-5-log-eloquent-queries/
쿼리 로깅을 달성하기 위해 빠르고 간단합니다.
DB 쿼리를 수신 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()
쿼리를 인쇄 할 위치를 사용할 수 있습니다 .
vendor
파일 을 편집하는 것은 좋지 않습니다 . 그들은 독창적으로 유지되어야합니다.