从01开始 从01开始
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理
  • 操作系统
  • Linux
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE
  • JavaWeb
  • Spring
  • 主流框架
  • 学习网课的心得
  • 输入法
职场系列
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)

peterjxl

人生如逆旅,我亦是行人
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理
  • 操作系统
  • Linux
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE
  • JavaWeb
  • Spring
  • 主流框架
  • 学习网课的心得
  • 输入法
职场系列
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)
  • JavaSE

  • JavaSenior

  • JavaEE

    • JavaEE概念

    • Ant

    • 日志

      • 日志介绍
      • print大法
      • 常见的日志框架-简单介绍
        • 前言
        • Log4j
        • JUL(Java Util Logging)
        • JCL(Jakarta Commons Logging)
        • Slf4j(Simple Logging Facade for Java)
        • Logback
        • Log4j2
        • 最佳实践
        • 参考
      • 一个日志框架的设计
      • JDK Logging
      • log4j2 笔记
      • 日志的一些小技巧
      • 日志系统小结
    • Junit

    • JDBC

    • XML和JSON

    • Java
  • JavaWeb

  • Spring

  • 主流框架

  • 韩顺平

  • Java
  • Java
  • JavaEE
  • 日志
2022-12-03
目录

常见的日志框架-简单介绍

# 02.常见的日志框架-简单介绍

不自己造轮子

# 前言

在前面我们介绍了什么是日志,以及日志的重要性,一般项目中都会用到,并介绍了print大法的缺点,怎么解决呢?我们可以自定义一个工具类,专门用于处理日志,取代sout。这样有几个优点

  1. 可以设置输出样式,例如设置错误输出的字体颜色,输出字眼是什么;
  2. 可以自定义输出级别,例如只输出错误日志的级别,当有问题的时候再调整级别更低,打印更多日志
  3. 可以将输出重定向到文件里(这种文件叫日志文件)
  4. 可以将输出重定向到数据库
  5. 可以………………

总之就是很多,工作中也几乎是必用的技术。

‍

很可惜,在早期,Java是没有提供相关的功能的。当时大部分人都是用Java的打印语句:System.out和System.err。 这应该是最早的日志记录方式吧,但是不灵活也不可配置,要么就是全部打印,要么就是全部不打印,没有一个统一的日志级别

‍

直到Java1.4 才有了相关的功能;在这之前,业内已经有不少成熟的日志框架了,几乎很少会用到Java提供的日志功能了。

‍

# Log4j

Log4j,全程是Log for Java,意指Java用的日志框架。官网:Apache Log4j (opens new window)

4是和for谐音,在英语中不少这样的谐音。例如P2P中,2是指to,P2P全称 Peer to Peer

在1996年初,E.U.SEMPER​(欧洲安全电子市场)项目决定编写自己的跟踪API​,最后该API​演变为Log4j​,Log4j​日志软件包一经推出就备受欢迎,当然这里必须要提到一个人,就是Log4j​的主要贡献者:Ceki Gülcü (巨佬,划重点,要考的)

后来Log4j​成为了Apache​基金会项目中的一员,同时Log4j​的火爆,让Log4j​一度成为业内日志标杆。(据说Apache​基金会还曾经建议Sun​引入Log4j​到java​的标准库中,但是sun​拒绝了)

‍

‍

# JUL(Java Util Logging)

2002年2月Java1.4​发布,Sun​竟然推出了自己的日志库Java Util Logging​(难道这就是之前sun拒绝Log4j的原因?),其实很多日志的实现思想也都是仿照Log4j​,毕竟Log4j​先出来很多年了,已经很成熟了此时,这两个日志工具打架,显然Log4j​是更胜一筹..........

‍

# JCL(Jakarta Commons Logging)

目前日志框架有很多个,如果用户想要切换的话,会非常麻烦,因为各个框架的设计和实现都不同;

能不能做一个抽象层?应用程序通过抽象层的API来生成日志,具体底层用什么日志框架,应用程序不用关心;当想要更换日志框架的时候,可以在不用改动代码(或者改动较少代码)的情况下完成切换,让应用程序更灵活。

笔者注:类似JDBC,一统数据库访问层;只提供了一种抽象,具体的实现靠各个数据库厂商实现的抽象。

‍

‍

​JUL​刚出来不久,2002年8月Apache​又推出了日志接口Jakarta Commons Logging​,也就是日志抽象层,当然也提供了一个默认实现Simple Log​,这野心很大,想一统日志抽象,让日志产品去实现它的抽象,这样只要你的日志代码依赖的是JCL​的接口,你就可以很方便的在Log4j​和JUL​之间做切换,当时日志领域大概是这样的结构,当然也还是方便理解的,也很优雅

​​

‍

虽然听上去不错,但JCL​用起来似乎并不是那么好,很多人认为引用它后造成的问题比解决的问题还多…………

例如有人是这样说的:Tapestry Central: So long, commons-logging, hello SLF4J (opens new window) (需科学上网)

I'm finally taking a bit to do something I've wanted to do for a long time: get away from commons-logging (opens new window) and switch over to SLF4J (opens new window).

Commons-logging has a justified reputation (opens new window) for causing more problems than it solves.

‍

‍

# Slf4j(Simple Logging Facade for Java)

Ceki Gülcü 觉得 JCL不好用,于2005年也推出了一个接口方式,叫Slf4j(Simple Logging Facade for Java)。事实证明,这个接口要比JCL​在很多地方更优秀

但是由于Slf4j​出来的较晚,而且还只是一个日志接口,所以之前已经出现的日志产品,如JUL​和Log4j​都是没有实现这个接口的。那怎么办呢?之前出现的日志产品就不能使用该接口了吗?可以的, 于是大佬Ceki Gülcü撸出了桥接包,也就是这种类似适配器模式

应用
↓
Slf4j
↓
桥接包
↓
日志产品
1
2
3
4
5
6
7

也就是说,应用程序通过引用桥接包,可以使用SLF4J接口,至于底层用什么日志框架,应用程序不用关心

​​

‍

此时的桥接包就是分了两种场景

  1. 为了适配之前Java​应用用的日志接口(如JCL​)
  2. 为了适配之前Java​应用用的日志产品(如Log4j, JUL​)

当然,桥接包不仅这么简单,这里不展开来说,具体可以参考本文的末尾。

‍

# Logback

Logback是由log4j创始人设计的又一个开源日志组件,2011年11月3日,Logback 1.0版本发布。

由于有了之前设计Log4j的经验,Logback的性能能好,并且实现了SLF4J的接口,而且大佬还专门写了一篇文章:Reasons to prefer logback (opens new window)

小结下:

  • 我们目前有两个日志接口:JCL 和 SLF4J
  • 3个日志框架:JUL,Log4j,Logback

但Logback 用起来速度快,效率最高,SLFJ4+Logback 成为了很多人的最爱, 大有超越Apache Common Logging + Log4j 之势。

‍

目前的日志框架,架构图大致如下:

​​

‍

‍

# Log4j2

Apache于2012年推出了新项目Log4j 2, (完全不兼容Log4j1.x 的版本),并且Log4j2几乎涵盖了Logback的特性(Logback是开源的,也不算抄袭?😂 )

并且,Log4j2 也搞了一个新的接口设计,分化成log4j-api​和log4j-core​,这个log4j-api​也是日志接口,log4j-core​才是日志产品。。。

现在我们可有了3个日志接口,以及4个日志产品。。。

  • 3个日志接口:JCL, SLF4J,Log4j-API
  • 3个日志框架:JUL,Log4j,Logback,Log4j2

听起来可能稍微有点乱,但只要知道他们的历史,还是挺利于理解的。

‍

‍

‍

# 最佳实践

有这么多接口规范和框架,我们应该如何在系统中使用呢?

  1. 应该使用日志接口的API,而非直接使用框架(这样后期方便更换日志框架)
  2. 只使用一个日志框架
  3. 在Maven中,把日志产品的依赖设置为Optional​和runtime scope​
    其中Optional​是为了依赖不会被传递,比如别的人引用你这个jar​,就会被迫使用不想用的日志依赖
  4. ​scope​设置为runtime​,是可以保证日志的产品的依赖只有在运行时需要,编译时不需要,这样,开发人员就不会在编写代码的过程中使用到日志产品的API​了

‍

# 参考

java - Java日志系统历史从入门到崩溃_个人文章 - SegmentFault 思否 (opens new window) :强推,写的很简单易懂,关于桥接包的描述很棒

一个著名的日志系统是怎么设计出来的? (opens new window):介绍了设计思路,提到了正交性,涨知识了

进阶之路:Java 日志框架全画传(上) - 知乎 (opens new window)

进阶之路:Java 日志框架全画传(中) - 知乎 (opens new window)

进阶之路:Java 日志框架全画传(下) - 知乎 (opens new window)

‍

在GitHub上编辑此页 (opens new window)
上次更新: 2023/3/26 02:41:39
print大法
一个日志框架的设计

← print大法 一个日志框架的设计→

Theme by Vdoing | Copyright © 2022-2023 粤ICP备2022067627号-1 粤公网安备 44011302003646号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式