Java日志框架介绍

​今天来聊一聊 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.hqwc.cn/news/1898.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库的操作

前言 在之前的文章中&#xff0c;我们已经了解了什么是数据库&#xff0c;以及为什么有数据库&#xff0c;和数据库有什么作用&#xff0c;有了这些宏观概念之后&#xff0c;本章为大家进一步详细介绍对于数据库在Linux上如何具体操作。 1.创建数据库 1.1创建数据库语法 语法…

MyBatis-Plus:条件构造器Wrapper

目录 1.Wrapper概述 1.1.Wrapper的继承关系 1.2.Wapper介绍 1.3.各个构造器使用区别 1.4.构造器常用方法 2.Wrapper常用构造器介绍 2.1.QueryWrapper 2.2.UpdateWrapper 2.3.LambdaQueryWrapper 2.4.AbstractWrapper 3. Lambda条件构造器 3.1.示例 4.鸣谢 MyBati…

Spring Boot 如何使用 Spring Security 进行认证和授权

Spring Boot 如何使用 Spring Security 进行认证和授权 在 Web 应用程序中&#xff0c;认证和授权是非常重要的功能。Spring Security 是一个基于 Spring 框架的强大的安全框架&#xff0c;它提供了完整的认证和授权解决方案&#xff0c;并且可以轻松地集成到 Spring Boot 应用…

服务器编程:数据库连接池

引言&#xff1a; 数据库连接池和线程池的思想一样&#xff0c;是为了避免频繁创建和销毁数据库连接导致的性能开销。如果一个项目频繁的需要访问数据库&#xff0c;那么它就有可能需要频繁的创建/销毁数据库连接&#xff0c;那么我们可以采用数据库连接池的技术&#xff0c;在…

【几何数学】【Python】【C++】将线段沿着线段方向延长一定长度,求新的点

p1点和p2点是一条线段的两端&#xff0c;沿着p1指向p2的方向&#xff0c;将线段长度延伸长度x&#xff0c;求延伸后的点ep。如下图&#xff1a; Python代码&#xff1a; import mathdef extend_line_segment(p1, p2, extension_length):"""延伸线段长度并返回…

Redis各数据类型操作命令

一、Redis数据类型及命令 &#xff08;一&#xff09;String 类别命令描述命令示例备注取/赋值操作赋值set key valueset lclkey lclvalue取值 get keyget lclkey取值并赋值getset key valuegetset lclkey1 lclvalue1获取原值&#xff0c;并设置新的值仅当不存在时赋值setnx k…

多元回归预测 | Matlab海洋捕食者算法(MPA)优化极限学习机ELM回归预测,MPA-ELM回归预测,多变量输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元回归预测 | Matlab海洋捕食者算法(MPA)优化极限学习机ELM回归预测,MPA-ELM回归预测,多变量输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码 %% …

Java 实现word、excel、ppt、txt等办公文件在线预览功能!

如何用 Java 实现word、excel、ppt、txt等办公文件在线预览功能&#xff1f;本文告诉你答案&#xff01; java 实现办公文件在线预览功能是一个大家在工作中也许会遇到的需求&#xff0c;网上些公司专门提供这样的服务&#xff0c;不过需要收费。 如果想要免费的&#xff0c;…

设计模式第19讲——命令模式(Command)

目录 一、什么是命令模式 二、角色组成 三、优缺点 四、应用场景 4.1 生活场景 4.2 java场景 五、代码实现 5.0 代码结构 5.1 抽象命令&#xff08;Command&#xff09;——Command 5.2 接收者&#xff08;Receiver&#xff09;——Chef 5.3 具体命令&#xff08;Co…

【读书笔记】《软件工程导论》

目录 一、软件工程概述 二、启动阶段 三、计划阶段 四、实施阶段 五、收尾阶段 一、软件工程概述 软件危机&#xff1a;在计算机软件的开发和维护过程中遇到的一系列严重问题。 软件危机的产生与自身的特点有关&#xff0c;还与软件开发、管理的方法不正确有关。 软件危…

Go语言并发微服务分布式高可用

Go语言并发微服务分布式高可用 Go语言基础 环境安装 命令行输入go&#xff0c;当前操作系统Os环境中依赖于PATH指定的日录们去找命令(可执行文件)windows会优先搜索当前日录&#xff0c;当前日录没有才依赖PATH中指定的日录 环境变量: 操作系统运行环境中提前定义好的变量P…

6-js基础-3

JavaScript 基础 - 3 知道什么是数组及其应用的场景&#xff0c;掌握数组声明及访问的语法&#xff0c;具备利用数组渲染柱形图表的能力 今日重点&#xff1a; 循环嵌套数组综合案例 今日单词&#xff1a; 循环嵌套 利用循环的知识来对比一个简单的天文知识&#xff0c;我们…