Java日志框架介绍

news2024/11/23 2:12:46

​今天来聊一聊 Java 日志框架,不管是在项目开发阶段的调试,还是项目上线后的运行,都离不开日志。日志具有处理历史数据、定位程序问题、理解程序运行过程等重要作用。在 Spring 项目开发过程中我们常见的日志框架可能就是 logback、log4j2 和 SLF4J。今天就一起系统地了解下 Java 日志框架。

发展史

​所有的技术的出现都是有缘由的,了解某个技术出现的来龙去脉,对技术也能更好的理解。

​日志框架出现顺序: log4j --> JUL --> JCL --> SLF4J --> logback --> log4j2

​最开始没有日志框架,在代码中使用 System.out、System.err 打印日志信息,没有日志级别控制,使用不灵活。

​1996年初,EU SEMPER 项目决定编写自己的项目跟踪 API,经过无数次增强,最终发展称为 log4j。后来 log4j 成了 Apache 基金会的一员,让 log4j 一度称为了业界的日志标杆。log4j 主要由瑞士程序员 Ceki Gülcü 贡献开发。

​sun 公司在2002年2月推出了 java 1.4 发布,推出了自己的日志库 java.util.logging,其实很多日志思想也都仿照 log4j。

​Apache 针对刚出来的 JUL,搞了一套 JCL,打算一统日志江湖,制定日志标准,JCL 是日志抽象层,让日志产品去实现它的抽象,只要你的日志代码实现 JCL 接口就可以很方便的在 log4j 和 JUL 之间切换。但是好景不长,随着 JCL 的应用,人们发现 JCL 带来的问题比它解决的问题还要多。

​这个时候 SLF4J 应运而生,依然是 Ceki Gülcü ,在2005年自己搞了一个新东西,也是一套日志接口,也有称之为日志门面,Slf4j 诞生了,后来也证明了,Slf4j 比 JCL 要更加优秀。在 SLF4J 之后,Ceki 基于之前已有的日志框架(log4j、JUL)又开发出了对应的适配器,至此,SLF4J 统一了日志接口,兼容已有日志框架,后来又重新写了一套基于 SLF4J 的实现 logback, logback完全实现 SLF4J 接口。

​2012年 Apache 推出了自己的新项目 log4j2,是对 log4j 的一次大升级,因为 log4j2 完全不兼容 log4j1.x,而且 log4j2 几乎涵盖了 logback 的全部新特性,log4j2 也搞了分离式设计,分化成 log4j-api 和 log4j-core,这个 log4j-api 也是日志接口,log4j-core才是日志产品。

​目前主流的使用组合是 SLF4J + log4j2 / logback

日志门面

  • JCL(Jakarta Commons Logging)(主要配合log4j, JUL 使用,如新增日志框架,需要修改源码)
  • SLF4J (Simple Logging Facade for Java) (主流的日志规范接口)

日志实现

  • JUL:java.util.logging Java原生日志框架,JDK自带,使用时不需要额外依赖包。
  • Log4j:Apache 的开源项目,由于需要与非常旧的 Java 版本兼容,它变得更加难以维护,并 于 2015 年 8 月停止使用。
  • Logbcak :由 Log4j 之父做的另一个开源项目,是一个可靠、通用且灵活的Java日志框架。
  • Log4j2 :Log4j 的升级版,各个方面与 logback 及其相似。具有插件式结构、配置文件优化等特征。
  • slf4j-simple: SLF4J 自带的简单日志实现。
  • 其他

SLF4J

​ SLF4J 主要是为了给Java日志访问提供一套标准、规范的API框架,其主要意义在于提供接口,具体的实现可以交由其他日志框架,例如 log4j 和 logback 等。当然 SLF4J 自己也提供了功能较为简单的实现 slf4j-simple,但是一般很少用到。

SLF4J 绑定日志框架

SLF4J 的日志绑定流程:

  1. 添加 slf4j-api 的依赖

  2. 使用 slf4j 的API在项目中进行统一的日志记录

  3. 绑定具体的日志实现框架

    (1) 绑定已经实现了 SLF4J 的日志框架,直接添加对应依赖

    (2) 绑定没有实现 SLF4J 的日志框架,先添加日志的适配器,再添加实现类的依赖

    (3) slf4j有且仅有一个日志实现框架的绑定(如果出现多个默认使用第一个依赖日志实现)

​SLF4J 不依赖于任何特殊的类加载器机制。事实上,每个 SLF4J 绑定在编译时都被硬连线 以使用一个且唯一一个特定的日志记录框架。例如,slf4j-log4j12-2.0.7.jar 绑定在编译时绑定以使用 log4j。在代码中,除了slf4j-api-2.0.7.jar之外,只需将一个且仅一个 日志实现jar 包放到适当的类路径位置即可。不要在类路径上放置多个绑定。

​下图是官网提供的SLF4J 和日志实现的绑定,slf4j-api.jar是SLF4J定义的日志规范接口,下图对应的jar是在使用日志框架是需要依赖的jar包。

​在项目使用 SLF4J 时,如果只引入 slf4j-api.jar,没有引入具体的日志实现,则不会绑定任何日志实现框架,也就不能输出日志。

​logback 和 slf4j-simple ,由于是在 SLF4J 之后开发的,因此直接实现的 SLF4J 接口,可以直接导入实现包就可以自动绑定。

​reload4j 和 JUL 由于在 SLF4J 规范出现之前已经有了,因此如果要使用SLF4J规范,需要引入适配器进行适配。(技术黑话:没有什么是加一层解决不了的)

绑定原理

  1. SLF4J 通过 LoggerFactory 加载日志具体的实现对象。

  2. LoggerFactory 在初始化的过程中,会通过 erformInitialization() 方法绑定具体的日志实现。

  3. 在绑定具体实现的时候,通过类加载器,加载 org/slf4j/impl/StaticLoggerBinder.class

  4. 所以,只要是一个日志实现框架,在 org.slf4j.impl 包中提供一个自己的 StaticLoggerBinder 类,在其中提供具体日志实现的LoggerFactory 就可以被 SLF4J 所加载

SLF4J日志级别

error > warn > info > debug > trace

为什么要使用日志门面?

1、面向接口编程,减少代码耦合,符合开闭原则。

2、使用日志门面,通过导入不同依赖可以灵活切换日志框架。

3、统一API,统一配置便于项目日志的使用和管理。

入门示例

1、引入依赖
<!--slf4j core 使用slf4j必須添加-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.27</version>
</dependency>
<!--slf4j 自带的简单日志实现 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.27</version>
</dependency>
2、编码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {

  public static void main(String[] args) {
    Logger logger = LoggerFactory.getLogger(HelloWorld.class);
    logger.info("Hello World");
  }
}

或使用 lombok 的注解 @Slf4j (编译后同样转化成上面的代码,仅简化了开发)

@Slf4j
public class HelloWorld {

  public static void main(String[] args) {
    log.info("Hello World");
  }
}

小结:

  • SLF4J 作为日志接口门面,规范并统一了日志接口。个人觉得未来在Java项目中很难有其替代者,很可能会有更好的日志实现框架出现。
  • 技术更迭十分快速,如果理解技术及相关产品的发展历程及主要解决什么问题,对越来越多的技术名词也不再特别恐惧。

参考文档:

SLF4J官网手册

java日志发展史 log4j slf4j log4j2 jul jcl 日志和各种桥接包的关系

Java 日志体系(二)jcl 和 slf4j

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

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

相关文章

Go学习圣经:Go语言实现高并发CRUD业务开发

说在前面&#xff1a; 现在拿到offer超级难&#xff0c;甚至连面试电话&#xff0c;一个都搞不到。 尼恩的技术社群中&#xff08;50&#xff09;&#xff0c;很多小伙伴凭借 “左手云原生右手大数据”的绝活&#xff0c;拿到了offer&#xff0c;并且是非常优质的offer&#…

APP/小程序嵌入游戏,游戏飞跃的赛道

APP/小程序接入游戏运营已不是新鲜事&#xff0c;然而&#xff0c;其仍具有巨大的发展潜力&#xff0c;尤其是社交类APP&#xff0c;多以加入娱乐游戏增加互动&#xff0c;获取目标客户&#xff0c;同时为产品增加变现渠道&#xff0c;实现双赢。 对于APP嵌入式游戏&#xff0…

Java之SpringCloud Alibaba【一】【Nacos一篇文章精通系列】

Java之SpringCloud Alibaba【一】【Nacos一篇文章精通系列】 一、微服务介绍1、系统架构演变1&#xff09;单体应用架构2&#xff09;垂直应用架构3&#xff09;分布式4&#xff09;SOA架构5&#xff09;微服务框架6&#xff09;常见微服务架构 2、SpringCloud Alibaba介绍3、S…

【C语言督学训练营 第十四天】二叉树真题实战 ----- 层序建树、前中后序遍历、求树的WPL

文章目录 前言树概念二叉树层序建树四种遍历二叉树的方式层次遍历前序遍历中序遍历后续遍历 真题实战&#xff01; 前言 今天进行总结的是考研408有关二叉树的基础知识&#xff0c;是王道C语言督学营的第十四天&#xff0c;随着课程的深入&#xff0c;代码实战的难度慢慢的上来…

MyCat01——如何实现MySQL中的主从复制

1 问题 数据对于我们来说是一项最重要的资产&#xff0c;因为数据丢失带来的损失&#xff0c;对于一家公司来说&#xff0c;有时也是毁灭性的。 那么如何确保数据安全&#xff0c;不因断电或系统故障带来数据丢失呢&#xff1f; 当用户增加&#xff0c;对数据库的访问量也随…

推荐一款好用的时序预测工具——Alibaba DChain Forecast

前言 绝大部分行业场景&#xff0c;尤其是互联网、量化行业&#xff0c;每天都会产生大量的数据。金融领域股票价格随时间的走势&#xff1b;电商行业每日的销售额&#xff1b;旅游行业随着节假日周期变化的机票酒店价格等。我们称这种不同时间收到的&#xff0c;描述一个或多…

Ajax技术的秘密揭秘:异步传输,高效交互

文章目录 I. 什么是AjaxAjax的定义和起源Ajax与传统的Web应用程序之间的区别 II. Ajax的工作原理Ajax的基本原理Ajax如何通过异步传输实现无需刷新页面 III. Ajax的应用场景在Web应用程序中应用Ajax的优势Ajax在哪些场景中使用 IV. Ajax的组成部分和APIXHR对象FormData对象Fetc…

用postman进行web端自动化测试

目录 前言 一、抓包&#xff08;使用Charles抓包工具&#xff09; 二、选择请求方法 三、填写url地址 四、填写Header 五、填写body 六、断言&#xff08;Tests页&#xff09; 七、获取动态参数——例如token 八、设置静态参数&#xff08;请求地址、账号密码等&#x…

【Django-功能优化】存储、循环、操作选择对代码性能的影响

功能开发背景 港口货轮需要进行集装箱的装卸任务&#xff1a; 船上的每一个集装箱&#xff0c;可以用三个维度的坐标来唯一定位&#xff1a;(bay, column, layer)&#xff0c;这三个维度结合其他一些固有信息&#xff0c;构成了一个箱子的字段属性&#xff0c;存储在箱子数据表…

百度的人脸识别的技术

百度的人脸识别的技术 1.基本概念 分组&#xff1a;分组ID&#xff08;group_id&#xff09;&#xff1a;分组ID用于对一组相关的人脸进行分组和管理。你可以根据自己的需求&#xff0c;将不同的人脸数据分配到不同的分组中。例如&#xff0c; 你可以根据人员的职位、部门或其…

Nginx优化安全防盗链

1.Nginx的页面优化 1.1 Nginx的网页压缩 在Nginx的ngx_http_gzip_module压缩模块提供对文件内容压缩的功能。进行相关的配置修改&#xff0c;就能实现Nginx页面的压缩&#xff0c;达到节约带宽&#xff0c;提升用户访问速度 1.2 配置Nginx的图片缓存 当Nginx将网页数据返回给…

阿里云企业邮箱免费版、标准版、集团版和尊享版区别

阿里云企业邮箱版本分为免费版、标准版、集团版和尊享版&#xff0c;除了价格区别&#xff0c;功能方面有什么差异&#xff1f;如何选择企业邮箱版本&#xff1f;免费版0元适合初创型企业&#xff0c;标准版适合大、中、小型企业使用&#xff0c;涉及子公司之间邮箱通讯可以选择…

jQuery学习

原生实现计数器 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-wi…

getopt_long 函数的使用

getopt_long 函数的使用网上已经有很多了&#xff0c;这里只是记录一下方便自己后续查找。首先函数原型声明&#xff1a; #include <getopt.h>int getopt_long(int argc, char *argv[],const char *optstring,const struct option *longopts, int *longindex); 函数是用…

Navicat使用导入向导批量插入数据到数据库

Mybatis,"可持久层数据库框架" Html,"超文本标记语言" Css,"网页外设计语言" JavaScript,"用户行为交互" Jquery,"提升网页开发效率的一种框架" Vue,"前端开发框架" Vant,"前开发预装组件库" git,"…

SM2算法对比RSA算法,有哪些优势?

SM2算法和RSA算法都是公钥密码算法&#xff0c;SM2算法是一种更先进安全的算法&#xff0c;在安全性能、速度性能等方面都优于RSA算法&#xff0c;在我国商用密码体系中被用来替换RSA算法。国家密码管理局于2010年12月17日发布了SM2算法&#xff0c;并要求现有的基于RSA算法的电…

《面试1v1》Redis基础

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

Golang/Python 调用 openAI 的API 详解

学习目标&#xff1a; OpenAI API介绍 学习如何通过 Golang 使用 OpenAI 的 API OpenAI 的常用的参数及其说明 了解OpenAI API 中令牌&#xff08;tokens) OpenAI API 提供了几个不同的终端点&#xff08;endpoints&#xff09;和模式&#xff08;modes&#xff09; 复杂和…

【已解决】Java 中导入excel时使用 trim() 无法去除空格的解决方法

使用trim无法去除空格的解决方法 一、问题描述二、原因分析三、解决方案方案一&#xff1a;使用正则表达式方案二&#xff1a;使用String.strip()方案三&#xff1a;使用 hutool的 StrUtil.trim()方法 四、总结 一、问题描述 在excel导入操作时&#xff0c;读取cell中的字符串…

自学Python 69 Selenium八大元素定位方法(新版BY方法)

Python Selenium八大元素定位方法(新版BY方法) 文章目录 Python Selenium八大元素定位方法(新版BY方法)前言一、常用的八种定位方法&#xff08;新旧对比&#xff09;二、查看网页元素三、八大元素定位示例1、id定位2、name定位3、class定位4、tag定位5、link定位6、partial_li…