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

Posted

技术标签:

【中文标题】如何配置 Spring 和 SLF4J 以便获得日志记录?【英文标题】:How do I configure Spring and SLF4J so that I can get logging? 【发布时间】:2011-03-24 04:19:17 【问题描述】:

我有一个要登录的 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 上四处搜索,但找不到一个简单的设置示例。有什么想法吗?

【问题讨论】:

我猜。如果您尝试完整路径 C:/config/log4j.xml,它的工作方式是否有所不同 不。硬编码没有帮助。 =( 【参考方案1】:

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

【讨论】:

我喜欢这里建议的第三种方法 - slf4j.org/faq.html#excludingJCL - 使用空工件。当前版本的 Spring 参考手册中建议使用此选项。【参考方案2】:

您可以在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 配置文件直接放在类路径中,而不是在我想要的配置目录下。 其实这确实有点帮助。我现在已经登录了我的应用程序,抱怨的只是春天。 如果某个特定的类在抱怨,您需要将所需的包添加到记录器注册的打包列表中。你也可以把它放在一个配置文件夹中,然后将该文件夹添加到类路径中。 我认为警告只是启动。一旦 log4j 配置器 bean 运行,我将获得我需要的所有日志记录。能够让警告消失会很好,但我想我可以离开它。【参考方案3】:

为了完整起见,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>

但不要忘记禁用 commons-logging 依赖项,它从 Spring 依赖项中萌芽,就像在接受的(Stijn 的)答案中一样。

【讨论】:

【参考方案4】:

使用打击配置在classpath 上实现JCL API

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

更多信息请查看here

【讨论】:

【参考方案5】:

将 log4j 文件保存在默认包中

【讨论】:

【参考方案6】:

我喜欢 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,所以不需要放那么多依赖

【讨论】:

【参考方案7】:

只需添加 lazy-init="false" 即可在您的根上下文中急切地加载 bean 以进行 log4j 配置。那应该可以解决警告消息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

【讨论】:

以上是关于如何配置 Spring 和 SLF4J 以便获得日志记录?的主要内容,如果未能解决你的问题,请参考以下文章

Spring中配置使用slf4j + log4j

Spring Boot 日志记录 SLF4J

springboot配置日志(Slf4j)

使用 oracle jdbc 驱动程序的 JUL 到 SLF4j

Spring Boot中的logback + slf4j

Spring Boot 使用slf4j+logback记录日志配置