slf4j+log4j+logback总结

http://www.cnblogs.com/huayu0815/p/5341712.html

java开发过程中为了找问题方便或是统计信息方便,总免不了要打各种日志。之前的各个项目都是配置好的,maven配置的时候,会看到各种类型的Log包:slf4j、log4j、commons-log、logback等等,看着就烦,今天仔细了解了一下,有点收获,记录一下

起因

使用JAVA的kafka api写main方法进行开发测试,发现总报错

1
2
3
log4j:WARN No appenders could be found for logger (kafka.utils.VerifiableProperties).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http: //logging .apache.org /log4j/1 .2 /faq .html #noconfig for more info.

解决过程

第一直觉是缺少log4j的配置。好办,classpath下加入log4j.properties(log4j默认应该是直接找classpath下的这个文件,当然,可以直接指定加载哪个文件),OK,不报错了

刚好最近的一个项目使用的是logback,而且网上也查了,logback性能要优于log4j(没有做过测试,先盲目从众吧),就想直接引入logback。

POM中加入logback的依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependency>
           <groupId>ch.qos.logback< /groupId >
           <artifactId>logback-core< /artifactId >
           <version>1.1.2< /version >
       < /dependency >
       <dependency>
           <groupId>ch.qos.logback< /groupId >
           <artifactId>logback-access< /artifactId >
           <version>1.1.2< /version >
       < /dependency >
       <dependency>
           <groupId>ch.qos.logback< /groupId >
           <artifactId>logback-classic< /artifactId >
           <version>1.1.2< /version >
       < /dependency >

启动,报错

1
2
3
4
5
6
7
8
log4j:WARN No appenders could be found for logger (kafka.utils.VerifiableProperties).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http: //logging .apache.org /log4j/1 .2 /faq .html #noconfig for more info.
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar: file : /C : /Users/zhaohuayu/ .m2 /repository/org/slf4j/slf4j-log4j12/1 .6.1 /slf4j-log4j12-1 .6.1.jar! /org/slf4j/impl/StaticLoggerBinder .class]
SLF4J: Found binding in [jar: file : /C : /Users/zhaohuayu/ .m2 /repository/ch/qos/logback/logback-classic/1 .1.2 /logback-classic-1 .1.2.jar! /org/slf4j/impl/StaticLoggerBinder .class]
SLF4J: See http: //www .slf4j.org /codes .html #multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]

哦,Class path contains multiple SLF4J bindings。

原来slf4j提供的是一个抽象的接口,实现可以是log4j、logback等,但是,运行时候只能有一个接口实现类。之前引入的kafka包,已经包含了对log4j的依赖,我又引入logback的包,冲突了

好办,去掉对Log4j的依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<dependency>
           <groupId>org.apache.kafka< /groupId >
           <artifactId>kafka_2.10< /artifactId >
           <version>0.8.2.0< /version >
           <exclusions>
               <exclusion>
                   <groupId>log4j< /groupId >
                   <artifactId>log4j< /artifactId >
               < /exclusion >
               <exclusion>
                   <groupId>org.slf4j< /groupId >
                   <artifactId>slf4j-log4j12< /artifactId >
               < /exclusion >
           < /exclusions >
       < /dependency >
       <dependency>
           <groupId>ch.qos.logback< /groupId >
           <artifactId>logback-core< /artifactId >
           <version>1.1.2< /version >
       < /dependency >
       <dependency>
           <groupId>ch.qos.logback< /groupId >
           <artifactId>logback-access< /artifactId >
           <version>1.1.2< /version >
       < /dependency >
       <dependency>
           <groupId>ch.qos.logback< /groupId >
           <artifactId>logback-classic< /artifactId >
           <version>1.1.2< /version >
       < /dependency >

这下总OK了吧,运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Exception in thread "main" java.lang.NoClassDefFoundError: org /apache/log4j/Logger
     at kafka.utils.Logging$class.logger(Logging.scala:24)
     at kafka.utils.VerifiableProperties.logger$lzycompute(VerifiableProperties.scala:26)
     at kafka.utils.VerifiableProperties.logger(VerifiableProperties.scala:26)
     at kafka.utils.Logging$class.info(Logging.scala:67)
     at kafka.utils.VerifiableProperties.info(VerifiableProperties.scala:26)
     at kafka.utils.VerifiableProperties.verify(VerifiableProperties.scala:217)
     at kafka.producer.ProducerConfig.<init>(ProducerConfig.scala:57)
     at KafkaProducer.getClient(KafkaProducer.java:26)
     at KafkaProducer.sendMsg(KafkaProducer.java:35)
     at KafkaProducer.main(KafkaProducer.java:41)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at java.lang.reflect.Method.invoke(Method.java:606)
     at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

what?

kafka.utils.Logging里包含了对log4j类的引用……

1
2
3
4
package kafka.utils;
 
import kafka.utils.Log4jController.;
import org.apache.log4j.Logger;

怎么办?难道使用kafka的项目必须使用log4j?

总有解决方案,

1
2
3
4
5
<dependency>
          <groupId>org.slf4j< /groupId >
          <artifactId>log4j-over-slf4j< /artifactId >
          <version>1.7.7< /version >
      < /dependency >

再次运行,OK,日志正常打印了

总结

1、slf4j提供各种抽象接口,日志应该基于slf4j的API进行日志打印,这样无论迁移到那个项目,只需要配一个实现类log4j or logback,都能正常打印日志

2、slf4j的实现类不能有多个,不然冲突

3、如果项目中有直接引用log4j的,可以加入log4j-over-slf4j,把旧的日志log4j适配到slf4j,这时候,再使用logback就可以了

分享一个博客中解决各个项目模块中,各种日志杂乱的方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<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
< /dependency
<dependency> 
     <groupId>org.slf4j< /groupId
     <artifactId>log4j-over-slf4j< /artifactId
     <version>${org.slf4j-version}< /version
< /dependency
<dependency> 
     <groupId>org.slf4j< /groupId
     <artifactId>jul-to-slf4j< /artifactId
     <version>${org.slf4j-version}< /version
< /dependency
<dependency> 
     <groupId>org.jboss.logging< /groupId
     <artifactId>jboss-logging< /artifactId
     <version>3.1.4.GA< /version
< /dependency

当然,前提是需要把各个项目中依赖的log实现exclusion掉

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值