Java日志框架梳理-Java日志框架总览

2,540 阅读3分钟

常见的Java日志框架

  • log4j
  • logback
  • j.u.l (java.util.logging)

常见的Java日志门面

  • SLF4J
  • commons-logging

其中,j.u.l是Java原生库,但是在Java 1.4中才被引用; commons-logging出自Apache,用于桥接j.u.l和log4j;log4j、logback和SLF4J出自同一个作者(Ceki),目前被广泛应用于开源项目中。以上日志框架、日志门面出现时间线如图:

这里写图片描述

  本节按上述框架、门面出现的时间顺序简单介绍各个节点

log4j

  在JDK 1.3及以前,Java打日志依赖System.out.println(), System.err.println()或者e.printStackTrace(),Debug日志被写到STDOUT流,错误日志被写到STDERR流。这样打日志有一个非常大的缺陷,即无法定制化,且日志粒度不够细。log4j是在这样的环境下诞生的,它是一个里程碑式的框架,它定义的Logger、Appender、Level等概念如今已经被广泛使用。
  
  

j.u.l

  受Logj启发,Sun在Java1.4版本中引入了java.util.logging,但是j.u.l功能远不如log4j完善,开发者需要自己编写Appenders(Sun称之为Handlers),且只有两个Handlers可用(Console和File),j.u.l在Java1.5以后性能和可用性才有所提升。

commons-logging (Jakarta Commons Logging: j.c.l)

  由于项目的日志打印必然以来两个框架中至少一个,这时候,Apache的commons-logging诞生了。commons-logging不是一个日志打印框架,而是一个API bridge,开发者可以使用它兼容不同的日志框架(log4j和j.u.l)。然而,commons-logging对Log4j和j.u.l的配置问题兼容的并不好,使用commons-loggings还可能会遇到类加载问题,导致NoClassDefFoundError的错误出现。

SLF4J

  最终,log4j的创始人Ceki发起了SLF4J(Simple Logging Facade for Java)项目,从设计模式的角度说,它是用来在log和代码层之间起到门面作用,对于用户来说只要使用SLF4J提供的接口,即可隐藏日志的具体实现,SLF4J提供的核心API是一些接口和一个LoggerFactory的工厂类,用户只需按照它提供的统一纪录日志接口,最终日志的格式、纪录级别、输出方式等可通过具体日志系统的配置来实现,因此可以灵活的切换日志系统。

  • 参数化打印日志(parameterized logging)
logger.error("the exception message is {}", message);

logback

  logback和log4j是同一个作者创作,它是log4j的升级版,因此logback相较于log4j有更多的优点:

  • 原生实现了SLF4J API(log4j需要一个中间层转换)
  • 支持XML、Groovy方式配置
  • 支持配置文件中加入条件判断
  • 更强大的过滤器
  • 更丰富的免费文档
  • 更充分的测试
  • 自动重载有变更的配置文件
  • 自动压缩历史日志
  • 打印异常信息时自动包含pachage名称及版本号
  • 其他特性

      日志框架的使用基本都会结合日志门面,关于commons-logging (j.c.l)的使用详见参考内容3。
      鉴于SLF4J使用较为广泛,下文主要介绍SLF4J的使用方法,SLF4J的使用方式有两种,一种是混合绑定(concrete-bindings),另一种是桥接遗产(bridging-legacy)。
      混合绑定模式指在项目中直接食用SLF4J来打印日志,而底层绑定任意一种日志框架,如:log4j、logback、j.u.l等。混合绑定根据实现原理又分为两种:有适配器(adapter)绑定、无适配器绑定。有适配器绑定是指底层没有实现SLF4J的接口,而是通过适配器调用底层日志框架的logger,无适配器绑定是指其本身实现了SLF4J的全部接口(logback),不需要调用其他日志框架的logger。几种混合绑定包简介:

  • slf4j-log4j12-1.7.21.jar : 有适配器,绑定log4j,logger由log4j-1.2.17.jar提供

  • slf4j-jdk14-1.7.21.jar : 有适配器,绑定j.u.l,logger由j.u.l提供
  • logback-classic-1.0.13.jar : 无适配器,logback实现了SLF4J的全部接口
  • slf4j-simple-1.7.21.jar : 无适配器,slf4j的简单实现,仅打印info及以上级别的日志,所有输出重定向到System.err,适合小应用。

      后续分别介绍有适配器的混合绑定(slf4j + log4j)和无适配器的混合绑定(slfj + logback)的具体实现。