Java 用 Spring 初始化 Log4J?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4400583/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 17:00:40  来源:igfitidea点击:

Initializing Log4J with Spring?

javaspringweb-applicationslog4j

提问by HDave

I have a web app that uses Spring's Log4jConfigurerclass to initialize my Log4J log factory. Basically it initializes Log4J with a config file that is off the class path.

我有一个 Web 应用程序,它使用 Spring 的Log4jConfigurer类来初始化我的 Log4J 日志工厂。基本上,它使用类路径之外的配置文件初始化 Log4J。

Here is the config:

这是配置:

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

However I get this error at application startup:

但是我在应用程序启动时收到此错误:

log4j:WARN No appenders could be found for logger

log4j:WARN No appenders could be found for logger

and tons of Spring application context initialization messages are printed to the console. I think this is because Spring is doing work to initialize my application before it has a chance to initialize my logger. In case it matters, I am using SLF4J on top of Log4J.

并且大量 Spring 应用程序上下文初始化消息被打印到控制台。我认为这是因为 Spring 在有机会初始化我的记录器之前正在做初始化我的应用程序的工作。以防万一,我在 Log4J 之上使用 SLF4J。

Is there some way I can get my Log4jConfigurer to be the first bean initialized? or is there some other way to solve this?

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

采纳答案by Ralph

You could configure your Log4j listener in the web.xml instead of the spring-context.xml

您可以在 web.xml 而不是 spring-context.xml 中配置您的 Log4j 侦听器

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

So it is up before Spring starts.

所以它在春天开始之前就结束了。

回答by matt b

Rather than configuring log4j yourself in code, why not just point log4j at your (custom) configuration file's location by adding

与其在代码中自己配置 log4j,不如通过添加将 log4j 指向您的(自定义)配置文件的位置

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

to your server's startup properties?

到您服务器的启动属性?

Even better, just move log4j.xml to the default location - on the classpath - and let log4j configure itself automatically.

更好的是,只需将 log4j.xml 移动到默认位置 - 在类路径上 - 让 log4j 自动配置自己。

回答by Harry Lime

Our standalone application required an SMTPAppenderwhere the email config already exists in a springconfig file and we didn't want that to be duplicated in the log4j.properties.

我们的独立应用程序需要一个SMTPAppender电子邮件配置已经存在于spring配置文件中的地方,我们不希望它在log4j.properties.

I put the following together to add an extra appender using spring.

我将以下内容放在一起以使用 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>

We also have a log4j.propertiesfile on the classpath which details our regular FileAppenders.

我们还在log4j.properties类路径上有一个文件,详细说明了我们的常规FileAppenders.

I realise this may be overkill for what you require :)

我意识到这对于您的要求可能有点过分:)

回答by Mond Raymond

If you are using Jetty you can add extra classpaths on a per application basis:

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

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

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

This will allow you to load your log4 properties in a standard manner (from the classpath:)

这将允许您以标准方式加载 log4 属性(从类路径:)

in web.xml:

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

in jetty-web.xml:

在 jetty-web.xml 中:

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

回答by ravi ranjan

You can use classpath instead of hardcoded path. It works for me

您可以使用类路径而不是硬编码路径。这个对我有用

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