java中的日志使用--slf4j,log4j,logback

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

原由java

使用JAVAkafka apimain方法进行开发测试,发现总报错apache

1api

2app

3maven

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

解决过程scala

第一直觉是缺乏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提供的是一个抽象的接口,实现能够是log4jlogback等,可是,运行时候只能有一个接口实现类。以前引入的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,日志正常打印了

总结

1slf4j提供各类抽象接口,日志应该基于slf4jAPI进行日志打印,这样不管迁移到那个项目,只须要配一个实现类log4j or logback,都能正常打印日志

2slf4j的实现类不能有多个,否则冲突

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