用Spring初始化Log4J?

我有一个Web应用程序,它使用Spring的Log4jConfigurer类来初始化我的Log4J日志工厂。 基本上它使用一个离开类path的configuration文件来初始化Log4J。

这是configuration:

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

但是我在应用程序启动时出现这个错误:

log4j:WARN No appenders could be found for logger

和大量的Spring应用程序上下文初始化消息被打印到控制台。 我认为这是因为Spring在初始化我的应用程序之前有工作来初始化我的应用程序。 万一重要,我在Log4J上面使用了SLF4J。

有什么办法可以让我的Log4jConfigurer成为初始化的第一个bean? 还是有其他的方法来解决这个问题?

您可以在web.xml中configuration您的Log4j侦听器,而不是在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> 

所以在Spring开始之前就已经到了。

我们的独立应用程序需要一个SMTPAppender ,其中的电子邮件configuration已经存在于一个springconfiguration文件中,我们不希望在log4j.properties重复这个configuration。

我把以下几点放在一起,用spring来添加一个额外的appender。

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

我们在类path上也有一个log4j.properties文件,它详细介绍了我们的常规FileAppenders

我意识到这可能是矫枉过正的你需要:)

为了不在代码中自己configurationlog4j,为什么不把log4j指向你的(自定义)configuration文件的位置?

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

到你的服务器的启动属性?

更妙的是,只要将log4j.xml移动到默认位置(在类path上),并让log4j自动进行自我configuration即可。

如果您正在使用Jetty,则可以在每个应用程序的基础上添加额外的类path:

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

这将允许你以标准的方式加载你的log4属性(从classpath 🙂

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

在jetty-web.xml中:

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

您可以使用classpath而不是硬编码的path。 它适用于我

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