基本日志

java中基本日志的使用,包括log4j,logback等

常用的日志组件

aaa

门面接口

Common-logging

apache提供的一个通用的日志接口、用户可以选择第三方的日志组件作为具体实现、eg log4j,logging等。通过动态查找(查找配置文件)的机制、在程序运行时自动找出真正使用的日志库。好处时代码依赖的时common-logging而非log4j,避免和具体的日志方案直接耦合,可以随时更换日志实现的第三方库。

动态查找方案:
  1. 寻找org.apache.commons.logging.LogFactory 属性配置

  2. classpah 下的META-INF/services/org.apache.commons.logging.LogFactory 配置

  3. Classpath 里寻找commons-logging.properties

  4. 使用默认配置:引入log4j并在classpath配置了log4j.xml.使用log4j,如果没有则使用JDK14Logger实现、再没有使用jcl内部提供的simpleLog实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.junit.Test;

    public class LogTest {
    @Test
    public void t1(){
    //使用jcl包
    Log log = LogFactory.getLog(LogTest.class);
    }
    }
1
2
3
4
5
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>

slf4j

simple logging facade for java,java简单日志门面,是对不同日志框架提供的一个门面封装、可以在部署的时候不修改任何配置就接入一种日志实现方案。但是在编译时静态绑定真正的Log库。使用slf4j时,必须选择正确的slf4j的jar包的集合(各种桥接包)。

静态绑定:

会在编译时绑定staticloggerBinder,这个类实现对具体的日志方案的绑定接入。任何一种基于slf4j的实现都要又一个这个类,当又多个实现类时,绑定失败。

jar包的分类

桥接包:slf4j-XXX-version.jar,XXX 可以是 log4j12, jdk14, jcl, nop 等

  • slf4j-log4j12.jar(绑定log4j)
  • log4j-slf4j-impl(绑定log4j2)
  • slf4j-jdk14.jar(jul)
  • slf4j-jcl.jar(jcl)
  • logback-classic(logback)

适配器 : XXX-over-slf4j.jar 日志输出重定向到 SLF4J

  • jcl-over-slf4j:slf4j替换jcl
  • jul-over-slf4j:slf4j替换jul
  • log4j-over-slf4j:slf4j替换log4j
优势:
  1. 可以在OSGI中使用
  2. 支持参数化的log字符串,拼装消息被推迟到它能够确定是不是要显示这条消息,减少字符串拼接的性能损耗、但是获取参数的代价并没有消除
1
2
3
4
5
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>

实现类

log4j

1
2
3
4
5
6
//log4j核心包
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:config/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value>
</context-param>
slf4j+log4j
1
2
3
4
5
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.1</version>
</dependency>

log4j2

配置文件的形式可以时xml|json等

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.5</version>
</dependency>
1
只需要把log4j2.xml放到工程resource目录下
slf4j+log4j2
1
2
3
4
5
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.8.2</version>
</dependency>

JUL(java.util.logging)

logback

logback当前分成三个模块:logback-core,logback- classic和logback-access。logback-core是其它两个模块的基础模块。

logback-classic是log4j的一个 改良版本,logback-classic完整实现SLF4J API使你可以很方便地更换成其它日记系统如log4j或JDK14 Logging。

logback-access访问模块与Servlet容器集成提供通过Http来访问日记的功能

1
2
3
4
5
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.7</version>
</dependency>
slf4j+logback
1
2
3
4
5
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
</dependency>
优势
  1. 速度
  2. 性能
  3. 文档

常见问题

其他日志迁入SLF4j

加入xxx-over-slf4j.jar包桥接包,使得xxx输出的日志交给slf4j

死循环

当第一种情况发生时,slf4j,如果加入了slf4j-xxx-version.jar,slf4j会将日志交给xxx,这样导致死循环,

多个绑定、打印不出日志等

Class path contains multiple SLF4J bindings

  1. 理清关系,要什么日志方案,推荐slf4j+logback
  2. 排包
  3. 如果排包可以完成,执行方案需要的jar包,如果有一些直接使用impl的方法,需要桥接包完成

logback.xml

configuration

​ scan:默认时true,配置文件发生改变、将会重新加载;

​ sacnperid:默认1分钟,扫描间隔

​ debug:默认false,true则打印logbaclne内部日志

1
2
3
<configuration scan="true" scanPeriod="60 seconds" debug="false"> 
      <!--其他配置省略-->
</configuration>

contextName

设置上下文名称,默认时default,一旦设置,不能修改

property

定义变量值

appender

负责写日志的组件、必须属性name和class,name指定appender名称,class指定appender的全限定名

ConsoleAppender :控制台

FileAppender :文件

RollingFileAppender

logger

用来设置某一个包或具体的某一个类的日志打印级别、

  • appender:没有设置,则本身不打印任何消息
  • name属性,
  • 可选level:默认继承上级
  • 可选的addtivity属性:是否向上级loger传递打印信息,默认是true)

root

它也是<loger>元素,但是它是根loger,是所有<loger>的上级 ,只有level属性,默认都是debug

参考文献

https://blog.csdn.net/yycdaizi/article/details/8276265

https://blog.csdn.net/NowUSeeMe/article/details/55010715

https://blog.csdn.net/u012129558/article/details/79947477