Initializing Log4J with Spring?
Solution 1
You could configure your Log4j listener in the web.xml instead of the spring-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>
So it is up before Spring starts.
Solution 2
Our standalone application required an SMTPAppender
where the email config already exists in a spring
config file and we didn't want that to be duplicated in the log4j.properties
.
I put the following together to add an extra appender using spring.
<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>
We also have a log4j.properties
file on the classpath which details our regular FileAppenders
.
I realise this may be overkill for what you require :)
Solution 3
Rather than configuring log4j yourself in code, why not just point log4j at your (custom) configuration file's location by adding
-Dlog4j.configuration=.../conf/log4j.xml
to your server's startup properties?
Even better, just move log4j.xml to the default location - on the classpath - and let log4j configure itself automatically.
Solution 4
You can use classpath instead of hardcoded path. It works for me
<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>
Solution 5
If you are using Jetty you can add extra classpaths on a per application basis:
http://wiki.eclipse.org/Jetty/Reference/Jetty_Classloading#Adding_Extra_Classpaths_to_Jetty
This will allow you to load your log4 properties in a standard manner (from the classpath:)
in 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>
in jetty-web.xml:
<Set name="extraClasspath">
<SystemProperty name="config.home" default="."/>/contexts/log4j
</Set>
![Dave](https://i.stack.imgur.com/xLpyz.jpg?s=256&g=1)
Comments
-
Dave over 4 years
I have a web app that uses Spring's
Log4jConfigurer
class to initialize my Log4J log factory. Basically it initializes Log4J with a config file that is off the class path.Here is the 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>
However I get this error at application startup:
log4j:WARN No appenders could be found for logger
and tons of Spring application context initialization messages are printed to the console. I think this is because Spring is doing work to initialize my application before it has a chance to initialize my logger. In case it matters, I am using SLF4J on top of Log4J.
Is there some way I can get my Log4jConfigurer to be the first bean initialized? or is there some other way to solve this?