Инициализация Log4J с помощью Spring?
У меня есть веб-приложение, которое использует класс Spring Log4jConfigurer
для инициализации журнала Log4J factory. В основном он инициализирует Log4J с помощью файла конфигурации, который находится вне пути к классу.
Вот конфигурация:
<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 выполняет работу по инициализации моего приложения, прежде чем он сможет инициализировать мой регистратор. В случае, если это имеет значение, я использую SLF4J поверх Log4J.
Есть ли способ, чтобы мой Log4jConfigurer был первым инициализированным bean? или есть ли другой способ решить это?
Ответы
Ответ 1
Вы можете настроить прослушиватель Log4j в файле web.xml вместо 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.
Ответ 2
Для нашего автономного приложения требуется SMTPAppender
, где конфигурация электронной почты уже существует в конфигурационном файле spring
, и мы не хотели, чтобы это дублировалось в log4j.properties
.
Я добавил следующее, чтобы добавить дополнительный appender с помощью 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>
У нас также есть файл log4j.properties
в пути к классам, который детализирует наш обычный FileAppenders
.
Я понимаю, что это может быть излишним для того, что вам нужно:)
Ответ 3
Вместо того, чтобы самостоятельно конфигурировать log4j в коде, почему бы не просто указать log4j в вашем (настраиваемом) месте конфигурационного файла, добавив
-Dlog4j.configuration=.../conf/log4j.xml
к свойствам запуска сервера?
Еще лучше, просто переместите log4j.xml в местоположение по умолчанию - по пути к классам - и пусть log4j автоматически настроится.
Ответ 4
Если вы используете Jetty, вы можете добавить дополнительные пути к классам для каждого приложения:
http://wiki.eclipse.org/Jetty/Reference/Jetty_Classloading#Adding_Extra_Classpaths_to_Jetty
Это позволит вам загружать ваши свойства log4 стандартным образом (из пути к классам:)
в 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>
Ответ 5
Вы можете использовать путь к классам вместо жестко заданного пути. Это работает для меня
<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>