2 votes

Hibernate JPA EntityManager crée un appender log4j supplémentaire ?

J'ai écrit une simple application console qui utilise JPA pour se connecter à une base de données MySQL. La lecture et l'écriture des données fonctionnent, mais la journalisation semble ne pas fonctionner. Chaque instance d'EntityManager que je crée semble ajouter son propre appender log4j à la console. Ainsi, puisque j'ai trois instances EntityManager dans mon application, j'obtiens trois lignes supplémentaires dans ma sortie de console en plus de la "vraie" ligne de sortie de console que je veux. Voici un exemple. La première ligne provient de mon "vrai" appender, les trois autres semblent provenir de l'appender de l'EntityManager :

08:31:58,970 com.electricgearbox.app.ProcessDataItemApp DEBUG main foobar:169 - geoEntityDao.getByCompositeKey took 81 milliseconds 
0 [main] DEBUG foobar  - geoEntityDao.getByCompositeKey took 81 milliseconds 
0 [main] DEBUG foobar  - geoEntityDao.getByCompositeKey took 81 milliseconds 
0 [main] DEBUG foobar  - geoEntityDao.getByCompositeKey took 81 milliseconds 

Voici ma configuration de log4j :

log4j.rootCategory=WARN, mylog

log4j.appender.mylog=org.apache.log4j.ConsoleAppender
log4j.appender.mylog.layout=org.apache.log4j.PatternLayout
log4j.appender.mylog.layout.ConversionPattern=%d{ABSOLUTE} %C %5p %t %c{2}:%L - %m%n

log4j.category.foobar=DEBUG

J'aimerais pouvoir désactiver ce comportement et n'obtenir que les lignes de la console que je souhaite. Je ne semble pas être en mesure de "déchiffrer le code" sur la façon de le faire - toute aide serait appréciée...

Informations complémentaires : Il semble qu'il y ait deux choses qui se passent ici. La première est le paramètre d'additivité de l'appender de log4j, qui est vrai par défaut. En relisant la documentation éparse de log4j (http://logging.apache.org/log4j/1.2/manual.html), je suis tombé sur ceci :

Chaque demande de journalisation activée pour un logger donné sera transmise à tous les appenders de ce logger ainsi qu'aux appenders situés plus haut dans la hiérarchie.

Ce qui n'est PAS mentionné, c'est qu'il le fait apparemment indépendamment des paramètres des enregistreurs situés plus haut dans la hiérarchie.

Ce que cela signifie, ou semble signifier dans mon cas, c'est que bien que mon logger Root soit réglé sur WARN, les appenders qui lui sont attachés par les classes Hibernate sont toujours utilisés par les messages de niveau DEBUG. C'est le contraire de ce que je m'attendais à voir se produire. Je ne sais pas si cela représente un bug dans l'implémentation JPA d'Hibernate 4.0.1 ou simplement un manque de documentation de la part de log4j, ou un problème entre log4j et slf4j (utilisé par Hibernate).

La deuxième chose qui se passe est que chaque fois que vous créez un objet EntityManager, il semble ajouter un appender à votre arbre de logging log4j, donc si vous avez plusieurs EntityManagers, vous obtenez plusieurs messages de logging. Je suis presque sûr qu'il s'agit d'un bogue dans la journalisation d'Hibernate.

Je suis toujours à la recherche d'une explication ou d'un exemple de la façon dont cette "additivité" fonctionne en pratique avec log4j - elle semble fonctionner à l'inverse de ce à quoi je m'attendais d'après la documentation limitée. C'est-à-dire que les appenders semblent être transmis vers le bas de l'arbre de journalisation au lieu que les événements de journalisation soient transmis vers le haut.

Voici ce que j'ai jusqu'à présent pour mon fichier de propriétés log4j (révisé), et cela semble fonctionner :

log4j.rootCategory=WARN, mylog

# logger "root" logs at WARN level to appender "mylog"
log4j.appender.mylog=org.apache.log4j.ConsoleAppender
log4j.appender.mylog.layout=org.apache.log4j.PatternLayout

# Logger "foobar" logs at DEBUG level to appender "bootylog"
log4j.category.foobar=DEBUG, bootylog

log4j.appender.bootylog=org.apache.log4j.ConsoleAppender
log4j.appender.bootylog.layout=org.apache.log4j.PatternLayout
log4j.appender.bootylog.layout.ConversionPattern=%d{ABSOLUTE} %C %5p %t %c{2}:%L - %m%n

# additivity is off
log4j.additivity.foobar=false
log4j.additivity.org.hibernate=false

Cela me donne le résultat suivant, qui est exactement ce que je veux :

11:15:43,622 com.electricgearbox.app.ProcessDataItemApp DEBUG main foobar:152 - geoDataItemDao.create took 5 milliseconds 
11:15:43,624 com.electricgearbox.app.ProcessDataItemApp DEBUG main foobar:166 - geoEntityDao.getByCompositeKey took 2 milliseconds 
11:15:43,626 com.electricgearbox.app.ProcessDataItemApp DEBUG main foobar:159 - dataEntityDao.getDataEntityByFieldCode took 1 milliseconds 

Enfin, je recommande vivement à tous ceux qui ont des problèmes avec log4j d'activer cette option de ligne de commande lorsqu'ils lancent leur application :

-Dlog4j.debug

0voto

Eran Medan Points 12234

En tant que répondu ailleurs Essayez de modifier le niveau de journalisation pour hibernate dans les propriétés de log4j.

par exemple

log4j.logger.org.hibernate=info

0voto

user1071914 Points 889

Il semble qu'il y ait deux choses qui se passent ici. La première est le paramètre d'additivité de l'appender log4j, qui est vrai par défaut. En relisant la documentation éparse de log4j (http://logging.apache.org/log4j/1.2/manual.html), je suis tombé sur ceci :

Chaque demande de journalisation activée pour un logger donné sera transmise à tous les appenders de ce logger ainsi qu'aux appenders situés plus haut dans la hiérarchie.

Ce qui n'est PAS mentionné, c'est qu'il le fait apparemment indépendamment des paramètres des enregistreurs situés plus haut dans la hiérarchie.

Ce que cela signifie, ou semble signifier dans mon cas, c'est que bien que mon logger Root soit réglé sur WARN, les appenders qui lui sont attachés par les classes Hibernate sont toujours utilisés par des messages de niveau DEBUG. C'est le contraire de ce que je m'attendais à voir se produire. Je ne sais pas si cela représente un bug dans l'implémentation JPA d'Hibernate 4.0.1 ou simplement un manque de documentation de la part de log4j, ou un problème entre log4j et slf4j (utilisé par Hibernate).

La deuxième chose qui se passe est que chaque fois que vous créez un objet EntityManager, il semble ajouter un appender à votre arbre de logging log4j, donc si vous avez plusieurs EntityManagers, vous obtenez plusieurs messages de logging. Je suis presque sûr qu'il s'agit d'un bogue dans la journalisation d'Hibernate.

Je suis toujours à la recherche d'une explication ou d'un exemple de la façon dont cette "additivité" fonctionne en pratique avec log4j - elle semble fonctionner à l'inverse de ce à quoi je m'attendais d'après la documentation limitée. C'est-à-dire que les appenders semblent être transmis vers le bas de l'arbre de journalisation au lieu que les événements de journalisation soient transmis vers le haut.

Voici ce que j'ai jusqu'à présent pour mon fichier de propriétés log4j (révisé), et cela semble fonctionner :

log4j.rootCategory=WARN, mylog

# logger "root" logs at WARN level to appender "mylog"
log4j.appender.mylog=org.apache.log4j.ConsoleAppender
log4j.appender.mylog.layout=org.apache.log4j.PatternLayout

# Logger "foobar" logs at DEBUG level to appender "bootylog"
log4j.category.foobar=DEBUG, bootylog

log4j.appender.bootylog=org.apache.log4j.ConsoleAppender
log4j.appender.bootylog.layout=org.apache.log4j.PatternLayout
log4j.appender.bootylog.layout.ConversionPattern=%d{ABSOLUTE} %C %5p %t %c{2}:%L - %m%n

# additivity is off
log4j.additivity.foobar=false
log4j.additivity.org.hibernate=false

Cela me donne le résultat suivant, qui est exactement ce que je veux :

11:15:43,622 com.electricgearbox.app.ProcessDataItemApp DEBUG main foobar:152 - geoDataItemDao.create took 5 milliseconds 
11:15:43,624 com.electricgearbox.app.ProcessDataItemApp DEBUG main foobar:166 - geoEntityDao.getByCompositeKey took 2 milliseconds 
11:15:43,626 com.electricgearbox.app.ProcessDataItemApp DEBUG main foobar:159 - dataEntityDao.getDataEntityByFieldCode took 1 milliseconds 

Enfin, je recommande vivement à tous ceux qui ont des problèmes avec log4j d'activer cette option de ligne de commande lorsqu'ils lancent leur application :

-Dlog4j.debug

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X