Grails में SQL स्टेटमेंट कैसे लॉग करें


86

मैं कंसोल या एक फ़ाइल में लॉग इन करना चाहता हूं, जो सभी क्वेरीज़ ग्रेल्स करता है, प्रदर्शन की जांच करने के लिए।

मैं कॉन्फ़िगर किया गया था इस सफलता नहीं मिली।

किसी भी विचार से मदद मिलेगी।


मेरे लिए किसी भी समाधान ने काम नहीं दिया। मैं यह सब सिर्फ इस बात के लिए लिख रहा हूं कि मैं कैसे हताश हूं।
एंड्रिया

जवाबों:


131

स्थापना

datasource {
...
logSql = true
}

DataSource.groovy में ( इन निर्देशों के अनुसार ) यह मेरे वातावरण में काम करने के लिए पर्याप्त था। ऐसा लगता है कि अक्सर पूछे जाने वाले प्रश्न पुराने हैं (उदाहरण के लिए "कई-से-कई कॉलम पीछे की ओर" प्रश्न), इसलिए यह कुछ ऐसा भी हो सकता है जो इस बीच बदल गया।


6
logSql=trueअकेला पर्याप्त नहीं है। हाइबरनेट लॉगिंग को भी चालू किया जाना चाहिए। देखिए @ पीट का जवाब।
जेसन

2
मैंने देखा है कि इसमें SQL कथन में जाने वाले मान शामिल नहीं हैं जहाँ "?" हैं।
जेसन

1
यह काम करता है, लेकिन सभी प्रश्नों के लिए। क्या logSql = true सेट किए बिना किसी विशेष मानदंड के लिए जनरेट किए गए sql को प्रिंट करना भी संभव है?
अगस्त

@ जीसस मैं एक विशेष मानदंड के लिए उत्पन्न एसक्यूएल को कैसे प्रिंट कर सकता हूं?
बनिअम

@biniam_Ethiopia जहाँ तक मुझे पता है, यह संभव नहीं है। मैं यह चाहता हूं कि यह कुछ वर्गों के डिबगिंग के लिए भी कष्टप्रद है और अन्य प्रश्नों को भी नहीं देखना चाहता।
अगस्त

91

मुझे निम्न कार्य करना अधिक उपयोगी लगता है, जो है हाइबरनेट के लॉगिंग को SQL को बाइंड चर के साथ लॉग करने के लिए सक्षम करना (ताकि आप अपने कॉल में दिए गए मानों को देख सकें, और अपने संपादक में अन्यथा आसानी से SQL को दोहराएं)।

अपने में Config.groovy, अपने log4j ब्लॉक में निम्नलिखित जोड़ें:

log4j = {

    // Enable Hibernate SQL logging with param values
    trace 'org.hibernate.type'
    debug 'org.hibernate.SQL'
    //the rest of your logging config
    // ...
    }

8
मैंने कई बार इसका इस्तेमाल किया है। एक बात ध्यान दें: परमेट्स को आउटपुट करना बहुत महंगा है। मैं केवल आपके देव बॉक्स पर ऐसा करने की सलाह दूंगा।
जॉन गॉर्डन

2
तुम भी एक अच्छी तरह से स्वरूपित उत्पादन के लिए अपने ब्लॉक format_sql = trueमें जोड़ सकते हैं । hibernateDataSource.groovy
ग्रेगर पेट्रिन

1
नोट: यह दोनों जहाँ क्लोज पैरामीटर और कॉलम वैल्यू को क्वेरी रिजल्ट सेट से निकाला जाएगा वहाँ लॉग करेगा। केवल जहां खंड खंड लॉग करने के लिए, का उपयोग करेंtrace 'org.hibernate.type.BasicBinder'
GreenGiant

किसी को पता है कि अनाज 33.8 के बराबर है?
जॉन लिटिल

किसी कारण से, वाक्यात्मक रूप से अमान्य प्रश्न (हाइबरनेट द्वारा उत्पन्न, दुख की बात है!) लॉग इन नहीं करते हैं - अन्य सभी प्रश्न लॉग हो जाते हैं ... संभवतः हाइबरनेट के साथ एक समस्या?
जनक बंडारा

31

अनाज के लिए 3. *

विकल्प # 1 logback.groovy में निम्न जोड़ें

logger("org.hibernate.SQL", DEBUG, ["STDOUT"], false)
logger("org.hibernate.type.descriptor.sql.BasicBinder", TRACE, ["STDOUT"], false)

या

विकल्प # 2 Application.yml में डेटा स्रोत के लिए निम्नलिखित जोड़ें। हालाँकि यह दृष्टिकोण पैरामीटर मानों को लॉग नहीं करता है

environments:
  local:
    dataSource:
        logSql: true
        formatSql: true

17

इसे इस्तेमाल करे:

log4j = {
   ...
   debug 'org.hibernate.SQL'
   trace 'org.hibernate.type.descriptor.sql.BasicBinder'
}

यह हाइबरनेट typeपैकेज लॉगिंग ट्रेस की प्रदर्शन समस्याओं से बचा जाता है । यह हाइबरनेट 3.6 और इसके बाद के संस्करण के साथ काम करता है। मुझे यह मिला: https://burtbeckwith.com/blog/?p=1604


6

समाधान केवल विकास के लिए है, उत्पादन के लिए नहीं।

काम के ऊपर सभी उत्तर और सही हैं। लेकिन वे एक अच्छे मानव पठनीय तरीके से पूरी क्वेरी नहीं दिखाते हैं। यदि आप अंतिम (किसी भी? के बिना?) क्वेरी देखना चाहते हैं तो आपके पास दो विकल्प हैं।

A) अपने jdbc कनेक्शन को log4jdbc या p6Spy के साथ प्रॉक्सी करें।

बी) इसे डेटाबेस स्तर पर देखें। उदाहरण के लिए वास्तव में mysql के साथ करना आसान है।

पता करें कि आप कहां पर हैं। सक्रिय सामान्य लॉग अगर पहले से सक्रिय नहीं है।

mysql command line> show variables like "%general_log%";
mysql command line> set global general_log = true;

अब सब कुछ आप लॉग फ़ाइल में लॉग इन है। अपने प्रश्नों की अच्छी धारा दिखाने के लिए Mac / linux उदाहरण।

tail -f path_to_log_file 

3

केवल संदर्भ के लिए शुद्ध, लेकिन मैं SQL क्वेरी लॉग करने के लिए p6spy का उपयोग करता हूं। यह एक छोटा मध्यवर्ती jdbc चालक है। सटीक क्वेरी लॉग की गई है क्योंकि यह सर्वर को भेजा जाएगा (शामिल मापदंडों के साथ)।

इसे अपनी परियोजना में शामिल करें:

runtime 'p6spy:p6spy:3.0.0'

अपना डेटा स्रोत ड्राइवर बदलें:

driverClassName: com.p6spy.engine.spy.P6SpyDriver

और आपका jdbc url:

url: jdbc:p6spy:mysql://

जासूसी का उपयोग करके इसे कॉन्फ़िगर करें।

driverlist=org.h2.Driver,com.mysql.jdbc.Driver
autoflush=true
appender=com.p6spy.engine.spy.appender.StdoutLogger
databaseDialectDateFormat=yyyy-MM-dd
logMessageFormat=com.p6spy.engine.spy.appender.MultiLineFormat

उत्पादन के लिए इसे निष्क्रिय करने के लिए मत भूलना!


2

मेरे लिए अगला काम:

grails एप्लिकेशन के अंतर्गत / conf / application.yml

# ...
hibernate:
    format_sql: true # <<<<<<< ADD THIS <<<<<<<
    cache:
        queries: false
        use_second_level_cache: true
# ...
environments:
    development:
        dataSource:
            logSql: true // <<<<<<< ADD THIS <<<<<<<
            dbCreate: create-drop
            url: jdbc:h2:mem:...
# ...

grails एप्लिकेशन के अंतर्गत / conf / logback.groovy

// ...
appender('STDOUT', ConsoleAppender) {
    encoder(PatternLayoutEncoder) {
        pattern = "%level %logger - %msg%n"
    }
}

// >>>>>>> ADD IT >>>>>>>
logger 'org.hibernate.type.descriptor.sql.BasicBinder', TRACE, ['STDOUT']
logger 'org.hibernate.SQL', TRACE, ['STDOUT']
// <<<<<<< ADD IT <<<<<<<

root(ERROR, ['STDOUT'])

def targetDir = BuildSettings.TARGET_DIR
// ...

स्रोत: http://sergiodelamo.es/log-sql-grails-3-app/


1

मुझे पता है कि यह पूछा गया था और लंबे समय तक जवाब दिया गया था। लेकिन मैं सिर्फ इस सवाल को देखने के लिए हुआ और हमारे प्रोजेक्ट में हमारे sql लॉगिंग कार्यान्वयन दृष्टिकोण का जवाब देने या साझा करने में खुद को रोक नहीं सका। आशा है कि यह कुछ मदद की हो।

वर्तमान में यह विकास के माहौल में है। हम sql को लॉग करने के लिए "log4jdbc ड्राइवर स्पाई" का उपयोग कर रहे हैं।

विन्यास:

अपने BuildConfig.groovy में: निर्भरता नीचे जोड़ें:

dependencies {
.....
runtime 'org.lazyluke:log4jdbc-remix:0.2.7'
}

और आपके डेटा स्रोत या अन्य संबंधित कॉन्फ़िगरेशन में: [जहाँ भी आपने डेटा स्रोत संबंधित कॉन्फ़िगरेशन को परिभाषित किया है], जोड़ें:

datasources{
.....
driverClassName: "net.sf.log4jdbc.DriverSpy",
url: "jdbc:log4jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = XXXXX.XX>XXX)(PORT = 1521))) (CONNECT_DATA = (SID = XXXX)(SERVER =DEDICATED)))",
....
}
log4j = {

    info 'jdbc.sqlonly' //, 'jdbc.resultsettable'

}

अपने व्यक्तिगत अनुभव से मैंने डिबगिंग करते समय इसे काफी उपयोगी और उपयोगी पाया। इसके अलावा अधिक जानकारी आप इस साइट में पा सकते हैं। https://code.google.com/p/log4jdbc-remix/

राजा का परवाह


0

कोड के एक विशेष ब्लॉक के लिए हम एक विधि भी बना सकते हैं जो एक क्लोजर को स्वीकार करता है। जैसे।

 static def executeBlockAndGenerateSqlLogs(Closure closure) {
    Logger sqlLogger = Logger.getLogger("org.hibernate.SQL");
    Level currentLevel = sqlLogger.level
    sqlLogger.setLevel(Level.TRACE)
    def result = closure.call()
    sqlLogger.setLevel(currentLevel)
    result }

executeBlockAndGenerateSqlLogs{DomainClazz.findByPropertyName("property value")}

0

यदि आपके पास कंसोल प्लगइन स्थापित है, तो आप इस छोटे कोड स्निपेट के साथ sql लॉगिंग प्राप्त कर सकते हैं।

// grails 2.3
def logger=ctx.sessionFactory.settings.sqlStatementLogger

// grails 3.3  
def logger = ctx.sessionFactory.currentSession.jdbcCoordinator.statementPreparer.jdbcService.sqlStatementLogger

logger.logToStdout=true    
try {
   <code that will log sql queries>
}
finally {
    logger.logToStdout = false
}

यह ऊपर दिए गए कई समाधानों पर भिन्नता है, लेकिन आपको रनटाइम पर मूल्य को ट्विक करने की अनुमति देता है। और इससे निपटने वाले अन्य समाधानों की तरह logToStdoutही प्रश्नों को दिखाता है न कि बंधे मूल्यों को।

इस विचार को कुछ साल पहले पढ़ी गई एक बर्टबेकविथ पोस्ट से चुराया गया था जो मुझे अभी नहीं मिल रहा है। इसे 3.3 के साथ काम करने के लिए संपादित किया गया है।

विशिष्ट एकीकरण परीक्षणों के लिए लॉगिंग चालू करने के लिए एक समान तकनीक का उपयोग किया जा सकता है:

class SomeIntegrationSpec extends IntegrationSpec {

    def sessionFactory

    def setup() {
        sessionFactory.settings.sqlStatementLogger.logToStdout = true
    }

    def cleanup() {
        sessionFactory.settings.sqlStatementLogger.logToStdout = false
    }

    void "some test"() {
           ...
    }

यह इस एक फ़ाइल में सिर्फ परीक्षणों के लिए sql लॉगिंग चालू करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.