2010-12-09 5 views
30

J'ai une application Web qui utilise la classe Log4jConfigurer de Spring pour initialiser ma fabrique de journaux Log4J. Fondamentalement, il initialise Log4J avec un fichier de configuration qui est hors du chemin de la classe.Initialisation de Log4J avec Spring?

Voici la config:

<bean id="log4jInitializer" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" depends-on="sbeHome"> 
    <property name="targetClass" value="org.springframework.util.Log4jConfigurer" /> 
    <property name="targetMethod" value="initLogging" /> 
    <property name="arguments"> 
     <list> 
      <value>#{ MyAppHome + '/conf/log4j.xml'}</value> 
     </list> 
    </property> 
</bean> 

Cependant, je reçois cette erreur au démarrage de l'application:

log4j:WARN No appenders could be found for logger

et des tonnes d'applications Spring messages d'initialisation de contexte sont imprimés sur la console. Je pense que c'est parce que Spring travaille pour initialiser mon application avant qu'elle n'ait une chance d'initialiser mon enregistreur. En cas de problème, j'utilise SLF4J en plus de Log4J.

Y a-t-il un moyen pour que mon Log4jConfigurer soit le premier bean initialisé? ou existe-t-il un autre moyen de résoudre ce problème?

Répondre

47

Vous pouvez configurer votre auditeur Log4j dans le web.xml au lieu du printemps context.xml

<context-param> 
    <param-name>log4jConfigLocation</param-name> 
    <param-value>/WEB-INF/classes/log4j.web.properties</param-value> 
</context-param> 

<listener> 
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> 
</listener> 

Il appartient donc avant le printemps commence.

+0

J'aurais dû mentionner que mon chemin vers le fichier de propriétés log4J provient d'une chaîne JNDI. Comment puis-je fournir cette valeur JNDI à . Si je pouvais le faire, je pense que je suis prêt. – HDave

+4

J'ai trouvé ceci: http://www.coderanch.com/t/362833/Servlets/java/log-ServletContextListener - il montre comment implémenter votre propre écouteur de configuration de log4j qui obtient quelques informations par JNDI – Ralph

+0

J'ai créé mon propre écouteur de contexte de servlet comme ils l'ont fait et tout fonctionne parfaitement. Merci. – HDave

4

Plutôt que de configurer log4j-vous dans le code, pourquoi ne pas pointer juste log4j à votre (personnalisé) l'emplacement du fichier de configuration en ajoutant

-Dlog4j.configuration=.../conf/log4j.xml 

aux propriétés de démarrage de votre serveur?

Encore mieux, déplacez simplement log4j.xml à l'emplacement par défaut - sur le chemin de classe - et laissez log4j se configurer automatiquement.

+4

J'essaie de garder le fichier log4j à l'extérieur de la WAR afin que nous puissions facilement le modifier au besoin pour le diagnostic du problème. En ce qui concerne la propriété JVM, nous n'avons actuellement aucun script de démarrage. Les clients déploient simplement le fichier WAR et y vont. – HDave

+0

Dans certains cas, il faut ajouter le préfixe « file » pour chemin '-Dlog4j.configuration = fichier: conf/log4j.properties' –

+0

b @ Matt préciser s'il vous plaît séquence classpath scanninng – gstackoverflow

8

Notre application autonome nécessitait une SMTPAppender où la configuration de courrier électronique existe déjà dans un fichier de configuration spring et nous ne voulions pas que pour être dupliqués dans le log4j.properties.

J'ai mis les éléments suivants ensemble pour ajouter un appender supplémentaire en utilisant le ressort.

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
    <property name="targetObject"> 
     <bean factory-method="getRootLogger" 
       class="org.apache.log4j.Logger" /> 
    </property> 
    <property name="targetMethod"> 
     <value>addAppender</value> 
    </property> 
    <property name="arguments"> 
     <list> 
      <bean init-method="activateOptions" 
        class="org.apache.log4j.net.SMTPAppender"> 
       <property name="SMTPHost" ref="mailServer" /> 
       <property name="from" ref="mailFrom" /> 
       <property name="to" ref="mailTo" /> 
       <property name="subject" ref="mailSubject" /> 
       <property value="10" name="bufferSize" /> 
       <property name="layout"> 
        <bean class="org.apache.log4j.PatternLayout"> 
         <constructor-arg> 
          <value>%d, [%5p] [%t] [%c] - %m%n</value> 
         </constructor-arg> 
        </bean> 
       </property> 
       <property name="threshold"> 
        <bean class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" 
          id="org.apache.log4j.Priority.ERROR" /> 
       </property> 
      </bean> 
     </list> 
    </property> 
</bean> 

Nous avons également un fichier log4j.properties sur le chemin de classe qui détaille notre FileAppenders régulière.

Je sais que cela peut être trop pour ce que vous avez besoin :)

1

Si vous utilisez la jetée, vous pouvez ajouter classpaths supplémentaires sur une base par application:

http://wiki.eclipse.org/Jetty/Reference/Jetty_Classloading#Adding_Extra_Classpaths_to_Jetty

Cela vous permettra de charger vos propriétés log4 de manière standard (du classpath :)

dans web.xml:

 <listener> 
      <listener-class>org.springframework.web.util.Log4jWebConfigurer</listener-class> 
     </listener> 
     <context-param> 
      <param-name>log4jConfigLocation</param-name> 
      <param-value>classpath:${project.artifactId}-log4j.properties</param-value> 
     </context-param> 

dans la jetée-web.xml:

 <Set name="extraClasspath"> 
      <SystemProperty name="config.home" default="."/>/contexts/log4j 
     </Set> 
1

Vous pouvez utiliser classpath au lieu de chemin hardcoded.Cela fonctionne pour moi

<bean id="log4jInitializer" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" depends-on="sbeHome"> 
    <property name="targetClass" value="org.springframework.util.Log4jConfigurer" /> 
    <property name="targetMethod" value="initLogging" /> 
    <property name="arguments"> 
     <list> 
      <value>classpath:/conf/log4j.xml</value> 
     </list> 
    </property> 
</bean> 
+0

C'était si grand! Merci ! – Hatem

+0

L'utilisation d'une URL avec cette solution est-elle possible? –