2010-12-09 20 views
30

Tengo una aplicación web que usa la clase Log4jConfigurer de Spring para inicializar la fábrica de registros Log4J. Básicamente inicializa Log4J con un archivo de configuración que está fuera de la ruta de clases.Inicializando Log4J con Spring?

Aquí está el 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> 

Sin embargo, me sale este error en el inicio de la aplicación:

log4j:WARN No appenders could be found for logger

y un montón de mensajes de inicialización de contexto de aplicación de primavera se imprimen en la consola. Creo que esto se debe a que Spring está trabajando para inicializar mi aplicación antes de que tenga la oportunidad de inicializar mi registrador. En caso de que importe, estoy usando SLF4J encima de Log4J.

¿Hay alguna forma de que pueda obtener mi Log4jConfigurer para ser el primer bean inicializado? o hay alguna otra forma de resolver esto?

Respuesta

47

podría configurar su oyente Log4J en el web.xml en lugar del resorte-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> 

lo que es hasta antes del inicio de la primavera.

+0

Debería haber mencionado que mi ruta al archivo de propiedades log4J proviene de una cadena JNDI. ¿Cómo puedo proporcionar ese valor JNDI a . Si pudiera hacer eso, creo que ya estoy listo. – HDave

+4

He encontrado esto: http://www.coderanch.com/t/362833/Servlets/java/log-ServletContextListener - muestra cómo implementar su propio oyente de configuración de log4j que obtiene información de JNDI – Ralph

+0

Creé mi propio Servidor de contexto de servlet como lo hicieron y todo funciona perfectamente. Gracias. – HDave

4

En lugar de la configuración de log4j a sí mismo en el código, ¿por qué no simplemente apunte a su log4j (personalizado) la ubicación del archivo de configuración mediante la adición de

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

a propiedades de inicio de su servidor?

Mejor aún, solo mueva log4j.xml a la ubicación predeterminada - en classpath - y deje que log4j se configure automáticamente.

+4

Estoy tratando de mantener el archivo log4j fuera del WAR para que el cliente pueda ajustarlo fácilmente según sea necesario para el diagnóstico del problema. En cuanto a la propiedad JVM, actualmente ni siquiera tenemos un script de inicio. Los clientes simplemente implementan el archivo WAR e inician. – HDave

+0

En algunos casos, deberíamos agregar el prefijo "file" a la ruta '-Dlog4j.configuration = file: conf/log4j.properties' –

+0

@matt b, por favor, aclare la secuencia classpath scanninng – gstackoverflow

8

Nuestra aplicación independiente requiere un SMTPAppender donde la configuración de correo electrónico ya existe en un archivo de configuración spring y que no quería que se va a duplicar en el log4j.properties.

Puse lo siguiente a la par para agregar un appender extra usando el resorte.

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

También tenemos un archivo log4j.properties en la ruta de clases que detalla nuestra regulares FileAppenders.

que se dan cuenta de que esto puede ser excesiva para lo que necesita :)

1

Si está utilizando embarcadero puede agregar rutas de clases adicionales en función de cada aplicación:

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

Esto le permitirá cargar sus propiedades log4 de una manera estándar (de la ruta de clase :)

en 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> 

en el embarcadero-web.xml:

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

Puede utilizar la ruta de clase en lugar de ruta codificado.Funciona para mí

<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

¡Eso fue genial! Gracias ! – Hatem

+0

¿Es posible usar una URL con esta solución? –