Laravel 5 में क्वेरी को कैसे प्राप्त करें? DB :: getQueryLog () खाली एरे लौटना


171

मैं एक क्वेरी के लिए लॉग देखने की कोशिश कर रहा हूं, लेकिन DB::getQueryLog()बस एक खाली सरणी लौटा रहा हूं :

$user = User::find(5);
print_r(DB::getQueryLog());

परिणाम

Array
(
)

मैं इस क्वेरी के लिए लॉग को कैसे देख सकता हूं?


Laravel Debugbar प्रश्नों को लॉग करने के लिए एक महान उपकरण है। इसमें कई अन्य भयानक विशेषताएं भी हैं।
तात्मीडली

जवाबों:


256

डिफ़ॉल्ट रूप से, क्वेरी लॉग Laravel 5 में अक्षम है: https://github.com/laravel/framework/commit/e0abfe5c49d225567cb4dfd56df9ef05cc297x8

आपको कॉल करके क्वेरी लॉग को सक्षम करना होगा:

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 
    }
);  

कुछ सुझाव

1. कई DB कनेक्शन

यदि आपके पास एक से अधिक DB कनेक्शन हैं, तो आपको यह निर्दिष्ट करना होगा कि किस कनेक्शन को लॉग इन करना है

इसके लिए क्वेरी लॉग को सक्षम करने के लिए my_connection:

DB::connection('my_connection')->enableQueryLog();

इसके लिए क्वेरी लॉग पाने के लिए my_connection:

print_r(
   DB::connection('my_connection')->getQueryLog()
);

2. क्वेरी लॉग को कहां सक्षम करें?

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()
        );
    }
}

कारीगरों के आदेशों के लिए एक मिडलवेयर की श्रृंखला नहीं चलेगी, इसलिए सीएलआई निष्पादन के लिए आप artisan.startइवेंट श्रोता में क्वेरी लॉग को सक्षम कर सकते हैं ।

उदाहरण के लिए आप इसे bootstrap/app.phpफ़ाइल में रख सकते हैं

$app['events']->listen('artisan.start', function(){
    \DB::enableQueryLog();
});

3. मेमोरी

लारवेल स्मृति में सभी प्रश्नों को रखता है। इसलिए कुछ मामलों में, जैसे कि बड़ी संख्या में पंक्तियों को सम्मिलित करना, या बहुत सारे प्रश्नों के साथ लंबे समय तक काम करना, यह एप्लिकेशन को अतिरिक्त मेमोरी का उपयोग करने का कारण बन सकता है।

ज्यादातर मामलों में आपको केवल डीबगिंग के लिए क्वेरी लॉग की आवश्यकता होगी, और यदि ऐसा है तो मैं आपको केवल विकास के लिए इसे सक्षम करने की सलाह दूंगा।

if (App::environment('local')) {
    // The environment is local
    DB::enableQueryLog();
}

संदर्भ


6
यदि आपका सिस्टम एक से अधिक db कनेक्शन का उपयोग करता है, तो आपको इसे निर्दिष्ट करना होगा, अन्यथा यह खाली सरणी लौटा सकता है:\DB::connection('myconnection')->enableQueryLog(); print_r(\DB::connection('myconnection')->getQueryLog());
डायना आर।

अपनी टिप्पणी अपने उत्तर @DianaR के रूप में पोस्ट करें।
नरेंद्रसिंह सिसोदिया


यह कैसे सक्षम करने के लिए लॉग लॉग करने के लिए "NameController :: create ();" बयान?
रुबिन रूइज़

2
ध्यान दें कि लारवेल 5.4 में DB::listenकॉलबैक फ़ंक्शन का एक अलग हस्ताक्षर है। यह इस तरह से अधिक है: DB::listen(function($query) { $sql = $query->sql; $bindings = $query->bindings; $time = $query->time; ... });
racl101

45

यदि आप वास्तव में परवाह करते हैं तो त्वरित डिबगिंग उद्देश्यों के लिए वास्तविक क्वेरी (अंतिम एक रन) है:

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" है)


1
हालांकि यह कोड कहां जाता है (5.4) मैंने नियंत्रक, मॉडल की कोशिश की है, और मिडलवेयर में देखा है, यह सुनिश्चित नहीं है कि मुझे डीबी की त्रुटि मिलने से पहले इसे निष्पादित करना कहां है।
ब्लेम

यदि निष्पादन को रोक रही क्वेरी को चलाते समय आपको कोई त्रुटि हो रही है, तो त्रुटि आपको बताएगी कि समस्या क्या है। यदि आप त्रुटियां बंद कर चुके हैं, तो आप त्रुटि लॉग इन / स्टोरेज / लॉग / लार्वेल या ऐसा कुछ देख सकते हैं। (मैं इस समय अपने कंप्यूटर पर नहीं हूं) यदि आप कह रहे हैं कि आपको मेरे उत्तर में मेरे द्वारा सुझाए गए कोड को चलाने में कोई त्रुटि हो रही है, तो सुनिश्चित करें कि आप जहां भी कोड चला रहे हैं, आप DB मुखौटा सहित शामिल हैं। निश्चित नहीं है कि आप क्या करने की कोशिश कर रहे हैं, लेकिन नियंत्रक आपके द्वारा बताए गए विकल्पों में से सबसे सही लगता है। (मैं आमतौर पर अलग-अलग सहायक कक्षाओं में प्रश्न चलाता हूं)
स्कीट जूल

14

इसे मार्गों पर रखें। 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 द्वारा प्रस्तुत, इस पृष्ठ में स्रोत कोड । आपको टिप्पणियों में लार्वा 5.2 के लिए यह फिक्स-कोड मिलेगा।


$ क्वेरी के लिए थोड़ा गंदा, लेकिन +1-> बाइंडिंग और $ क्वेरी-> समय संकेत
पाओलो स्टीफन

साफ! इसका उपयोग करने से दृश्य में परिणाम दिखाई देते हैं, जहां क्वेरी हो रही है!
चार्ल्स वुड

14

आपको पहले क्वेरी लॉगिंग को सक्षम करने की आवश्यकता है

DB::enableQueryLog();

तो आप बस द्वारा क्वेरी लॉग प्राप्त कर सकते हैं:

dd(DB::getQueryLog());

बेहतर होगा कि आप आवेदन शुरू होने से पहले क्वेरी लॉगिंग को सक्षम कर लें, जिसे आप एक प्री-मेलवेयर में कर सकते हैं और उसके बाद एग्जाम क्वेरी को आफ्टरमाडेलवेयर में प्राप्त कर सकते हैं।


11

जाहिरा तौर पर लारवेल 5.2 के साथ, DB::listenकेवल एक ही पैरामीटर में क्लोजर प्राप्त होता है।

इसलिए, यदि आप DB::listenलारवेल 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);
    }
);

पुराने
लावेले के

8

के लिए laravel 5.8 तुम सिर्फ जोड़ने dd या डंप

उदाहरण के लिए:

DB::table('users')->where('votes', '>', 100)->dd();

या

DB::table('users')->where('votes', '>', 100)->dump();

संदर्भ: https://laravel.com/docs/5.8/queries#debugging


5

toSql()इसके बजाय का उपयोग करें get():

$users = User::orderBy('name', 'asc')->toSql();
echo $users;
// Outputs the string:
'select * from `users` order by `name` asc'

2

(Laravel 5.2) मुझे सबसे सरल तरीका यह लगता है कि एसक्यूएल प्रश्नों की निगरानी के लिए एक कोड लाइन जोड़ना है:

\DB::listen(function($sql) {var_dump($sql); });

1

लारवेल 5.2 के साथ स्पष्ट रूप से जारी रखने में , DB में बंद :: सुनो केवल एक ही पैरामीटर प्राप्त करता है ... ऊपर की प्रतिक्रिया: आप इस कोड को मिडलवेयर स्क्रिप्ट में डाल सकते हैं और मार्गों में इसका उपयोग कर सकते हैं।

इसके अतिरिक्त:

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);

कौन सा हिस्सा मिडलवेयर में रखा जाना चाहिए? कौन से मार्गों में?
user1016265

1

यह कोड इस प्रकार है:

  • लारवेल 5.2
  • Mysql डेटाबेस में स्टेटमेंट लॉग करें

यहाँ कोड है, जो @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 स्टेटमेंट डालने की पुनरावृत्ति को रोकती है ।


0

मुझे लगता है कि इस लेख में स्थित उत्तर: 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));
        });
    }
}

0

मान लीजिए आप निम्नलिखित कथनों की SQL क्वेरी को प्रिंट करना चाहते हैं।

$user = User::find(5);

आपको केवल निम्नानुसार करने की आवश्यकता है:

DB::enableQueryLog();//enable query logging

$user = User::find(5);

print_r(DB::getQueryLog());//print sql query

यह Laravel में अंतिम निष्पादित क्वेरी को प्रिंट करेगा।


-3

लार्वा 5 और उसके बाद केवल DB :: getQueryLog () का उपयोग करने के लिए, नहीं करेंगे। इसमें डिफ़ॉल्ट रूप से का मान

 protected $loggingQueries = false;

इसे बदलो

protected $loggingQueries = true; 

लॉगिंग क्वेरी के लिए नीचे दी गई फ़ाइल में।

/vendor/laravel/framework/src/illuminate/Database/Connection.php 

और फिर हम उस DB::getQueryLog()जगह का उपयोग कर सकते हैं जहां आप क्वेरी प्रिंट करना चाहते हैं।


1
vendorफ़ाइलों को संपादित करना एक बुरा विचार है । उन्हें मूल रखा जाना चाहिए।
शुक्शिन.विवान

@ shukshin.ivan हाँ किसी को विक्रेता फ़ाइलों को संपादित नहीं करना चाहिए, लेकिन सटीक क्वेरी प्राप्त करने के लिए हमने इस कोड को कुछ समय के लिए संपादित किया है तो हम इसे वापस बदल सकते हैं।
रूपाली पेमारे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.