Spring 引导:使用 logback 而不是 log4j

Spring Boot: use logback instead of log4j

我想将 Logback 与 Spring 引导项目一起使用,因为它的性能和灵活性。我将 Logback 依赖项添加到 pom.xml:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>1.1.3</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.1.3</version>
</dependency>

... 并确保我项目中每个 类 中的日志记录是这样创建的:

public class MyClass {

    static final Logger LOG = LoggerFactory.getLogger(MyClass.class);

项目启动时,控制台显示以下警告:

log4j:WARN No appenders could be found for logger (org.springframework.boot.logging.ClasspathLoggingApplicationListener).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

似乎 Spring 仍在尝试使用 log4j 而不是 logback。我尝试将 logging.config=classpath:logback.xml 添加到 Spring application.properties,但没有解决问题。

你能看出我做错了什么吗?

更新

@AliDehghani 和@chrylis 都建议 log4jpom 中的另一个包引用。 mvn dependency:tree 的输出确认 hbase-common 是来源:

com.woolford:my-project:jar:1.0-SNAPSHOT
+- org.apache.hbase:hbase-common:jar:1.1.2:compile
|  [... etc ...]
|  +- commons-logging:commons-logging:jar:1.2:compile
|  [... etc ...]
|  +- org.apache.hadoop:hadoop-common:jar:2.5.1:compile
|  [... etc ...]
|  |  +- org.slf4j:slf4j-log4j12:jar:1.7.5:compile
|  |  \- com.jcraft:jsch:jar:0.1.42:compile
|  +- org.apache.hadoop:hadoop-mapreduce-client-core:jar:2.5.1:compile
|  [... etc ...]
|  +- log4j:log4j:jar:1.2.17:compile
|  [... etc ...]
\- org.apache.hbase:hbase-client:jar:1.1.2:compile
   [... etc ...]

我尝试从 hbase-common 中排除 log4j(和 slf4j),如下所示:

<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-common</artifactId>
    <version>1.1.2</version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
    </exclusions>
</dependency>

项目构建失败:

[ERROR] Failed to execute goal on project my-project: Could not resolve dependencies for project com.woolford:my-project:jar:1.0-SNAPSHOT: The following artifacts could not be resolved: javax.jms:jms:jar:1.1, com.sun.jdmk:jmxtools:jar:1.2.1, com.sun.jmx:jmxri:jar:1.2.1: Could not transfer artifact javax.jms:jms:jar:1.1 from/to java.net (https://maven-repository.dev.java.net/nonav/repository): Cannot access https://maven-repository.dev.java.net/nonav/repository with type legacy using the available connector factories: BasicRepositoryConnectorFactory: Cannot access https://maven-repository.dev.java.net/nonav/repository with type legacy using the available layout factories: Maven2RepositoryLayoutFactory: Unsupported repository layout legacy -> [Help 1]

我尝试将这些依赖项添加到 pom.xml,但这没有帮助。

@AliDehghani 在下面的回答中指出,Spring Boot 默认使用 Logback,因此不应该将 logback-corelogback-classic 添加到 pom.xml必要的。我确信他是 100% 正确的。但是,当我在 pom.xml 中注释掉 logback-corelogback-classic 时,我看到了几个警告,例如

log4j:ERROR Could not create an Appender. Reported error follows.
java.lang.ClassNotFoundException: ch.qos.logback.core.ConsoleAppender

Spring 默认情况下使用 Logback 进行日志记录。无需明确添加:

By default, If you use the ‘Starter POMs’, Logback will be used for logging. Appropriate Logback routing is also included to ensure that dependent libraries that use Java Util Logging, Commons Logging, Log4J or SLF4J will all work correctly.

您还可以通过在 application.properies 中使用 logging.level.*=LEVEL 来更改日志级别。

你已经知道了这一点,但我想总结一下并概括一下...


有这三个日志框架:

  • log4j(古)
  • slf4j(api无处不在,有不同的后端可用)
  • logback(具有不错的功能和配置,slf4j的继承者)

你必须手动扔掉 log4j 并用兼容性桥 log4j-over-slf4j 替换它。

有一个名为 logback-classicslf4j 后端。


mvn:

<dependency>
    <!-- legacy log4j ==> slf4j -->
    <groupId>org.slf4j</groupId>
    <artifactId>log4j-over-slf4j</artifactId>
    <version>1.7.21</version>
</dependency>
<dependency>
    <!-- slf4j ==> logback -->
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.1.7</version>
</dependency>
<dependency>
    <groupId>...no maintainer...</groupId>
    <artifactId>...old stuff...</artifactId>
    <version>...ancient...</version>
    <exclusions>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
    </exclusions>
</dependency>

sbt:

libraryDependencies ++= Seq(
    Seq(...),
    Seq(
      "org.slf4j" % "log4j-over-slf4j" % "1.7.21",   // legacy log4j --> slf4j
      "ch.qos.logback" % "logback-classic" % "1.1.7" // slf4j --> logback
    )
  ).flatten.map(_.excludeAll(
    ExclusionRule(organization = "log4j", name = "log4j", artifact = "*"),
    ExclusionRule(organization = "org.slf4j", name = "slf4j-log4j12", artifact = "*")
  ))