Comment configurer la journalisation dans Hibernate 4 pour utiliser SLF4J

hibernation 3.x utilisé pour l'exploitation forestière. Hibernation 4.x utilise . J'écris une application autonome qui utilise Hibernate 4, et SLF4J pour la journalisation.

comment configurer Hibernate pour se connecter à SLF4J?

si ce n'est pas possible, Comment puis-je configurer la journalisation D'Hibernate?

Hibernate 4.1 manuel "1519110920 la section" enregistrement commence avec l'avertissement qu'il est ...

complètement périmé. Hibernate utilise la journalisation JBoss à partir de 4.0. Cela sera documenté au fur et à mesure que nous migrerons ce contenu vers le Guide du développeur.

... continue à parler de SLF4J, et est donc inutile. Ni le guide de démarrage ni le guide du développeur parler de l'exploitation forestière à tous. La migration non plus guide .

j'ai cherché de la documentation sur jboss-logging lui-même, mais je n'en ai pas trouvé du tout. La page de GitHub est muette , et la page de JBoss community projects ne mentionne même pas jboss-logging. Je me suis demandé si le bug tracker du projet th pourrait avoir des problèmes concernant la fourniture de documentation, mais ce n'est pas le cas.

la bonne nouvelle est que lors de l'utilisation Hibernate 4 à l'intérieur d'un serveur d'application, tel que JBoss AS7, la journalisation est en grande partie prise en charge pour vous. Mais comment puis-je configurer dans une application autonome?

102
demandé sur Raedwald 2012-07-25 02:02:26

11 réponses

Look to https://github.com/jboss-logging/jboss-logging/blob/master/src/main/java/org/jboss/logging/LoggerProviders.java :

static final String LOGGING_PROVIDER_KEY = "org.jboss.logging.provider";

private static LoggerProvider findProvider() {
    // Since the impl classes refer to the back-end frameworks directly, if this classloader can't find the target
    // log classes, then it doesn't really matter if they're possibly available from the TCCL because we won't be
    // able to find it anyway
    final ClassLoader cl = LoggerProviders.class.getClassLoader();
    try {
        // Check the system property
        final String loggerProvider = AccessController.doPrivileged(new PrivilegedAction<String>() {
            public String run() {
                return System.getProperty(LOGGING_PROVIDER_KEY);
            }
        });
        if (loggerProvider != null) {
            if ("jboss".equalsIgnoreCase(loggerProvider)) {
                return tryJBossLogManager(cl);
            } else if ("jdk".equalsIgnoreCase(loggerProvider)) {
                return tryJDK();
            } else if ("log4j".equalsIgnoreCase(loggerProvider)) {
                return tryLog4j(cl);
            } else if ("slf4j".equalsIgnoreCase(loggerProvider)) {
                return trySlf4j();
            }
        }
    } catch (Throwable t) {
    }
    try {
        return tryJBossLogManager(cl);
    } catch (Throwable t) {
        // nope...
    }
    try {
        return tryLog4j(cl);
    } catch (Throwable t) {
        // nope...
    }
    try {
        // only use slf4j if Logback is in use
        Class.forName("ch.qos.logback.classic.Logger", false, cl);
        return trySlf4j();
    } catch (Throwable t) {
        // nope...
    }
    return tryJDK();
}

ainsi les valeurs possibles pour org.jboss.logging.provider sont: jboss , jdk , log4j , slf4j .

si vous ne définissez pas org.jboss.logging.provider il essaie jboss, puis log4j, puis slf4j (seulement si logback utilisé) et fallback vers jdk.

j'utilise slf4j avec logback-classic :

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.0.13</version>
        <scope>${logging.scope}</scope>
    </dependency>

et tout fonctionne bien!

UPDATE certains utilisateurs utilisent dans L'application très principale.java:

static { //runs when the main class is loaded.
    System.setProperty("org.jboss.logging.provider", "slf4j");
}

mais pour les solutions à base de conteneur cela ne fonctionne pas.

UPDATE 2 ceux qui pensent gérer Log4j avec SLF4J pour jboss-logging ce n'est pas exactement ainsi. jboss-logging utilise directement Log4j sans SLF4J!

51
répondu gavenkoa 2015-12-02 15:26:56

pour que SLF4J fonctionne avec la journalisation de JBoss sans Logback car le backend nécessite l'utilisation d'une propriété de système org.jboss.logging.provider=slf4j . La tactique log4j-over-slf4j ne semble pas fonctionner dans ce cas car la journalisation retombera sur JDK si ni Logback ni log4j n'est pas réellement présent dans classpath.

c'est un peu gênant et pour faire fonctionner autodetection vous avez vu que classloader contient au moins ch.qos.logback.classic.Logger de logback-classic ou org.apache.log4j.Hierarchy de log4j pour le truc de l'JBoss Journalisation de ne pas retomber à la journalisation JDK.

la magie est interprétée à org.jboss.logging.LoggerProviders

mise à jour: la prise en charge du chargeur de Service a été ajoutée afin qu'il soit possible d'éviter les problèmes d'autodétection en déclarant META-INF/services/org.jboss.logging.LoggerProvider (avec org.jboss.logging.Slf4jLoggerProvider comme valeur). Il semble qu'il y ait aussi un support log4j2 ajouté.

25
répondu Tuomas Kiviaho 2014-09-10 05:33:31

Inspiré par Leif Hypoport post , c'est la façon dont je "plié" Hibernate 4 retour à la slf4j:

supposons que vous utilisez Maven.

  • ajouter org.slf4j:log4j-over-slf4j comme une dépendance à votre pom.xml
  • utilisez la commande mvn dependency:tree , assurez-vous que aucun des artefacts que vous utilisez depende sur slf4j:slf4j (pour être précis, aucun artefact ne doit avoir compiler portée de dépendance ou de runtime la portée de la dépendance slf4j:slf4j )

Background: Hibernate 4.x dépend de l'artefact org.jboss.logging:jboss-logging . De façon transitoire, cet artéfact a une fournie dépendance de portée sur l'artéfact slf4j:slf4j .

comme nous avons maintenant ajouté le org.slf4j:log4j-over-slf4j artefact, org.slf4j:log4j-over-slf4j imite le slf4j:slf4j artefact. Par conséquent tout ce que JBoss Logging logs va maintenant passer par slf4j.

disons que vous utilisez Logback comme support de votre journalisation. Voici un échantillon pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    ....
    <properties>
        ....
        <slf4j-api-version>1.7.2</slf4j-api-version>
        <log4j-over-slf4j-version>1.7.2</log4j-over-slf4j-version>
        <jcl-over-slf4j-version>1.7.2</jcl-over-slf4j-version> <!-- no problem to have yet another slf4j bridge -->
        <logback-core-version>1.0.7</logback-core-version>
        <logback-classic-version>1.0.7</logback-classic-version>
        <hibernate-entitymanager-version>4.1.7.Final</hibernate-entitymanager-version> <!-- our logging problem child -->
    </properties>

    <dependencies>
            <!-- begin: logging-related artifacts .... -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j-api-version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>jcl-over-slf4j</artifactId>
                <version>${jcl-over-slf4j-version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>log4j-over-slf4j</artifactId>
                <version>${log4j-over-slf4j-version}</version>
            </dependency>   
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-core</artifactId>
                <version>${logback-core-version}</version>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>${logback-classic-version}</version>
            </dependency>
            <!-- end: logging-related artifacts .... -->

            <!-- begin: some artifact with direct dependency on log4j:log4j ....  -->
            <dependency>
            <groupId>org.foo</groupId>
                <artifactId>some-artifact-with-compile-or-runtime-scope-dependency-on-log4j:log4j</artifactId>
                <version>${bla}</version>
                <exclusions>
                    <exclusion>
                        <groupId>log4j</groupId>
                        <artifactId>log4j</artifactId>
                    </exclusion>
                </exclusions>   
            </dependency>
            <!-- begin: some artifact with direct dependency on log4j:log4j ....  -->

            <!-- begin: a hibernate 4.x problem child........... -->
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-entitymanager</artifactId>
                <version>${hibernate-entitymanager-version}</version>
            </dependencies>
            <!-- end: a hibernate 4.x problem child........... -->
    ....
</project>

sur votre chemin de classe, avoir un logback.xml , comme celui-ci situé dans src/main/java :

<!-- begin: logback.xml -->
<configuration>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
</appender> 

<logger name="org.hibernate" level="debug"/>

<root level="info">
    <appender-ref ref="console"/>
</root>

</configuration>
<!-- end: logback.xml -->

certains composants peuvent vouloir avoir accès à logback.xml à L'Heure de démarrage de JVM pour une journalisation correcte, par exemple le Plugin Jetty Maven. Dans ce cas, ajoutez un système Java logback.configurationFile=./path/to/logback.xml à votre commande (par exemple mvn -Dlogback.configurationFile=./target/classes/logback.xml jetty:run ).

dans le cas où vous obtenez encore la sortie" raw "stdout Hibernate de la console (comme Hibernate: select ... ), puis la question de débordement de la pile " désactiver la journalisation de l'hibernation vers la console " peut s'appliquer.

11
répondu Abdull 2017-05-23 12:34:35

tout d'abord, vous réalisez que SLF4J n'est pas un droit de bibliothèque de journalisation, c'est un enveloppeur de journalisation. Il lui-même ne Note rien, il délègue simplement pour "soutenir".

pour" configurer " JBoss-logging il vous suffit d'ajouter n'importe quel cadre de journalisation que vous voulez utiliser sur votre classepath (avec JBoss-logging) et JBoss-logging comprend le reste.

j'ai créé un guide axé sur L'hibernation pour la configuration de journalisation de JBoss: http://docs.jboss.org/hibernate/orm/4.3/topical/html/logging/Logging.html

7
répondu Steve Ebersole 2015-12-15 16:35:54

J'utilise le noyau D'hibernation 4.1.7.Finale + printemps 3.1.2.La mise en application autonome. J'ai ajouté Log4j 1.2.17 à mes dépendances et il semble que, comme JBoss Logging logs directement sur log4j si disponible et Spring utilise la journalisation Commons, witch utilise aussi Log4j si disponible, toute la journalisation peut être configurée via Log4J.

voici ma liste de dépendances pertinentes:

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>4.1.7.Final</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>3.1.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>3.1.2.RELEASE</version>
</dependency>
3
répondu Stefan Scheidt 2012-10-18 09:03:04

Hibernate 4.3 a documentation sur le contrôle de la org.jboss.logging :

  • il recherche le chemin de classe pour un logging provider . Il recherche slf4j après avoir cherché log4j. Donc, en théorie, s'assurer que votre chemin de classe (WAR) n'inclut pas log4j et inclut l'API slf4j et un back-end devrait fonctionner.

  • comme dernier resort vous pouvez définir la propriété du système org.jboss.logging.provider à slf4j .


malgré les affirmations de la documentation, org.jboss.logging a insisté pour essayer d'utiliser log4j, malgré l'absence de log4j et la présence de SLF4J, ce qui a donné le message suivant dans mon fichier Tomcat log ( /var/log/tomcat/catalina.out ):

 log4j:WARN No appenders could be found for logger (org.jboss.logging).
 log4j:WARN Please initialize the log4j system properly.
 log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

j'ai dû suivre la suggestion de la réponse par dasAnderl ausMinga et comprend le pont log4j-over-slf4j .

3
répondu Raedwald 2017-05-23 12:10:10

j'utilise maven et j'ai ajouté la dépendance suivante:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.6.6</version>
</dependency>

puis, j'ai créé un log4j.properties fichiers dans /src/main/resources :

# direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
# set log levels
log4j.rootLogger=warn

cela le placera à la racine de votre .jar . Il fonctionne comme un charme...

2
répondu Jérôme Verstrynge 2012-08-17 20:02:45

donc, je l'ai eu dans mon projet. hibernate 4, slf4j, logback. mon projet est gradle, mais devrait être le même pour maven.

Abdull a raison. Là où il N'a pas raison, c'est que vous N'avez pas à supprimer slf4j des dépendances.

  1. inclure les compiler portée:

    org.slf4j: slf4j-api

    org.slf4j:log4j-sur-slf4j

    p.ex. pour le retour (ch.la qualité de service.logback:logback-classique, ch.la qualité de service.logback: logback-core: 1.0.12)

  2. exclure complètement les libs log4j des dépendances

résultat: mise en veille prolongée journaux via slf4j à logback. bien sûr, vous devriez être en mesure d'utiliser l'implémentation de log différent de logback

pour être sûr qu'aucun log4j n'est présent, vérifiez vos lib sur classpath ou web-inf/lib pour les fichiers de guerre.

bien sûr, vous avez mis les loggers dans logback.xml par exemple:

<logger name="org.hibernate.SQL" level="TRACE"/>

2
répondu dasAnderl ausMinga 2013-10-18 09:08:20

j'ai eu un problème pour faire fonctionner hibernate 4 logging avec weblogic 12c et log4j. La solution est de mettre ce qui suit dans votre application weblogic.xml:

<prefer-application-packages>
    <package-name>org.apache.log4j.*</package-name>
    <package-name>org.jboss.logging.*</package-name>
</prefer-application-packages>
1
répondu gozer 2016-08-23 22:46:22

à tous ceux qui pourraient faire face au même problème que moi. Dans le cas où vous avez essayé toutes les autres solutions expliquées ici et ne voyez toujours pas hibernate logging travailler avec votre slf4j, cela pourrait être parce que vous utilisez un conteneur qui a dans ses bibliothèques de dossiers le JBoss-logging.pot. Cela signifie qu'il est préchargé avant même que vous puissiez configurer n'importe quelle configuration pour l'influencer. Pour éviter ce problème dans weblogic vous pouvez spécifier dans le fichier de weblogic application.xml dans ton oreille/META-INF à préférer la bibliothèque chargée de l'application. il devrait y avoir un mécanisme similaire pour d'autres serveurs conteneurs. Dans mon cas, je devais ajouter:

<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-application xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-application" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/javaee_5.xsd http://xmlns.oracle.com/weblogic/weblogic-application http://xmlns.oracle.com/weblogic/weblogic-application/1.5/weblogic-application.xsd">
   <wls:prefer-application-packages>    
       <!-- logging -->
       <wls:package-name>org.slf4j.*</wls:package-name>
       <wls:package-name>org.jboss.logging.*</wls:package-name>             
   </wls:prefer-application-packages>
   <wls:prefer-application-resources>
        <wls:resource-name>org/slf4j/impl/StaticLoggerBinder.class</wls:resource-name>
    </wls:prefer-application-resources>     
</wls:weblogic-application>
0
répondu Massimo 2017-12-08 13:19:31

avez-vous essayer ceci:

- slf4j-log4j12.jar dans le cas de Log4J. Voir la documentation SLF4J pour plus de détails. Pour utiliser Log4j vous aurez également besoin de placer un log4j.fichier de propriétés dans votre classpath. Un exemple de fichier de propriétés est distribué avec Hibernate dans le répertoire src/

il suffit d'ajouter ces bocaux et propriétés ou log4j xml dans le chemin de classe

-2
répondu Avihai Marchiano 2012-07-24 22:21:08