Come registrare le istruzioni SQL in Grails


86

Voglio accedere alla console o in un file, tutte le query che fa Grails, per controllare le prestazioni.

Avevo configurato questo senza successo.

Qualsiasi idea aiuterebbe.


Nessuna delle soluzioni fornite funziona per me. Sto scrivendo questo solo per far sapere a tutti quanto sono disperato.
Andrea

Risposte:


131

Ambientazione

datasource {
...
logSql = true
}

in DataSource.groovy (secondo queste istruzioni) è stato sufficiente per farlo funzionare nel mio ambiente. Sembra che parti delle FAQ siano obsolete (ad esempio, la domanda "le colonne molti-a-molti all'indietro"), quindi questo potrebbe anche essere qualcosa che è cambiato nel frattempo.


6
logSql=trueda solo non basta. Anche la registrazione di ibernazione deve essere attivata. Vedi la risposta di @ Pete.
Jason

2
Ho notato che questo non include i valori che vanno nelle istruzioni SQL dove si trovano i "?".
Jason

1
Funziona, ma per tutte le domande. È anche possibile stampare lo sql generato per un determinato criterio senza dover impostare logSql = true?
agosto

@Guus come posso stampare lo sql generato per un determinato criterio?
biniam

@biniam_Ethiopia Per quanto ne so, questo non è possibile. Lo voglio così come è fastidioso per il debug di determinate classi e non voglio vedere anche altre query.
agosto

91

Trovo più utile fare quanto segue, che è abilitare la registrazione di Hibernate per registrare l'SQL insieme alle variabili di bind (così puoi vedere i valori passati nelle tue chiamate e replicare facilmente l'SQL nel tuo editor o in altro modo).

Nel tuo Config.groovy, aggiungi quanto segue al tuo blocco log4j:

log4j = {

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

8
L'ho usato molte volte. Una cosa da notare: l'output dei parametri è molto costoso. Consiglierei di farlo solo sulla tua dev box.
John Gordon

2
Puoi anche aggiungere format_sql = truenel hibernateblocco del tuo DataSource.groovyper un output ben formattato.
Gregor Petrin

1
Nota: in questo modo verranno registrati sia i parametri della clausola where che i valori delle colonne estratti dai set di risultati della query. Per registrare solo i parametri della clausola where, utilizzaretrace 'org.hibernate.type.BasicBinder'
GreenGiant

Qualcuno sa l'equivalente per Graal 3.3.8?
John Little

Per qualche ragione, le query sintatticamente non valide (generate dallo stesso Hibernate, purtroppo!) Non vengono registrate - tutte le altre query vengono registrate ... Forse un problema con Hibernate stesso?
Janaka Bandara,

31

Per graal 3. *

L'opzione n. 1 aggiunge quanto segue a logback.groovy

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

o

L'opzione # 2 aggiunge quanto segue a dataSource in application.yml. Tuttavia, questo approccio non registra i valori dei parametri

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

17

Prova questo:

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

Evita i problemi di prestazioni della registrazione della traccia del typepacchetto Hibernate . Funziona con Hibernate 3.6 e versioni successive. Ho ricevuto questo da: https://burtbeckwith.com/blog/?p=1604


6

La soluzione è solo per lo sviluppo, non per la produzione.

Tutte le risposte di cui sopra funzionano e sono corrette. Ma non mostrano la query completa in un bel modo leggibile dall'uomo. Se vuoi vedere la query finale (senza?,?) Hai due opzioni.

A) proxy la tua connessione jdbc con log4jdbc o p6Spy.

B) guardalo a livello di database. Ad esempio davvero facile da fare con mysql.

Scopri dove si trova general_log_file. Registro generale attivo se non già attivato.

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

Ora tutto è registrato nel tuo file di registro. Esempio di Mac / linux per mostrare un bel flusso delle tue query.

tail -f path_to_log_file 

3

Pure solo come riferimento, ma io uso p6spy per registrare le query SQL. È un piccolo driver jdbc intermedio. La query esatta viene registrata come verrebbe inviata al server (con parametri inclusi).

includilo nel tuo progetto:

runtime 'p6spy:p6spy:3.0.0'

Modifica il driver dell'origine dati:

driverClassName: com.p6spy.engine.spy.P6SpyDriver

E il tuo URL jdbc:

url: jdbc:p6spy:mysql://

Configuralo usando spy.properties (in 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

Non dimenticare di disabilitarlo per la produzione!


2

I prossimi lavori per me:

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

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


1

So che è stato chiesto e risposto molto tempo fa, ma mi è capitato di vedere questa domanda e non potevo fermarmi a rispondere o condividere il nostro approccio di implementazione del logging sql nel nostro progetto. Spero che sia di qualche aiuto.

Attualmente è in ambiente di sviluppo. Stiamo usando "log4jdbc Driver Spy" per accedere a sql.

Configurazione:

Nel tuo BuildConfig.groovy: aggiungi le seguenti dipendenze:

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

E nel tuo DataSource o altra configurazione correlata: [ovunque tu abbia definito la configurazione relativa all'origine dati], aggiungi:

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'

}

Dalla mia esperienza personale l'ho trovato abbastanza utile e utile durante il debug. Inoltre ulteriori informazioni si possono trovare in questo sito. https://code.google.com/p/log4jdbc-remix/

Saluti re


0

Per un particolare blocco di codice possiamo anche creare un metodo che accetti una chiusura. per esempio.

 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

Se hai installato il plug-in della console , puoi ottenere la registrazione sql con questo piccolo frammento di codice.

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

Questa è una variazione su molte delle soluzioni precedenti, ma consente di modificare il valore in fase di esecuzione. E proprio come le altre soluzioni che si occupano di logToStdoutesso, mostra solo le query e non i valori di associazione.

L'idea è stata rubata da un burtbeck con un post che ho letto alcuni anni fa e che non riesco a trovare in questo momento. È stato modificato per funzionare con Graal 3.3.

Una tecnica simile può essere utilizzata per attivare la registrazione per test di integrazione specifici:

class SomeIntegrationSpec extends IntegrationSpec {

    def sessionFactory

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

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

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

Questo attiverà la registrazione sql solo per i test in questo file.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.