用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已经存在于一个spring
configuration文件中,我们不希望在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>