web-dev-qa-db-fra.com

Comment consigner des instructions SQL dans Grails

Je souhaite consigner dans la console ou dans un fichier, toutes les requêtes effectuées par Grails, afin de vérifier les performances.

J'avais configuré cela sans succès.

Toute idée aiderait.

78
user2427

Réglage

datasource {
...
logSql = true
}

dans DataSource.groovy (selon this instructions) suffisait pour que cela fonctionne dans mon environnement. Il semble que certaines parties de la FAQ soient obsolètes (par exemple, la question "plusieurs colonnes à l'envers"), de sorte que cela pourrait également être modifié entre-temps.

125

Je trouve plus utile de faire ce qui suit, c'est-à-dire permettre à la journalisation d'Hibernate de consigner le code SQL avec les variables de liaison (afin que vous puissiez voir les valeurs transmises à vos appels et répliquer facilement le code SQL dans votre éditeur ou autrement).

Dans votre Config.groovy, ajoutez ce qui suit à votre bloc log4j:

log4j = {

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

Pour les Grails 3. *

Option n ° 1 ajoutez les éléments suivants à logback.groovy

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

ou 

L'option n ° 2 ajoute les éléments suivants à dataSource dans le fichier application.yml. Cependant, cette approche ne consigne pas les valeurs des paramètres

environments:
  local:
    dataSource:
        logSql: true
        formatSql: true
31
Robert Hutto

Essaye ça:

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

Cela évite les problèmes de performances liés à la consignation de trace du paquet Hibernate type. Cela fonctionne avec Hibernate 3.6 et supérieur. Je l'ai reçu de: https://burtbeckwith.com/blog/?p=1604

17
Jason

La solution est uniquement pour le développement, pas la production. 

Toutes les réponses ci-dessus fonctionnent et sont correctes. Mais ils ne montrent pas la requête complète de manière lisible pour l’être humain. Si vous voulez voir la dernière (sans?,?) Requête, vous avez deux options.

A) proxy votre connexion jdbc avec log4jdbc ou p6Spy.

B) Regardez au niveau de la base de données. Par exemple, très facile à faire avec mysql.

Découvrez où vous êtes general_log_file. Journal général actif si non activé déjà.

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

Maintenant, tout est enregistré dans votre fichier journal. Exemple Mac/Linux pour montrer le flux Nice de vos requêtes. 

tail -f path_to_log_file 
5
Wuestenfuchs

Pur pour référence seulement, mais j'utilise p6spy pour enregistrer les requêtes SQL. C'est un petit pilote jdbc intermédiaire. La requête exacte est enregistrée telle qu'elle serait envoyée au serveur (avec les paramètres inclus). 

incluez-le dans votre projet:

runtime 'p6spy:p6spy:3.0.0'

Changez votre pilote de source de données: 

driverClassName: com.p6spy.engine.spy.P6SpyDriver

Et votre URL jdbc: 

url: jdbc:p6spy:mysql://

Configurez-le à l'aide de spy.properties (dans 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

N'oubliez pas de désactiver ceci pour la production! 

3
Dennie de Lange

Je sais que cette question a été posée et que ma réponse a été longue. Mais il m'est arrivé de voir cette question et je ne pouvais pas m'empêcher de répondre ou de partager notre approche de mise en œuvre de la journalisation SQL dans notre projet.

Actuellement, il est dans l’environnement de développement . Nous utilisons "log4jdbc Driver Spy" pour journaliser SQL.

Configuration:

Dans votre BuildConfig.groovy: Ajoutez ci-dessous des dépendances:

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

Et dans votre source de données ou toute autre configuration liée: [partout où vous avez défini la configuration liée à la source de données], Ajouter:

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'

}

D'après mon expérience personnelle, je l'ai trouvé très utile et utile lors du débogage . De plus, vous trouverez plus d'informations sur ce site. https://code.google.com/p/log4jdbc-remix/

King Regards

1
Madhu Bose

Pour un bloc de code particulier, nous pouvons également créer une méthode qui accepte une fermeture. par exemple.

 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
user3180264

Suivant fonctionne pour moi:

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

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

0
Eduardo Cuomo

Si vous avez le plugin console installé, vous pouvez obtenir une journalisation SQL avec ce petit extrait de code.

// 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 {
    logToStdout = false
}

Ceci est une variation de la plupart des solutions ci-dessus, mais vous permet de modifier la valeur au moment de l'exécution. Et, tout comme les autres solutions qui traitent de logToStdout, il affiche uniquement les requêtes et non les valeurs de liaison. 

L'idée a été volée dans un billet de burtbeckwith que j'ai lu il y a quelques années et que je ne trouve pas pour le moment. Il a été édité pour fonctionner avec Grails 3.3. 

Une technique similaire peut être utilisée pour activer la journalisation pour des tests d'intégration spécifiques:

class SomeIntegrationSpec extends IntegrationSpec {

    def sessionFactory

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

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

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

Cela activera la journalisation SQL uniquement pour les tests de ce fichier.

0
burns