Подтвердить что ты не робот

Инициализация 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? или есть ли другой способ решить это?

4b9b3361

Ответ 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>