在程序运行过程中,日志非常重要。是记录程序运行状况,寻找bug,维护稳定性的重要工具。但市面上的日志系统十分繁多,于是在这里记录并整理。如有错误,请评论区留言告知。

日志门面与日志产品

日志门面

日志门面又称日志接口,它并不是真正的日志实现,但是对上层提供了一套统一的API,故在代码层面可以使用统一的写法,而引入不同的适配器来实现不同的日志输出。

主流的日志门面有

  1. JCL(Jakarta Commons Logging)
  2. slf4j(Simple Logging Facade for Java)

日志实现

真正的日志实现。主要有

  1. JUL(JDK自带)
  2. logback
  3. log4j
  4. log4j2

在我们的项目中,通常会用到不同的组件与模块。由于不同开发者可能会使用不同的日志系统,为了让我们的日志打印出来工整统一,且避免包的冲突,合理使用桥接包与适配器就非常重要。

桥接包与适配器

适配器就是从SLF4J日志实现的包,封装了统一的API。
桥接包就是从日志实现SLF4J的包,对于已经使用日志实现A的模块,使用桥接包将其链接到日志门面上,就可以再次适配到其他日志实现B了。

我整理了日志系统适配器与桥接器的关系图如下所示。

java 项目本地日志路径 java项目日志管理_java 项目本地日志路径

如果模块原先使用JUL日志系统来记录,但我们想把它迁移到log4j2上。那么引入桥接包jul-to-slf4j,日志门面slf4j-api,引入适配器log4j-slf4j-impl,最后引入日志实现log4j-apilog4j-core。就可以了。对于同一种日志实现,对应适配器与桥接器不可同时引入,否则会循环依赖。

官网例子

java 项目本地日志路径 java项目日志管理_log4j_02


例如右上角的图,原先有2个模块,分别使用JCL门面JUL,要转为log4j日志系统。先引入2个桥接器,然后引入slf4j-api,再引入适配器slf4j-log4j12,最后引入日志的实现log4j

最佳实践

  • 使用日志接口的 API 而不是日志产品的 API
  • 日志产品的依赖只添加一个
  • 日志产品的依赖设置为 optional和runtime scope。为了这个依赖不会被传递。

版本

Maven Repository: Search/Browse/Explore 直接在Maven仓库中搜索上图中的jar包,引入对应的版本即可。