Инициализация Log4J с помощью Spring? - PullRequest
30 голосов
/ 09 декабря 2010

У меня есть веб-приложение, которое использует класс Spring * Log4jConfigurer для инициализации моей фабрики журналов Log4J.По сути, он инициализирует 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 может быть инициализирован первым бином?или есть другой способ решить эту проблему?

Ответы [ 5 ]

48 голосов
/ 09 декабря 2010

Вы можете настроить прослушиватель 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 он работает.

7 голосов
/ 06 мая 2011

Наше автономное приложение требовало SMTPAppender, где конфигурация электронной почты уже существует в файле конфигурации spring, и мы не хотели, чтобы это дублировалось в log4j.properties.

Я добавил следующее, чтобы добавить дополнительный 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>

У нас также есть файл log4j.properties на пути к классам, который описывает наш обычный FileAppenders.

Я понимаю, что это может быть излишним для того, что вам нужно:)

4 голосов
/ 09 декабря 2010

Вместо того, чтобы настраивать log4j самостоятельно в коде, почему бы просто не указать log4j на местоположение вашего (пользовательского) файла конфигурации, добавив

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

в свойства запуска вашего сервера?

Еще лучше,просто переместите файл log4j.xml в местоположение по умолчанию - на пути к классам - и позвольте log4j настроить себя автоматически.

2 голосов
/ 27 мая 2015

Вы можете использовать classpath вместо жестко заданного пути.У меня работает

<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>
1 голос
/ 21 июля 2011

Если вы используете Jetty, вы можете добавить дополнительные пути к классам для каждого приложения:

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...