Java 日志体系泣血总结

目录

一. 前言

二. Log 日志体系

2.1. 背景/发展史

2.2. 关系/依赖

2.2.1. JCL(Jakarta Commons Logging)

2.2.2. SLF4J

2.2.3. SLF4J 的适配

2.2.4. Spring 统一输出

三. 总结


一. 前言

    本文的目的是搞清楚 Java 中各种日志 Log 之间是怎样的关系,如何作用、依赖,好让我们平时在工作中如果遇到“日志打不出”或者“日志 jar 包冲突”等之类的问题知道该如何入手解决,以及在各种场景下如何调整项目中的各个框架的日志输出,使得输出统一。

二. Log 日志体系

    在日常工作中我们可能看到项目中依赖的跟日志相关的 jar 包有很多:commons-logging.jar、log4j.jar、sl4j-api.jar、logback.jar 等等,眼花缭乱。我们要正确的配置,使用 jar 包相互作用生效之前,就先要理清它们之间的关系。

2.1. 背景/发展史

那就要从 Java Log 的发展历程开始说起。

1. log4j(作者 Ceki Gülcü)出来时就得到了广泛的应用(注意这里是直接使用),是 Java 日志事实上的标准,并成为了 Apache 的项目。

2. Apache 要求把 log4j 并入到 JDK,SUN 拒绝,并在 JDK1.4 版本后增加了 JUL(java.util.logging)。

3. 毕竟是 JDK 自带的,JUL 也有很多人用。同时还有其他日志组件,如 SimpleLog 等。这时如果有人想换成其他日志组件,如 log4j 换成 JUL,因为 api 完全不同,就需要改动代码。

4. Apache 见此,开发了 JCL(Jakarta Commons Logging),即 commons-logging-xx.jar。它只提供一套通用的日志接口 api,并不提供日志的实现。很好的设计原则嘛,依赖抽象而非实现。这样应用程序可以在运行时选择自己想要的日志实现组件。

5. 这样看上去也挺美好的,但是 log4j 的作者觉得 JCL 不好用,自己开发出 slf4j,它跟 JCL 类似,本身不提供日志具体实现,只对外提供接口或门面。目的就是为了替代 JCL。同时,还开发出logback,一个比 log4j 拥有更高性能的组件,目的是为了替代 log4j。

6. Apache 参考了 logback,并做了一系列优化,推出了 log4j2,性能远超 logbak。

2.2. 关系/依赖

大概了解心路历程后,再详细看看它们之间的关系、依赖。

2.2.1. JCL(Jakarta Commons Logging)

commons-logging 已经停止更新,最后的状态如下所示:

JCL 支持日志组件不多,不过也还是有很人用的,只是现在用的人越来越少了,就不多讲了。

2.2.2. SLF4J

    因为当时 Java 的日志组件比较混乱繁杂,Ceki Gülcü 推出 slf4j 后,也相应为行业中各个主流日志组件推出了 slf4j 的适配,图来源于官方文档:

slf4j 适配

图的意思为,如果你想用 slf4j 作为日志门面的话,你如何去配合使用其他日志实现组件,这里说明一下(注意 jar 包名缺少了版本号,在找版本时也要注意版本之间是否兼容)。

  1. slf4j + logback:slf4j-api.jar + logback-classic.jar + logback-core.jar。
  2. slf4j + log4j:slf4j-api.jar + slf4j-log4j12.jar + log4j.jar。
  3. slf4j + jul:slf4j-api.jar + slf4j-jdk14.jar。
  4. 也可以只用 slf4j 无日志实现 slf4j-api.jar + slf4j-nop.jar。

2.2.3. SLF4J 的适配

    slf4j 支持各种适配,无论你现在是用哪种日志组件,你都可以通过 slf4j 的适配器来使用上slf4j。只要你切换到了 slf4j,那么再通过 slf4j 用上实现组件,即上面说的。图来源于官方文档:

其实总的来说,无非就是以下几种情况:

  1. 你在用 JCL 时,使用 jcl-over-slf4j.jar 适配。
  2. 你在用 log4j 时,使用 log4j-over-slf4j.jar 适配。
  3. 你在用 JUL 时,使用 jul-to-slf4j.jar 适配。

给大家一个整体的依赖图:

2.2.4. Spring 统一输出

    这就是为了对 slf4j 的适配做一个例子说明。Spring 是用 JCL 作为日志门面的,那我们的应用是slf4j + logback,怎么让 Spring 也用到 logback 作为日志输出呢?这样的好处就是我们可以统一项目内的其他模块、框架的日志输出(日志格式,日志文件,存放路径等,以及其他 slf4j 支持的功能),很简单,就是加入 jcl-over-slf4j.jar 就好了。请看下图:

适配思路:

  1. 你首先确认需要统一日志的模块、框架是使用哪个日志组件的,然后再找到 sfl4j 的适配器。
  2. 记得去掉无用的日志实现组件,只保留你要用的。

三. 总结

    slf4j 的日志加载会在程序启动时把日志打出来,所以一定要注意,它会说明加载是否成功,加载了那个日志实现。slf4j 已经对错误作了说明,下面讲一下可能经常遇到的问题。

1. Failed to load class org.slf4j.impl.StaticLoggerBinder

    没找到日志实现,如果你觉得你已经写上了对应的日志实现依赖了,那你要检查一下了,一般来说极有可能是版本不兼容。

2. Multiple bindings

    找到多个日志实现,slf4j 会找其中一个作为日志实现。

3. 阿里对此的代码规范

【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架 SLF4J 中的 API,
使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

private static final Logger logger = LoggerFactory.getLogger(Abc.class);

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

spring boot mybatis-plus dynamic-datasource 配置文件 相关依赖环境配置

spring boot mybatis-plus dynamic-datasource 配置文件 相关依赖环境配置 ##yaml配置 server:port: 8866servlet:context-path: /yymtomcat:max-threads: 300connection-timeout: 57000max-connections: 500connection-timeout: 57000 spring:datasource:dynamic:primary: m…

MyBatis 查询数据库

一. MyBatis 框架的搭建 本篇所用sql 表: drop table if exists userinfo; create table userinfo(id int primary key auto_increment,username varchar(100) not null,password varchar(32) not null,photo varchar(500) default ,createtime timestamp default current_tim…

SpringBoot 全局异常统一处理:BindException(绑定异常)

概述 在Spring Boot应用中,数据绑定是一个至关重要的环节,它负责将HTTP请求中的参数映射到控制器方法的入参对象上。在这个过程中如果遇到任何问题,如参数缺失、类型不匹配或验证失败等,Spring MVC将会抛出一个org.springframewo…

Hive 数据迁移

一、需求 同步集团的数据到断直连环境。 二、思路 三、同步数据(方案) 1、环境:断直连模拟环境 2、操作机器:ETL 机器 XX.14.36.216 3、工作路径:cd /usr/local/fqlhadoop/hadoop/bin 4、执行命令: 命令…

python 元组的详细用法

当前版本: Python 3.8.4 文章目录如下 1. 介绍元组 2. 定义元组 3. 访问元组 4. 查询元组 1. 介绍元组 元组(Tuple)是一个有序的、不可变的数据序列。它可以包含各种类型的数据,例如数字、字符串、列表等。元组使用圆括号()来…

书生·浦语大模型实战营第四节课笔记及作业

XTuner 大模型单卡低成本微调实战 1 Finetune简介 大语言模型LLM是在海量的文本内容基础上,以无监督或半监督方式进行训练的。海量的文本内容赋予了大模型各种各样的行业知识。但是如果直接把大模型的知识用于生产实践,会发现回答不大满意。微调的目的…

【RL】(task1)绪论、马尔科夫过程、动态规划、DQN(更新中)

note 文章目录 note一、马尔科夫过程二、动态规划DQN算法时间安排Reference 一、马尔科夫过程 递归结构形式的贝尔曼方程计算给定状态下的预期回报,这样的方式使得用逐步迭代的方法就能逼近真实的状态/行动值。 有了Bellman equation就可以计算价值函数了马尔科夫过…

微服务架构设计核心理论:掌握微服务设计精髓

文章目录 一、微服务与服务治理1、概述2、Two Pizza原则和微服务团队3、主链路规划4、服务治理和微服务生命周期5、微服务架构的网络层搭建6、微服务架构的部署结构7、面试题 二、配置中心1、为什么要配置中心2、配置中心高可用思考 三、服务监控1、业务埋点的技术选型2、用户行…

Burp Suite如何拦截站点请求

Burp Suite是一款强大的Web渗透测试工具,可以用于拦截、修改和分析Web应用程序的请求和响应。要使用Burp Suite拦截站点请求有两个方案。我会倾向选用方案二,因为它不会影响本地电脑代理配置。 1. 方案一 安装Burp Suite:首先,您…

【C语言】ipoib驱动 - ipoib_cm_post_receive_nonsrq_rss函数

一、ipoib_cm_post_receive_nonsrq_rss函数定义 static int ipoib_cm_post_receive_nonsrq_rss(struct net_device *dev,struct ipoib_cm_rx *rx, int id) {struct ipoib_dev_priv *priv ipoib_priv(dev);struct ipoib_recv_ring *recv_ring priv->recv_ring rx->ind…

提升开发效率的google插件

在如今的软件开发领域,Google Chrome浏览器的开发者插件扮演着至关重要的角色,为开发人员提供了丰富的工具和功能,从而提高了开发效率。下面介绍几款强大的 Google 插件,它们在不同方面为开发者提供了便利,并能显著提升…

力扣每日一题--2088. 统计农场中肥沃金字塔的数目

看到这道题有些人很容易放弃,其实这道题不是很难,主要是题目长,读的容易让人放弃,但是 只要抓住一些性质就可以解决该问题。 本题中的定义放到图像里其实就是个金字塔,下层的那部分比上一层的那部分,长度加…

51单片机HC-SR04超声波测距lcd1602显示(程序+ad硬件设计+文档说明)

本帖主控使用STC89C52单片机,超声波测距采用HC-SR04模块,包含ad硬件设计和文档。 测距原理 超声波测距是通过不断检测超声波发射后遇到障碍物所反射的回波,从而测出发射和接收回波的时间差t,然后求出距SCt/2,式中的C为超声波波速。由于超声…

【GitHub】如何删除GitHub仓库里的文件夹(区分 rm/git rm)

删除GitHub仓库里的一个文件夹 1、复制仓库地址2、在本地新建一个空文件夹3、在空文件夹内,右键选择Git Bash Here4、弹出GIT Bash框5、克隆远程仓库6、拉取远程仓库7、查看仓库里的文件8、选择想要删除的文件夹进行删除9、提交删除说明10、更新GitHub远程仓库 在gi…

微信小程序-----wxss模版样式

目录 前言 一、WXSS 1. 什么是 WXSS 2. WXSS 和 CSS 的关系 二、rpx 1. 什么是 rpx 尺寸单位 2. rpx 的实现原理 3. rpx 与 px 之间的单位换算 三、样式导入 1. 什么是样式导入 2. import 的语法格式 四、全局样式和局部样式 1. 全局样式 2. 局部样式 前言 上一期…

伪装目标检测模型论文阅读之:Zoom in and out

论文链接:https://arxiv.org/abs/2203.02688 代码;https://github.com/lartpang/zoomnet 1.摘要 最近提出的遮挡对象检测(COD)试图分割视觉上与其周围环境融合的对象,这在现实场景中是非常复杂和困难的。除了与它们的背景具有高…

漏洞复现-金和OA jc6/servlet/Upload接口任意文件上传漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

【RT-DETR有效改进】ShapeIoU、InnerShapeIoU关注边界框本身的IoU(包含二次创新)

前言 大家好,我是Snu77,这里是RT-DETR有效涨点专栏。 本专栏的内容为根据ultralytics版本的RT-DETR进行改进,内容持续更新,每周更新文章数量3-10篇。 专栏以ResNet18、ResNet50为基础修改版本,同时修改内容也支持Re…

【Linux】Linux系统编程——pwd命令

文章目录 1.命令概述2.命令格式3.常用选项4.相关描述5.参考示例 1.命令概述 pwd(Print Working Directory)命令用于显示用户当前工作目录的完整路径。这是一个常用的命令,帮助用户确定他们目前所在的目录位置。 2.命令格式 基本的 pwd 命令…

基于Redis+Lua的分布式限流

本文已收录至我的个人网站:程序员波特,主要记录Java相关技术系列教程,共享电子书、Java学习路线、视频教程、简历模板和面试题等学习资源,让想要学习的你,不再迷茫。 前面我们了解了如何利用Nginx做网关层限流&#xf…