Grails'te SQL deyimleri nasıl kaydedilir


86

Performansı kontrol etmek için Grails'in yaptığı tüm sorguları konsolda veya bir dosyada oturum açmak istiyorum.

Ben yapılandırılmış olan bu başarılı olamadı.

Herhangi bir fikir yardımcı olabilir.


Sağlanan çözümlerin hiçbiri benim için işe yaramıyor. Bunu herkesin ne kadar çaresiz olduğumu bilmesini sağlamak için yazıyorum.
Andrea

Yanıtlar:


131

Ayar

datasource {
...
logSql = true
}

DataSource.groovy'de ( bu talimatlara göre) ortamımda çalışması için yeterliydi. Görünüşe göre SSS'nin bazı kısımları güncel değil (örneğin "çoktan çoğa sütunlar" sorusu), bu yüzden bu arada değişen bir şey de olabilir.


6
logSql=truetek başına yeterli değil. Hazırda bekletme günlüğü de açılmalıdır. @ Pete'in cevabına bakın.
Jason

2
Bunun "?" Lerin bulunduğu SQL ifadelerinde yer alan değerleri içermediğini fark ettim.
Jason

1
Bu işe yarar, ancak tüm sorgular için. LogSql = true ayarı yapmak zorunda kalmadan, belirli bir Kriter için oluşturulan sql'yi yazdırmak da mümkün müdür?
Ağustos

@Guus, belirli bir Kriter için oluşturulan sql'yi nasıl yazdırabilirim?
biniam

@biniam_Ethiopia Bildiğim kadarıyla bu mümkün değil. Bunu, belirli sınıflarda hata ayıklamak ve diğer sorguları da görmek istememek için can sıkıcı olmasının yanı sıra istiyorum.
Ekim

91

Bağlama değişkenleri ile birlikte SQL'i günlüğe kaydetmek için Hibernate'in günlüğünü etkinleştirmek olan aşağıdakileri yapmayı daha yararlı buluyorum (böylece çağrılarınıza aktarılan değerleri görebilir ve düzenleyicinizde veya başka bir şekilde SQL'i kolayca çoğaltabilirsiniz).

Gözlerinde farklı Config.groovy, sizin log4j bloğuna aşağıdaki ekleyin:

log4j = {

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

8
Bunu birçok kez kullandım. Unutulmaması gereken bir şey: parametrelerin çıktısını almak çok pahalıdır. Bunu yalnızca geliştirici kutunuzda yapmanızı tavsiye ederim.
John Gordon

2
Ayrıca ekleyebilir format_sql = trueiçine hibernatearamalarınızdan bloğun DataSource.groovybir güzel biçimlendirilmiş çıkış için.
Gregor Petrin

1
Not: Bu, hem yan tümce parametrelerinin hem de sorgu sonuç kümelerinden alınan sütun değerlerinin günlüğünü tutar. Yalnızca yan tümce parametrelerinde oturum açmak için şunu kullanıntrace 'org.hibernate.type.BasicBinder'
GreenGiant

Grails 3.3.8 için eşdeğerini bilen var mı?
John Little

Bazı nedenlerden dolayı, sözdizimsel olarak geçersiz sorgular (ne yazık ki Hibernate tarafından oluşturulan!) Günlüğe kaydedilmez - diğer tüm sorgular günlüğe kaydedilir ... Muhtemelen Hibernate ile ilgili bir sorun var mı?
Janaka Bandara

32

Grails için 3. *

Seçenek 1, aşağıdakileri logback.groovy'ye ekleyin

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

veya

Seçenek # 2, application.yml dosyasındaki dataSource'a aşağıdakileri ekleyin. Ancak bu yaklaşım parametre değerlerini kaydetmez

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

17

Bunu dene:

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

Hazırda Bekletme typepaketini izleme günlüğüne kaydetmenin performans sorunlarını önler . Bu, Hibernate 3.6 ve üstü ile çalışır. Bunu şu adresten aldım: https://burtbeckwith.com/blog/?p=1604


6

Çözüm sadece geliştirme içindir, üretim için değil.

Yukarıdaki tüm cevaplar işe yarıyor ve doğru. Ancak tam sorguyu insan tarafından okunabilir bir şekilde göstermezler. Son (?,? Olmadan) sorguyu görmek istiyorsanız iki seçeneğiniz vardır.

A) jdbc bağlantınızı log4jdbc veya p6Spy ile proxy yapın.

B) buna veritabanı düzeyinde bakın. Örneğin mysql ile yapmak gerçekten çok kolay.

General_log_file dosyanızın nerede olduğunu bulun. Henüz etkinleştirilmemişse genel günlük etkin.

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

Şimdi her şey günlük dosyanıza kaydedilir. Sorgularınızın güzel akışını göstermek için Mac / linux örneği.

tail -f path_to_log_file 

3

Yalnızca referans için saf, ancak SQL sorgularını günlüğe kaydetmek için p6spy kullanıyorum. Küçük bir ara jdbc sürücüsü. Tam sorgu, sunucuya gönderileceği gibi günlüğe kaydedilir (parametreler dahil).

projenize dahil edin:

runtime 'p6spy:p6spy:3.0.0'

Veri kaynağı sürücünüzü değiştirin:

driverClassName: com.p6spy.engine.spy.P6SpyDriver

Ve jdbc url'niz:

url: jdbc:p6spy:mysql://

Spy.properties (grails-app / conf içinde) kullanarak yapılandırın.

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

Bunu üretim için devre dışı bırakmayı unutmayın!


2

Sonraki benim için çalışıyor:

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

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


1

Bunun uzun zaman önce sorulduğunu ve yanıtlandığını biliyorum.Ama bu soruyu gördüm ve projemizde sql loglama uygulama yaklaşımımızı yanıtlamaktan veya paylaşmaktan kendimi alamadım. Umarım yardımı olur.

Şu anda geliştirme ortamında. Sql'yi kaydetmek için "log4jdbc Driver Spy" kullanıyoruz.

Yapılandırma:

BuildConfig.groovy dosyanızda: aşağıdaki bağımlılıkları ekleyin:

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

Ve DataSource'unuzda veya diğer yapılandırmada: [veri kaynağıyla ilgili yapılandırmayı tanımladığınız her yerde], Ekle:

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'

}

Kişisel deneyimlerime göre, hata ayıklarken oldukça yararlı ve yararlı buldum. Ayrıca bu sitede daha fazla bilgi bulabilirsiniz. https://code.google.com/p/log4jdbc-remix/

Saygılarımızla


0

Belirli bir kod bloğu için, kapanışı kabul eden bir yöntem de oluşturabiliriz. Örneğin.

 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

Eğer varsa konsol eklentisi yüklü, bu küçük kod parçacığı ile sql günlüğü alabilirsiniz.

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

Bu, yukarıdaki çözümlerin çoğunun bir varyasyonudur, ancak çalışma zamanında değeri değiştirmenize izin verir. Ve logToStdoutonunla ilgilenen diğer çözümlerde olduğu gibi , bağlama değerlerini değil, yalnızca sorguları gösterir.

Fikir, birkaç yıl önce okuduğum ve şu anda bulamadığım bir gönderiyle bir burtbeck'ten çalındı. Grails ile çalışmak üzere düzenlenmiştir 3.3.

Belirli entegrasyon testleri için günlük kaydını açmak üzere benzer bir teknik kullanılabilir:

class SomeIntegrationSpec extends IntegrationSpec {

    def sessionFactory

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

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

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

Bu, yalnızca bu tek dosyadaki testler için sql günlüğünü etkinleştirir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.