如何配置Spring和SLF4J以便获取日志记录?

46

我有一个使用Maven和Spring的应用程序,我想记录日志。 我想使用SLF4J。

我希望将所有的配置文件都放在目录{classpath}/config下,包括log4j.xml,并使用Spring bean进行初始化。

例如:

<bean id="log4jInitialization" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetClass" value="org.springframework.util.Log4jConfigurer"/>
    <property name="targetMethod" value="initLogging"/>
    <property name="arguments">
        <list>
            <value>classpath:config/log4j.xml</value>
        </list>
    </property>
</bean>

然而我收到了这个警告,但没有日志记录。

log4j:WARN:找不到适用程序记录器(org.springframework.context.support.ClassPathXmlApplicationContext)的附加程序。 log4j:WARN:请正确初始化log4j系统。 log4j:WARN:有关更多信息,请参见http://logging.apache.org/log4j/1.2/faq.html#noconfig

我在Google上搜索过,但找不到一个简单的设置示例。有什么建议吗?


我猜测一下。如果你尝试使用完整路径*<value>C:/config/log4j.xml</value>*,它是否有任何不同的作用? - JoseK
不行。硬编码没用。=( - Programming Guy
7个回答

47

除了Jatin的回答之外:

Spring使用Jakarta Commons Logging作为日志记录API。要记录到slf4j,您需要确保commons-logging不在类路径上。jcl-over-slf4j是替代commons-logging的jar文件。

如果您使用maven,可以使用mvn dependency:tree检测commons-logging来自哪里,并使用依赖项排除从所有需要它的依赖项中排除它。但是,您可能需要多次运行mvn dependency:tree,因为它仅显示传递依赖项的第一次出现。

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>${org.springframework.version}</version>
  <exclusions>
    <exclusion>
      <artifactId>commons-logging</artifactId>
      <groupId>commons-logging</groupId>
    </exclusion>
  </exclusions>
</dependency>

1
我喜欢这里建议的第三种方法 - http://slf4j.org/faq.html#excludingJCL - 使用空构件。这个选项在当前版本的Spring参考手册中得到推荐。 - Andrew B

27

你可以在https://github.com/mbogoevici/spring-samples/tree/master/mvc-basic/trunk找到一个示例。你需要在POM文件中包含一些依赖项以启用日志记录。

<!-- Logging -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${org.slf4j.version}</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>${org.slf4j.version}</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>${org.slf4j.version}</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.16</version>
        <scope>runtime</scope>
    </dependency>

这个例子将log4j配置文件直接放在类路径下,而不是我想要的放在一个config目录下。 - Programming Guy
实际上那确实有些帮助。我现在已经在我的应用中记录日志了,只是 Spring 在抱怨。 - Programming Guy
如果特定的类发出投诉,则需要将所需的包添加到已向记录器注册的包列表中。您还可以将其放入配置文件夹中,并将该文件夹添加到类路径中。 - Jatin
我认为这个警告只是在启动时出现。一旦log4j配置器bean运行,我就得到了所有我需要的日志记录。能够让警告消失会很好,但我认为我可以不管它。 - Programming Guy

6
为了完整起见,这里还有一个logback-classic变体:
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.0.0</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
    <version>1.6.6</version>
    <scope>runtime</scope>
</dependency>

不要忘记禁用Spring依赖中出现的commons-logging,这与接受的答案(Stijn's)中提到的类似。


5
请使用以下配置将 JCL API 实现在 classpath 上:
<dependencies>
       <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>3.0.0.RELEASE</version>
          <scope>runtime</scope>
          <exclusions>
             <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
             </exclusion>
          </exclusions>
       </dependency>
       <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>jcl-over-slf4j</artifactId>
          <version>1.5.8</version>
          <scope>runtime</scope>
       </dependency>
       <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
          <version>1.5.8</version>
          <scope>runtime</scope>
       </dependency>
       <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
          <version>1.5.8</version>
          <scope>runtime</scope>
       </dependency>
       <dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>1.2.14</version>
          <scope>runtime</scope>
       </dependency>
    </dependencies> 

更多信息请查看这里

涉及IT技术的内容。

1

我喜欢logback的方式,对于slf4j,我们进行类似的配置:

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
    </dependency>

slf4j-log4j12会自动引入slf4j-api和log4j,所以不需要放置太多依赖。


1

将log4j文件保留在默认包中


0
只需在根上下文中添加lazy-init="false"以急切地加载log4j配置的bean。这应该解决log4j:WARN No appenders could be found for logger的警告信息。
示例:
<bean id="log4jInitialization" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" lazy-init="false">

更好的方法是将配置放在web.xml中或作为JVM参数(-Dlog4j.configuration=.../conf/log4j.xml 或者对于某些情况,使用'file:'前缀的-Dlog4j.configuration=file:conf/log4j.properties)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接