springframework - tag library spring
configuración log4j específica del entorno por muelle (2)
Estoy cargando log4j.xml usando la forma tradicional
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:conf/log4j.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
Esto funciona bien, pero ahora necesito cargar un archivo log4j.xml diferente en función del entorno en el que esté definido por una variable de entorno / entrada jndi ... así que esperaba que con la nueva administración de propiedades de la primavera 3.1 simplemente pudiera cambiar esto a
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:conf/log4j-${ENV-NAME}.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
y spring cargará el archivo log4j correcto en cada entorno, pero esto no funciona probablemente porque web.xml se carga antes de spring. Me encontré con este método
<bean id="log4jInitialization" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="org.springframework.util.Log4jConfigurer" />
<property name="targetMethod" value="initLogging" />
<property name="arguments">
<list>
<value>log4j-${ENV-NAME}.xml</value>
</list>
</property>
</bean>
por lo que esencialmente se mueve la configuración de log4j al archivo de contexto de Spring en lugar de web.xml. Pero esto tampoco funciona, por alguna razón, el registro se habilita de manera que todo se registra. Entonces, ¿cómo puedo usar un archivo log4j.xml diferente basado en una variable de entorno o cargarlo programáticamente en el servletcontextlistener?
Es demasiado tarde para ayudar a adeelmahmood, pero espero que otros se beneficien de mi respuesta. La cosa es que adeelmahmood tenía razón, esta configuración:
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:conf/log4j-${ENV-NAME}.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
está funcionando, pero
- ¡Log4jConfigListener debe registrarse antes de ContextLoaderListener en web.xml!
- También debe recordar que Log4jConfigListener asume un archivo WAR expandido.
Luego, si se establece la variable de entorno ENV-NAME, funciona como se esperaba.
Por cierto, $ {ENV-NAME} también se puede usar en los archivos de configuración de Spring! Eso no es todo ... También puede usar nuestra propiedad env.property para establecer el perfil de Spring:
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>${ENV-NAME}</param-value>
</context-param>
De esta manera puede establecer log4jConfigLocation y spring profile, ambos con uno y el mismo env. variable.
Por cierto y por si acaso: usar perfiles de Maven para tener compilaciones separadas para desarrollo, prueba y producción no es una buena práctica. Leer por ejemplo http://java.dzone.com/articles/maven-profile-best-practices y recuerde: "Utilice los perfiles para administrar las variables de tiempo de compilación, no las variables de tiempo de ejecución y no (con las excepciones RARE) versiones alternativas de su artefacto" .
Esto también podría ayudar a los lectores más recientes: en Log4j 2.7 (pero probablemente es más antiguo) el nombre del parámetro ha sido alterado: vea la interfaz Log4jWebSupport
:
/**
* The {@link javax.servlet.ServletContext} parameter name for the location of the configuration.
*/
String LOG4J_CONFIG_LOCATION = "log4jConfiguration";