Java日志框架的发展历史,你不想了解一下吗

news2024/11/30 2:33:59

前言

在这里插入图片描述

相信大家在项目开发中肯定遇到过log4jJULslf4jlogbacklog4j2等日志框架相关名词,这些日志框架之间到底有什么关系,Java日志框架究竟经历了什么样的发展历程,相信有很多人都对此充满了好奇。
下边将按照时间线对Java日志框架的发展历史进行介绍,从log4jJULJCL,到slf4jlogback,再到log4j2

Java日志框架为什么不断更新,层出不穷,它们之间又有什么关系,相信通过这篇文章你会对Java日志框架有一个全新的认识!

📌博主主页:小新要变强的主页
👉Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉算法刷题路线可参考:算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~


目录

数据结构基础【数组】

  • 前言
  • 目录
  • 1️⃣Java日志生态图
  • 2️⃣System.out与System.err
  • 3️⃣Log4j
  • 4️⃣JUL
  • 5️⃣JCL
  • 6️⃣Slf4j
  • 7️⃣Logback
  • 8️⃣Log4j2
  • 9️⃣思考
  • 后记

在这里插入图片描述

1️⃣Java日志生态图

首先来看一张Java日志生态图,其中蓝色部分是日志实现,粉红色部分是日志门面,白色部分是相关的绑定包桥接包。(关于Java日志框架的详细介绍请期待我的下一篇文章)

在这里插入图片描述

初次看这张图肯定是比较懵逼的,各种包桥接过去桥接过来,绑定来绑定去,都是些啥玩意儿?

虽然看这张Java日志生态图很乱,很难梳理清楚,可能名字都不是很好记,但是如果我们从Java日志系统本身的发展历史去了解一下,可能就会明白为什么会出现图中这种情况了!

Java日志框架整体经历了如下图所示的演变历史,接下来就来看看吧~在这里插入图片描述

2️⃣System.out与System.err

这应该是最早的日志记录方式吧,缺点是:

  • 不灵活也不可以配置,要么就是全部打印,要么就是全部不打印,没有一个统一的日志级别;
  • 产生大量的IO操作同时在生产环境中无法合理的控制是否需要输出;
  • 输出的内容不能保存到文件;只打印在控制台,打印完就过去了,也就是说除非你一直盯着程序跑;
  • 无法定制化,且日志粒度不够细。

3️⃣Log4j

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

这位大佬应该不能仅仅用大佬来称呼了,可能应该叫巨佬了!讲到后面你就慢慢明白了,后来Log4j成为了Apache基金会项目中的一员,同时Log4j的火爆,让Log4j一度成为业内日志标杆。(据说Apache基金会还曾经建议Sun引入Log4j到java的标准库中,但是Sun拒绝了)

4️⃣JUL

果然Sun有“自己的考虑”,2002年2月Java1.4发布,Sun竟然推出了自己的日志库Java Util LoggingJUL),其实很多日志的实现思想也都是仿照Log4j,毕竟Log4j先出来很多年了,已经很成熟了此时,这两个日志工具打架,显然Log4j是更胜一筹。

神仙打架其实就是互相竞争,Sun心里可能在想,不就是做个日志工具嘛,谁不会!当然好景不长。

5️⃣JCL

Apache: 玩编程,谁玩的过我!你不让我成为JDK标准,我就自己成为日志标准!

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

在这里插入图片描述

但是好景不长,在使用过程中,虽然现在日志系统在JCL的统一下很优雅,很美好,但大家发现了JCL还不够好,有些人甚至认为JCL造成的问题比解决的问题还多…JUL主要有三个缺点:(1)效率较低;(2)容易引发混乱;(3)使用了自定义ClassLoader的程序中,使用JCL会引发内存泄露。

在这里插入图片描述

6️⃣Slf4j

所以大佬出现,Ceki Gülcü(也就是Log4j的作者)由于一些原因离开了Apache,之后觉得JCL不好,于是于2005年自己撸出一个新工程,也就是一套新日志接口(有得也叫日志门面):Slf4jSimple Logging Facade for Java),感觉粗来了么,这战争的硝烟,明显这个Slf4j是直指JCL啊,但是后面确实也证明了Slf4j是要比JCL在很多地方更优秀。

Ceki Gülcü: 玩接口,我一个人就是一支军队!

但是由于Slf4j出来的较晚,而且还只是一个日志接口,所以之前已经出现的日志产品,如JULLog4j都是没有实现这个接口的,所以尴尬的是光有一个接口,没有实现的产品也是很憋屈啊,就算开发者想用Slf4j也是用不了,这时候,大佬发话了。

Ceki Gülcü: 别急,我早帮你们想好了,要让Sun或者Apache这两个庞然大物来实现我的接口,太南啦,老铁,但…我帮你们实现,不就完了么。

于是大佬Ceki Gülcü撸出了之前提到的桥接包,通过桥接包来帮助Slf4j接口与其他日志库建立关系,这种方式称桥接设计模式。代码使用Slf4j接口,就可以实现日志的统一标准化,后续如果想要更换日志实现,只需引入Slf4j与相关的桥接包,再引入具体的日志标准库即可。

在这里插入图片描述

大佬提供了桥接包,于是日志系统现在有了这样的结构:

在这里插入图片描述

但是其实之前很多Java应用应该依赖的JCL,所以光有日志产品桥接包,好像还不够。

Ceki Gülcü: 没问题,不就是桥接包么,我写,我来证明Slf4j是最完美的。

于是有了JCL的桥接包:

在这里插入图片描述
相当于此时的桥接包就是分了两种场景:(1)之前Java应用用的日志接口(如JCL);(2)之前Java应用用的日志产品(如Log4j)。

那我们如果再考虑一下这种场景呢?
假设你的Java应用使用了Spring的第三方的框架,但是假设Spring默认用JCL,并且最终用的JUL打印的日志,但是你的系统使用了Slf4j作为日志接口,日志产品使用了Log4j,那不出意外的话…你将有两种日志输出,两种日志的打印方式不统一,到时候解决bug的时候就很恼火,而且配置日志的配置文件还需要两份。

在这里插入图片描述

所以为了方便统一应用中的所有日志,大佬发话了。

Ceki Gülcü: 没事,大家都选择用Slf4j统一吧,我来帮大家统一,没有事是桥接包解决不了的,有的话,那就再来个。

在这里插入图片描述

当然此时这种场景也是符合之前说的两种情况的,因此现在日志系统大体应该是这样的:

在这里插入图片描述

但是…但是看后边吧,大佬毕竟是大佬,Log4j不就是自己写的么,所以最清楚Log4j缺点的人也正是他。

7️⃣Logback

Ceki Gülcü 巨佬觉得市场上的日志标准库都是间接实现Slf4j接口,也就是说每次都需要配合桥接包,也就是之前的日志产品都不是正统的Slf4j的实现。

因此在2006年,Ceki Gülcü 基于Slf4j接口写出了Logback日志标准库,做为Slf4j接口的默认实现,Logback 也十分给力,在功能完整度和性能上超越了所有已有的日志标准库,其根本原因还在于,随着用户体量的提升,Log4j无法满足高性能的要求,成为应用的性能瓶颈。而且当时大佬还专门写了一篇文章:

在这里插入图片描述

是不是这太针对了…哈哈哈哈,就是这么无情,当然都是他写的,他肯定是最清楚这两者实现的区别。

毋庸置疑,Logback是完美实现了Slf4j,于是现在日志系统变成了:

在这里插入图片描述

现在有了2个日志接口,3个日志产品,大家也都看起来相安无事。但…Slf4j+Logback的模式,显然很冲击JCL+Log4j,并且本身Logback确实比Log4j性能更优,设计更为合理,所以,老东家Apache可就坐不住了。

8️⃣Log4j2

在2012年,Apache直接推出新项目,不是Log4j1.x升级,而是新项目Log4j2,因为Log4j2是完全不兼容Log4j1.x的。

并且很微妙的,Log4j2几乎涵盖Logback所有的特性(这不是对着干是啥~而且还有抄袭的嫌疑哈哈哈),更甚者的Log4j2也搞了分离的设计,分化成log4j-apilog4j-core,这个log4j-api也是日志接口,log4j-core才是日志产品。

现在我们可有了3个日志接口,以及4个日志产品。当然Apache也知道该做啥,为了让大家可以接入自己的Log4j2,那不就是桥嘛,Apache也麻溜的推出了它的桥接包,所以日志系统变成了现在的局面:

在这里插入图片描述

9️⃣思考

了解了日志的发展历史,我们再回过头来思考一下,如果,你的系统在选择日志方案的时候,如何抉择呢?毕竟有3个日志接口,以及4个日志产品。

  • 显然第一点是使用日志接口的API而不是直接使用日志产品的API。这一条也是必须的,也是符合依赖倒置原则的,我们应该依赖日志的抽象,而不是日志的实现。
  • 日志产品的依赖只添加一个。当然也这个也是必须的,依赖多个日志产品,只会让自己的应用处理日志显得更复杂,不可统一控制。
  • 把日志产品的依赖设置为Optional和runtime scope。其中Optional是为了依赖不会被传递,比如别的人引用你这个jar,就会被迫使用不想用的日志依赖;而scope设置为runtime,是可以保证日志的产品的依赖只有在运行时需要,编译时不需要,这样,开发人员就不会在编写代码的过程中使用到日志产品的API了。
  <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>${log4j.version}</version>
      <optional>true</optional>
  </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>${log4j.version}</version>
        <scope>runtime</scope>
    </dependency>

后记

在这里插入图片描述
👉Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉算法刷题路线可参考:算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/3187.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Socket 编程基础

文章目录一、socket 简介二、socket 编程接口介绍1. socket()函数2. bind()函数3. listen()函数4. accept()函数5. connect()函数6. 发送和接收函数read()函数recv()函数write()函数send()函数7. close()关闭套接字三、IP 地址格式转换函数inet_pton()函数inet_ntop()函数本篇会…

决策树与随机森林在分类预测中的应用(附源码)

写在前面 今天给大家分享一下基于决策树和随机森林在乳腺癌分类中实战。决策树和随机森林是白盒模型&#xff0c;数学建模中常用到这两种模型&#xff0c;用于预测或分类&#xff0c;随机森林还可以进行特征选择&#xff0c;故很推荐大家学习&#xff01;&#xff01;&#xff…

Qt5.14.2在Windows下使用mysql

第一步:下载依赖 1.1去Qt官方下载Qt5.14.2的源代码: Index of /archive/qt/5.14/5.14.2/singlehttps://download.qt.io/archive/qt/5.14/5.14.2/single/ 下载链接:https://download.qt.io/archive/qt/5.14/5.14.2/single/qt-everywhere-src-5.14.2.zip 1.2去Mysql官网下载Mys…

面试官:说说TCP如何实现可靠传输

今天来讲一下TCP是如何保证可靠传输的。这也是面试常问的一个题目&#xff0c;这个问题不单止能看出你是否真的了解TCP原理&#xff0c;更看出你是否有一个总结的能力。 我们从三个部分来讲TCP是如何实现可靠传输的。 滑动窗口 首先是讲TCP中的滑动窗口&#xff0c;它和TCP的…

基本的Dos命令

基本的Dos命令 打开CMD的方式 开始系统命令提示符win键R输入cmd (推荐使用)在任意的文件夹下&#xff0c;按住Shift键鼠标右击&#xff0c;打开命令行窗口在资源管理器地址栏路径前面加 “cmd ”管理员运行方式&#xff1a;命令提示符右键以管理员身份运行&#xff08;最高权…

动态规划--01背包问题详解

代码随想录day42和day43 动态规划 模块01背包问题 “即使到不了远方&#xff0c;心中也要有远方的模样。” 文章目录1. 01背包理论基础1.1什么是背包问题1.2二维dp数组01背包1.3一维dp数组(滚动数组)01背包2.leetcode 416.分割等和子集2.1 详细思路及思考难点2.2具体步骤及代码…

当食品制造业遇见数字化工具,如何借助S2B2C电商系统实现企业新增长

食品制造业是我国产业发展中的重要组成部分&#xff0c;具有点多、面广、投资小、见效快的特点&#xff0c;在经济发展中发挥着重要作用。根据工信部数据统计&#xff0c;从2018至2021年我国食品制造业经营规模稳步增长&#xff0c;2021年我国食品制造业营业收入达21268.1亿元&…

QT·移植Qt到ARM平台及搭建Qt交叉编译环境

目录 一、编译tslib库 二、移植 tslib 到文件系统 三、编译Qt源码&#xff08;用于移植到ARM&#xff09; 四、移植Qt到文件系统 五、搭建 Qt Creator 交叉编译环境 六、获得Qt可执行文件的另一种方法 要想在ARM平台上运行Qt程序&#xff0c;得满足以下两个点&#xff1a;1、…

【表达式求值】

目录&#xff1a;前言一、有效的括号&#xff08;一&#xff09;题目分析&#xff08;二&#xff09;整体代码二、表达式求值&#xff08;一&#xff09;题目分析1.栈的基本操作&#xff1a;2. 大体思路&#xff1a;3.具体计算过程&#xff1a;&#xff08;二&#xff09;整体代…

【代码随想录】二刷-哈希表

哈希表 《代码随想录》 哈希表一般用来快速查找某个元素是否在一个集合中。如果使用枚举的话时间复杂度为O(n)&#xff0c;而使用哈希表只O(1)就可以做到。——元素查询。 242.有效的字母异位词 使用unordered_map // 时间复杂度 O(n) // 空间复杂度 O(n) class Solution { pub…

嵌入式分享合集94

一、单片机硬件电路设计 减少后级电源对前级的影响&#xff0c;防止电源正负接反烧坏后级电路&#xff0c;防止电源关电时电流倒灌&#xff0c;但经过二极管有0.4V左右压降&#xff0c;需要考虑经过0.4V降压后会不会低于后级电路的正常工作电压。 一、按键电路 R1上拉电阻&…

用C语言开发入门游戏FlappyBird

前言 《flappy bird》是一款由来自越南的独立游戏开发者Dong Nguyen所开发的作品&#xff0c;游戏于2013年5月24日上线&#xff0c;并在2014年2月突然暴红。2014年2月&#xff0c;《Flappy Bird》被开发者本人从苹果及谷歌应用商店撤下。2014年8月份正式回归APP Store&#xf…

java从零开始系统性学习完整笔记(一)

java从零开始系统性学习完整超全资源笔记(还在更新中&#xff09; 前言 资源来自&#xff1a;王汉远java基础&#xff0c; B站视频&#xff1a; https://www.bilibili.com/video/BV1b4411g7bj/?spm_id_from333.1007.top_right_bar_window_custom_collection.content.click&a…

渗透测试之分享常用工具、插件和脚本(干货)

BRUP插件&#xff1a; 漏洞挖掘插件&#xff1a;Autorize、CSRF Token Tracker、XSS Validator、Turbo Intruder 辅助插件&#xff1a;HaE、sqlmap4brup、hackbar、Software Vulnerability Scanner 浏览器插件&#xff1a; wappalyzer、MySSL、Cookie Editor 脚本&#xff1a; …

Vue学习:vue生命周期

Vue实例有一个完整的生命周期&#xff0c;也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程&#xff0c;我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程&#xff0c;就是生命周期。生命周期又称为生命周期回调函数&#…

水果叠叠乐

水果叠叠乐 介绍 消消乐是一款益智类小游戏&#xff0c;最近比较火爆的一种是立体叠叠乐式的&#xff0c;然后小蓝也想开发一个自己练练手&#xff0c;给它起名叫“水果叠叠乐”。 准备 本题已经内置了初始代码&#xff0c;打开实验环境&#xff0c;目录结构如下&#xff1…

OSPF高级配置——学习OSPF路由协议的高级应用

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.路由重分发及配置 1.路由重分发概述 2.理解路由重分发 3.路…

【HMS Core】华为分析SDK如何申请数据导出功能?

1、问题描述 项目中集成了华为分析SDK&#xff0c;现在有一个需求&#xff0c;想要申请数据导出功能&#xff0c;申请页面提示数据导出功能目前仅对部分邀请伙伴开放&#xff0c;需要通过在线提单的方式申请开通此功能&#xff0c;那么具体该如何操作呢&#xff1f; 2、解决方…

校园跑腿微信小程序,校园跑腿小程序,微信小程序跑腿系统毕设作品

项目背景和意义 目的&#xff1a;本课题主要目标是设计并能够实现一个基于微信校园跑腿小程序系统&#xff0c;前台用户使用小程序发布跑腿任何和接跑腿任务&#xff0c;后台管理使用基于PHPMySql的B/S架构&#xff1b;通过后台管理跑腿的用户、查看跑腿信息和对应订单。 意义…

C++ Reference: Standard C++ Library reference: C Library: cwchar: wcstoll

C官网参考链接&#xff1a;https://cplusplus.com/reference/cwchar/wcstoll/ 函数 <cwchar> wcstoll long long int strtoll (const wchar_t* str, wchar_t** endptr, int base); 将宽字符串转换为long long整数 解析C宽字符串str&#xff0c;将其内容解释为指定base的…