跳至主要內容

Java领域的日志框架

Jin大约 6 分钟

Java领域的日志框架

1、概念

1.1、日志的概述

日志文件是用于记录系统操作事件的文件集合,可分为事件日志和消息日志。具有处理历史数据、诊断问题的追踪以及理解系统的活动等重要作用。

在计算机中,日志文件是记录在操作系统或其他软件运行中发生的事件或在通信软件的不同用户之间的消息的文件。记录是保持日志的行为。在最简单的情况下,消息被写入单个日志文件。

1.2、日志的作用

  1. 调试
    • 在Java项目调试时,查看栈信息可以方便地知道当前程序的运行状态,输出的日志便于记录程序在之前的运行结果。
  2. 错误定位
    • 项目在运行一段时候后,可能由于数据问题,网络问题,内存问题等出现异常。这时日志可以帮助开发或者运维人员快速定位错误位置,提出解决方案。
  3. 数据分析
    • 大数据的兴起,使得大量的日志分析成为可能,ELK也让日志分析门槛降低了很多。日志中蕴含了大量的用户数据,包括点击行为,兴趣偏好等,用户画像对于公司下一步的战略方向有一定指引作用。

2、日志框架的分类

日志系统
日志系统

2.1、门面型日志框架(抽象层)

2.1.1、JCL(Jakarta Commons Logging)

Apache基金会所属的项目,是一套Java日志接口,之前叫Jakarta Commons Logging,后更名为Commons Logging

为了解耦日志接口与实现,Apache 在 2002 年推出了JCL(Jakarta Commons Logging)。JCL 定义了一套日志接口,具体的实现由Log4jJUL完成。Commons Logging使用动态绑定来实现日志记录,编码时只需要使用它定义的接口即可,程序运行时会使用ClassLoader来查找和加载底层的日志库,因此可以灵活选择Log4jJUL来实现日志功能。

2.1.2、slf4j( Simple Logging Facade for Java)

是一套简易Java日志门面,本身并无日志的实现。(Simple Logging Facade for Java,缩写Slf4j)

为Java提供简单日志记录的抽象层。它本身并不实现日志记录功能,而是依赖于其他日志框架(如Log4J、Log4J2、LogBack等)来实现具体的日志记录。SLF4J的主要优点是它提供了一个统一的日志接口,使得应用程序可以在不修改源代码的情况下更换日志框架。此外,SLF4J还提供了丰富的日志级别和灵活的日志输出方式,使得日志记录更加灵活和方便。

2.2、记录型日志框架

2.2.1、 JUL(java util logging)

JUL全称Java util Logging是java原生的日志框架,使用时不需要另外引用第三方类库,相对其他日志框 架使用方便,学习简单,能够在小型应用中灵活使用

2.2.2、logback

  1. Logback是由log4j创始人设计的另一个开源日志组件,性能比log4j要好。
  2. 官方网站:https://logback.qos.ch/index.htmlopen in new window

2.2.3、log4j

  1. Log4j是Apache下的一款开源的日志框架。
  2. 官方网站:http://logging.apache.org/log4j

2.2.4、log4j2

  1. 目前市面上最主流的日志门面就是SLF4J,虽然Log4j2也是日志门面,因为它的日志实现功能非常强大,性能优越。所以大家一般还是将Log4j2看作是日志的实现,Slf4j + Log4j2应该是未来的大势所趋。
  2. https://logging.apache.org/log4j/2.12.xopen in new window

3、发展历程

要搞清楚它们的关系,就要从它们是在什么情况下产生的说起。我们按照时间的先后顺序来介绍。

Log4j

在JDK 1.3及以前,Java打日志依赖System.out.println(), System.err.println()或者e.printStackTrace(),Debug日志被写到STDOUT流,错误日志被写到STDERR流。这样打日志有一个非常大的缺陷,即无法定制化,且日志粒度不够细。 于是, Gülcü 于2001年发布了Log4j,后来成为Apache 基金会的顶级项目。Log4j 在设计上非常优秀,对后续的 Java Log 框架有长久而深远的影响,它定义的Logger、Appender、Level等概念如今已经被广泛使用。Log4j 的短板在于性能,在Logback 和 Log4j2 出来之后,Log4j的使用也减少了。

JUL

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

JCL(commons-logging)

由于项目的日志打印必然选择两个框架中至少一个,这时候,Apache的JCL(commons-logging)诞生了。JCL 是一个Log Facade,只提供 Log API,不提供实现,然后有 Adapter 来使用 Log4j 或者 JUL 作为Log Implementation。 在程序中日志创建和记录都是用JCL中的接口,在真正运行时,会看当前ClassPath中有什么实现,如果有Log4j 就是用 Log4j, 如果啥都没有就是用 JDK 的 JUL。

这样,在你的项目中,还有第三方的项目中,大家记录日志都使用 JCL 的接口,然后最终运行程序时,可以按照自己的需求(或者喜好)来选择使用合适的Log Implementation。如果用Log4j, 就添加 Log4j 的jar包进去,然后写一个 Log4j 的配置文件;如果喜欢用JUL,就只需要写个 JUL 的配置文件。如果有其他的新的日志库出现,也只需要它提供一个Adapter,运行的时候把这个日志库的 jar 包加进去。

不过,commons-logging对Log4j和j.u.l的配置问题兼容的并不好,使用commons-loggings还可能会遇到类加载问题,导NoClassDefFoundError的错误出现。到这个时候一切看起来都很简单,很美好。接口和实现做了良好的分离,在统一的JCL之下,不改变任何代

SLF4J & Logback

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

4、技术选型

推荐应用程序面向日志门面编程,以便底层可以在不同的日志实现之间自由切换。

项目中的日志框架,通常是两个:日志门面(抽象)+ 日志实现

  • SLF4J+Logback(推荐)
贡献者: Jin