Reputation: 4563
I'd like to use Logback, for its performance and flexibility, with a Spring Boot project. I added the Logback dependencies to 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>
... and ensured that the logging, within each of the classes in my project, was created like this:
public class MyClass {
static final Logger LOG = LoggerFactory.getLogger(MyClass.class);
When the project starts, the following warning is displayed in the console:
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.
It seems that Spring is still trying to use log4j
and not logback. I tried adding logging.config=classpath:logback.xml
to the Spring application.properties
, but it didn't resolve the issue.
Can you see what I'm doing wrong?
Both @AliDehghani and @chrylis suggested that log4j
is being referenced by another package in the pom
. The output from mvn dependency:tree
confirmed that hbase-common
was the source:
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 ...]
I tried excluding log4j
(and slf4j
) from hbase-common
like this:
<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>
The project failed to build:
[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]
I tried adding these dependencies to pom.xml
, but that didn't help.
@AliDehghani noted, in his answer below, that Spring Boot uses Logback by default and so adding logback-core
and logback-classic
to the pom.xml
shouldn't be necessary. I'm sure he's 100% correct. However, when I comment out the logback-core
and logback-classic
in pom.xml
I see several warnings, e.g.
log4j:ERROR Could not create an Appender. Reported error follows.
java.lang.ClassNotFoundException: ch.qos.logback.core.ConsoleAppender
Upvotes: 3
Views: 19639
Reputation: 5261
you already know this, but i wanted to wrap it up and generalize...
there are these three logging frameworks:
log4j
(ancient)slf4j
(api used everywhere, there are different backends available)logback
(has nice features and configuration, successor of slf4j
)you have to manually throw out log4j
and replace it with the compatibility bridge log4j-over-slf4j
.
there is a slf4j
backend called logback-classic
.
<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>
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 = "*")
))
Upvotes: 13
Reputation: 48193
Spring Boot by default using Logback for its logging. There is no need for adding it explicitly:
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.
You can also, change the log levels through using logging.level.*=LEVEL
in your application.properies
.
Upvotes: 3