Cara membuat log pernyataan SQL di Grails


86

Saya ingin masuk ke konsol atau dalam file, semua pertanyaan yang dilakukan Grails, untuk memeriksa kinerja.

Saya telah mengkonfigurasi ini tanpa hasil.

Ide apa pun akan membantu.


Tidak ada solusi yang memberikan hasil bagi saya. Saya menulis ini hanya untuk memberi tahu semua orang betapa saya putus asa.
Andrea

Jawaban:


131

Pengaturan

datasource {
...
logSql = true
}

di DataSource.groovy (sesuai petunjuk ini ) sudah cukup untuk membuatnya berfungsi di lingkungan saya. Tampaknya bagian dari FAQ sudah usang (mis. Pertanyaan "banyak-ke-banyak kolom mundur") jadi ini mungkin juga sesuatu yang berubah untuk sementara.


6
logSql=truesaja tidak cukup. Hibernate logging juga harus diaktifkan. Lihat jawaban @ Pete.
Jason

2
Saya telah memperhatikan bahwa ini tidak termasuk nilai-nilai yang masuk dalam pernyataan SQL di mana "?" Berada.
Jason

1
Ini berfungsi, tetapi untuk semua kueri. Apakah mungkin juga untuk mencetak sql yang dihasilkan untuk Kriteria tertentu tanpa harus menyetel logSql = true?
Agustus

@Guus bagaimana cara mencetak sql yang dihasilkan untuk Kriteria tertentu?
biniam

@biniam_Ethiopia Sejauh yang saya tahu, ini tidak mungkin. Saya ingin ini juga mengganggu untuk men-debug kelas tertentu dan tidak ingin melihat kueri lain juga.
Agustus

91

Saya merasa lebih berguna untuk melakukan hal berikut, yaitu mengaktifkan logging Hibernate untuk mencatat SQL bersama dengan variabel bind (sehingga Anda dapat melihat nilai yang diteruskan ke panggilan Anda, dan dengan mudah mereplikasi SQL di editor Anda atau sebaliknya).

Di Anda Config.groovy, tambahkan yang berikut ini ke blok log4j Anda:

log4j = {

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

8
Saya telah menggunakan ini berkali-kali. Satu hal yang perlu diperhatikan: mengeluarkan parameter sangat mahal. Saya akan merekomendasikan melakukan ini hanya di kotak dev Anda.
John Gordon

2
Anda juga dapat menambahkan format_sql = trueke dalam hibernateblok Anda DataSource.groovyuntuk keluaran yang diformat dengan baik.
Gregor Petrin

1
Catatan: Ini akan mencatat baik di mana parameter klausa dan nilai kolom diekstrak dari kumpulan hasil kueri. Untuk mencatat hanya di mana parameter klausa, gunakantrace 'org.hibernate.type.BasicBinder'
GreenGiant

Adakah yang tahu padanan untuk grails 3.3.8?
John Little

Untuk beberapa alasan, kueri yang tidak valid secara sintaksis (yang dibuat oleh Hibernate sendiri, sayangnya!) Tidak dicatat - semua kueri lain dicatat ... Mungkinkah ada masalah dengan Hibernate itu sendiri?
Bandara Janaka

32

Untuk grails 3. *

Opsi # 1 tambahkan berikut ini ke logback.groovy

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

atau

Opsi # 2 tambahkan berikut ini ke dataSource di application.yml. Namun pendekatan ini tidak mencatat nilai parameter

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

17

Coba ini:

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

Ini menghindari masalah kinerja pelacakan logging typepaket Hibernate . Ini berfungsi dengan Hibernate 3.6 dan yang lebih baru. Saya mendapatkan ini dari: https://burtbeckwith.com/blog/?p=1604


6

Solusi hanya untuk pengembangan, bukan produksi.

Semua jawaban di atas berfungsi dan benar. Tapi mereka tidak menampilkan kueri lengkap dengan cara yang mudah dibaca manusia. Jika ingin melihat kueri akhir (tanpa?,?), Anda memiliki dua opsi.

A) proxy koneksi jdbc Anda dengan log4jdbc atau p6Spy.

B) melihatnya di tingkat database. Misalnya sangat mudah dilakukan dengan mysql.

Cari tahu di mana Anda general_log_file berada. Log umum aktif jika belum diaktifkan.

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

Sekarang semuanya sudah masuk ke file log Anda. Contoh Mac / linux untuk menunjukkan aliran kueri Anda yang bagus.

tail -f path_to_log_file 

3

Murni untuk referensi saja, tetapi saya menggunakan p6spy untuk mencatat kueri SQL. Ini adalah driver jdbc menengah kecil. Kueri yang tepat dicatat seperti yang akan dikirim ke server (dengan parameter disertakan).

sertakan dalam proyek Anda:

runtime 'p6spy:p6spy:3.0.0'

Ubah driver sumber data Anda:

driverClassName: com.p6spy.engine.spy.P6SpyDriver

Dan url jdbc Anda:

url: jdbc:p6spy:mysql://

Konfigurasikan menggunakan spy.properties (di grails-app / conf).

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

Jangan lupa untuk menonaktifkan ini untuk produksi!


2

Berikutnya bekerja untuk saya:

grails-app / 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-app / 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
// ...

Sumber: http://sergiodelamo.es/log-sql-grails-3-app/


1

Saya tahu ini telah ditanyakan dan dijawab sejak lama. Tetapi saya kebetulan melihat pertanyaan ini dan tidak dapat menahan diri untuk menjawab atau membagikan pendekatan implementasi sql logging kami dalam proyek kami. Semoga bisa membantu.

Saat ini dalam lingkungan pembangunan. Kami menggunakan "log4jdbc Driver Spy" untuk log sql.

Konfigurasi:

Di BuildConfig.groovy Anda: tambahkan dependensi di bawah ini:

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

Dan di Sumber Data Anda atau konfigurasi lain yang terkait: [di mana pun Anda telah menentukan konfigurasi terkait sumber data], Tambahkan:

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'

}

Dari pengalaman pribadi saya, saya merasa cukup berguna dan membantu saat debugging. Juga informasi lebih lanjut dapat Anda temukan di situs ini. https://code.google.com/p/log4jdbc-remix/

Salam Raja


0

Untuk Blok kode tertentu kita juga dapat membuat metode yang menerima penutupan. misalnya.

 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

Jika Anda telah menginstal plugin konsol , Anda bisa mendapatkan sql logging dengan potongan kode kecil ini.

// 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
}

Ini adalah variasi dari banyak solusi di atas, tetapi memungkinkan Anda mengubah nilai pada waktu proses. Dan seperti solusi lain yang mengatasinya logToStdouthanya menampilkan kueri dan bukan nilai mengikat.

Ide itu dicuri dari burtbeckdengan posting yang saya baca beberapa tahun yang lalu yang tidak dapat saya temukan sekarang. Ini telah diedit untuk bekerja dengan grails 3.3.

Teknik serupa dapat digunakan untuk mengaktifkan logging untuk pengujian integrasi tertentu:

class SomeIntegrationSpec extends IntegrationSpec {

    def sessionFactory

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

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

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

Ini akan mengaktifkan sql logging hanya untuk tes dalam satu file ini.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.