Cómo registrar declaraciones SQL en Grails

86

Quiero iniciar sesión en la consola o en un archivo, todas las consultas que hace Grails, para verificar el rendimiento.

Había configurado esta sin éxito.

Cualquier idea ayudaría.

user2427
fuente
Ninguna de las soluciones me dio resultado. Estoy escribiendo esto solo para que todos sepan lo desesperado que estoy.
Andrea

Respuestas:

131

Ajuste

datasource {
...
logSql = true
}

en DataSource.groovy (según estas instrucciones) fue suficiente para que funcione en mi entorno. Parece que partes de las preguntas frecuentes están desactualizadas (por ejemplo, la pregunta "la pregunta de" muchas a muchas columnas al revés "), por lo que esto también podría ser algo que haya cambiado mientras tanto.

Tomislav Nakic-Alfirevic
fuente
6
logSql=truesolo no es suficiente. El registro de Hibernación también debe estar activado. Vea la respuesta de @ Pete.
Jason
2
He notado que esto no incluye los valores que van en las declaraciones SQL donde están los "?".
Jason
1
Esto funciona, pero para todas las consultas. ¿También es posible imprimir el sql generado para un criterio particular sin tener que establecer logSql = true?
agosto
@Guus ¿cómo puedo imprimir el sql generado para un criterio en particular?
biniam
@biniam_Ethiopia Hasta donde yo sé, esto no es posible. Quiero esto además de que es molesto para depurar ciertas clases y no querer ver otras consultas también.
agosto
91

Me parece más útil hacer lo siguiente, que es habilitar el registro de Hibernate para registrar el SQL junto con las variables de enlace (para que pueda ver los valores pasados ​​a sus llamadas y replicar fácilmente el SQL en su editor o de otra manera).

En tus Config.groovy , agregue lo siguiente a su bloque log4j:

log4j = {

    // Enable Hibernate SQL logging with param values
    trace 'org.hibernate.type'
    debug 'org.hibernate.SQL'
    //the rest of your logging config
    // ...
    }
Pedro
fuente
8
Lo he usado muchas veces. Una cosa a tener en cuenta: generar los parámetros es muy costoso. Recomendaría hacer esto solo en su caja de desarrollo.
John Gordon
2
También puede agregarlo format_sql = trueal hibernatebloque de su DataSource.groovypara obtener una salida bien formateada.
Gregor Petrin
1
Nota: Esto registrará tanto los parámetros de la cláusula where como los valores de columna extraídos de los conjuntos de resultados de la consulta. Para registrar solo los parámetros de la cláusula where, usetrace 'org.hibernate.type.BasicBinder'
GreenGiant
Alguien sabe el equivalente de griales 3.3.8?
John Little
Por alguna razón, las consultas sintácticamente inválidas (generadas por el propio Hibernate, ¡lamentablemente!) No se registran, todas las demás consultas se registran ... ¿Posiblemente un problema con Hibernate en sí?
Janaka Bandara
31

Para griales 3. *

Opción # 1 agregue lo siguiente a logback.groovy

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

o

Opción # 2 agregue lo siguiente a dataSource en application.yml. Sin embargo, este enfoque no registra los valores de los parámetros.

environments:
  local:
    dataSource:
        logSql: true
        formatSql: true
Robert Hutto
fuente
17

Prueba esto:

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

Evita los problemas de rendimiento del registro de seguimiento del typepaquete Hibernate . Esto funciona con Hibernate 3.6 y superior. Obtuve esto de: https://burtbeckwith.com/blog/?p=1604

Jason
fuente
6

La solución es solo para el desarrollo, no para la producción.

Todas las respuestas anteriores funcionan y son correctas. Pero no muestran la consulta completa de una manera agradable y legible por humanos. Si desea ver la consulta final (sin ninguna?,?) Tiene dos opciones.

A) proxy de su conexión jdbc con log4jdbc o p6Spy.

B) míralo a nivel de base de datos. Por ejemplo, realmente fácil de hacer con mysql.

Descubra dónde está general_log_file. Registro general activo si no está activado.

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

Ahora todo está registrado en su archivo de registro. Ejemplo de Mac / Linux para mostrar un buen flujo de consultas.

tail -f path_to_log_file 
Wuestenfuchs
fuente
3

Puro solo como referencia, pero uso p6spy para registrar las consultas SQL. Es un pequeño controlador jdbc intermedio. La consulta exacta se registra como se enviaría al servidor (con los parámetros incluidos).

inclúyelo en tu proyecto:

runtime 'p6spy:p6spy:3.0.0'

Cambie su controlador de fuente de datos:

driverClassName: com.p6spy.engine.spy.P6SpyDriver

Y su URL jdbc:

url: jdbc:p6spy:mysql://

Configúrelo usando spy.properties (en 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

¡No olvide desactivar esto para la producción!

Dennie de Lange
fuente
2

Lo siguiente funciona para mí:

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

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

Eduardo Cuomo
fuente
1

Sé que esto fue preguntado y respondido hace mucho tiempo. Pero simplemente vi esta pregunta y no pude dejar de responder o compartir nuestro enfoque de implementación de registro SQL en nuestro proyecto. Espero que te sea de ayuda.

Actualmente se encuentra en entorno de desarrollo. Estamos usando "log4jdbc Driver Spy" para registrar sql.

Configuración:

En su BuildConfig.groovy: agregue las siguientes dependencias:

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

Y en su fuente de datos u otra configuración relacionada: [donde haya definido la configuración relacionada con la fuente de datos], agregue:

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'

}

Desde mi experiencia personal, lo encontré bastante útil y útil durante la depuración. También puedes encontrar más información en este sitio. https://code.google.com/p/log4jdbc-remix/

Atentamente

Madhu Bose
fuente
0

Para un bloque de código en particular, también podemos crear un método que acepte un cierre. p.ej.

 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")}
Akashsethi
fuente
0

Si tiene instalado el complemento de la consola , puede obtener el registro de SQL con este pequeño fragmento de código.

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

Esta es una variación de muchas de las soluciones anteriores, pero le permite ajustar el valor en tiempo de ejecución. Y al igual que las otras soluciones que se ocupan de logToStdoutello, solo muestra las consultas y no los valores de enlace.

La idea fue robada de una publicación de burtbeckwith que leí hace algunos años y que no puedo encontrar ahora. Ha sido editado para trabajar con grails 3.3.

Se puede utilizar una técnica similar para activar el registro para pruebas de integración específicas:

class SomeIntegrationSpec extends IntegrationSpec {

    def sessionFactory

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

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

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

Esto activará el registro de SQL solo para las pruebas en este archivo.

quemaduras
fuente