logging consultas - Cómo registrar sentencias de SQL en Grails




ejemplos complejas (8)

Para Grails 3. *

La opción n. ° 1 agrega lo siguiente a logback.groovy

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

o

La opción n. ° 2 agrega lo siguiente a dataSource en la aplicación.yml. Sin embargo, este enfoque no registra los valores de los parámetros

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

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

Lo configuré sin éxito.

Cualquier idea ayudaría


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

Todas las respuestas anteriores funcionan y son correctas. Pero no muestran la consulta completa en una buena forma humana legible. Si quieres ver la consulta final (¿sin ninguna?,?) Tienes dos opciones.

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

B) mire en el nivel de la base de datos. Por ejemplo, es realmente fácil de hacer con mysql.

Averigüe dónde está general_log_file. Registro general activo si ya 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 una buena secuencia de tus consultas.

tail -f path_to_log_file 

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

Actualmente está en entorno de desarrollo. Estamos utilizando "log4jdbc Driver Spy" para registrar sql.

Configuración:

En su BuildConfig.groovy: agregue dependencias a continuación:

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

Y en su DataSource u otra configuración relacionada: [donde haya definido la configuración relacionada con el origen 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, me pareció bastante útil y útil durante la depuración. También más información que puedes encontrar en este sitio. https://code.google.com/p/log4jdbc-remix/

Atentamente


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

incluirlo en su proyecto:

runtime 'p6spy:p6spy:3.0.0'

Cambie su controlador de fuente de datos:

driverClassName: com.p6spy.engine.spy.P6SpyDriver

Y tu 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 deshabilitar esto para producción!


Ajuste

datasource {
...
logSql = true
}

en DataSource.groovy (según these instrucciones) fue suficiente para hacerlo funcionar en mi entorno. Parece que algunas partes de las preguntas frecuentes están desactualizadas (por ejemplo, la pregunta de "muchas a muchas columnas hacia atrás"), por lo que podría ser algo que haya cambiado mientras tanto.


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

En su 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
    // ...
    }

Para un bloque de código 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")}

MySQL

Obtendrá el mejor rendimiento si olvida la cláusula where y coloca todas las condiciones en la expresión ON.

Creo que esto se debe a que la consulta primero tiene que unirse a las tablas y luego ejecuta la cláusula where en eso, por lo que si puede reducir lo que se requiere para unirse, esa es la forma más rápida de obtener los resultados / hacer la actualización.

Ejemplo

Guión

Tienes una tabla de usuarios. Pueden iniciar sesión con su nombre de usuario o correo electrónico o número de cuenta. Estas cuentas pueden ser activas (1) o inactivas (0). Esta tabla tiene 50000 filas.

Luego tienes una tabla de usuarios para deshabilitar de una sola vez porque descubres que todos han hecho algo malo. Sin embargo, esta tabla tiene una columna con nombres de usuario, correos electrónicos y números de cuenta combinados. También tiene un indicador "has_run" que debe establecerse en 1 (verdadero) cuando se ha ejecutado

Consulta

UPDATE users User
    INNER JOIN
        blacklist_users BlacklistUser
        ON
        (
            User.username = BlacklistUser.account_ref
            OR
            User.email = BlacklistedUser.account_ref
            OR
            User.phone_number = BlacklistUser.account_ref
            AND
            User.is_active = 1
            AND
            BlacklistUser.has_run = 0
        )
    SET
        User.is_active = 0,
        BlacklistUser.has_run = 1;

Razonamiento

Si tuviéramos que unirnos solo en las condiciones OR, esencialmente tendríamos que revisar cada fila 4 veces para ver si debería unirse, y potencialmente devolver muchas más filas. Sin embargo, al darle más condiciones, puede "saltar" muchas filas si no cumplen todas las condiciones al unirse.

Prima

Es más legible. Todas las condiciones están en un solo lugar y las filas para actualizar están en un solo lugar







sql logging grails