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);

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

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

相关文章

【深入理解 ByteBuf 之三 接口类拆解】2. Recycler 接口设计真正的回收机制

Recycler 回收器接口设计 本节接着 ObjectPool 的设计脉络,具体看看其具体实现 RecyclerObjectPool 中引用的 Recycler 究竟是怎么实现的 这一张图基本已经说明白了,我再做个总结,对细节感兴趣的可以看看我下面带源码的注释。 对于 Recycle…

2023.1.15 关于 Redis 持久化 RDB 策略详解

目录 Redis 持久化 Redis 实现持久化的两大策略 RDB 策略 手动触发 save 命令 bgsave 命令 bgsave 命令执行流程 自动触发 rdb 文件 实例演示一 实例演示二 实例演示三 实例演示四 RDB 策略的优缺点 Redis 持久化 什么是持久化? 回答: 将数据存…

SeaTunnel 海量数据同步工具的使用(连载中……)

一、概述 SeaTunnel 是一个非常易用,高性能、支持实时流式和离线批处理的海量数据处理产品,前身是 WaterDrop (中文名:水滴),自 2021年10月12日更名为 SeaTunnel 。2021年12月9日,SeaTunnel 正式…

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

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

STM32 USB OTG主机模式的实现方法

为了实现STM32的USB OTG主机模式,我们首先需要了解一些基本概念和原理,然后进行相应的硬件连接和软件编程。在这篇文章中,我们将介绍如何在STM32微控制器上实现USB OTG主机模式,并提供相应的代码示例。 1. STM32 USB OTG主机模式…

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…

教你用通义千问只要五步让千年的兵马俑跳上现代的科目三?

教你用五步让千年的兵马俑跳上现代的舞蹈科目三? 上面这个“科目三”的视频,只用了一张我上月去西安拍的兵马俑照片生成的。 使用通义千问,只要5步就能它舞动起来,跳上现在流行的“科目三”舞蹈。 全民舞王 第1步 打开通义千问…

【Spring实战】29 @Value 注解

文章目录 1. 定义2. 好处3. 示例1)注入基本类型2)注入集合类型3)使用默认值4)注入整数和其他类型 总结 在实际的应用中,我们经常需要从外部配置文件或其他配置源中获取参数值。Spring 框架提供了 Value 注解&#xff0…

《DAMA数据管理知识体系指南》05—第5章 数据建模和设计 知识点记录

第5章 数据建模和设计 5.1 引言 1.数据建模概要: 1)本章将描述数据模型的用途、数据建模中的基本概念和常用词汇以及数据建模的目标和原则。本章将使用一组与教育相关的数据作为案例来说明用各种数据建模的方法,并介绍它们之间的差异。 2&a…

如何用Mac工具制作“苹果高管形象照”

大伙儿最近有没有刷到“苹果高管形象照”风格,详细说来就是: 以苹果官网管理层简介页面中,各位高管形象照为模型,佐以磨皮、美白、高光等修图术,打造的看上去既有事业又有时间有氧的证件照,又称“苹…

OpenCV-25sobel算子(索贝尔算子)

前面所提到的滤波都是用于降噪的,去掉噪声,而算子是用来找边界,来识别图像的边缘。 一、概念 边缘是像素值发生跃迁的值,是图像的显著特点之一,在图像特征提取,对象检测,模式识别等方面都有重…

Vue3响应式系统(一)

一、副作用函数。 副作用函数指的是会产生副作用的函数。例如:effect函数会直接或间接影响其他函数的执行,这时我们便说effect函数产生了副作用。 function effect(){document.body.innerText hello vue3 } 再例如: //全局变量let val 2f…

Alist开源网盘搭建

官网:https://alist.nn.ci/zh/github下载地址:https://github.com/alist-org/alist/releases gitcode上也提供了源码:https://gitcode.com/mirrors/alist-org/alist/tags 源码安装使用自己研究,这里不讲解,较为复杂 我使⽤的版本:v3.29.1 我的下载地址:…

websocket项目 聊天室

1.项目概述 这个项目是一个基本的实时聊天应用,适用于小型团队或群体。提供了多个聊天室供用户选择。可以通过该代码进行进一步的扩展和定制,例如添加聊天机器人、改进界面等。 2.技术栈 flask,boostrapt,websocket&#xff0c…

大语言模型下载,huggingface和modelscope加速

huggingface 下载模型 如果服务器翻墙了,不用租机器 如果服务器没翻墙,可以建议使用下面的方式 可以租一台**autodl**不用显卡的机器,一小时只有1毛钱,启动学术加速,然后下载,下载完之后,用scp…

芯片烧写工具

问题描述 最近出了一个机器变砖的问题,一些用户使用的设备,头一天晚上用的好好的,第二天来一上电开机就起不来了。 然后就寄回来,返厂维修。一些是因为部分电子器件坏了,还有一些是文件系统问题,重新升级一…

GIT SourceTree 回滚提交

步骤一: 步骤二: 步骤三: 在终端输入命令(位置是项目目录下) git push origin feature_mo2.1_r3_zhanx653 -f

深圳三维扫描分析/偏差检测模具型腔三维尺寸及形位偏差测量公司

CASAIM中科广电三维扫描模具型腔深圳案例: 模具型腔的三维扫描分析/偏差检测是一项重要的质量控制过程,旨在确保模具制造过程中的精确度和一致性。 CASAIM中科广电通过使用高精度的三维扫描设备,可以获取模具型腔的实际形状和尺寸数据&…

Python - 深夜数据结构与算法之 LRUCache

目录 一.引言 二.LRU Cache 简介 1.实现特性 2.工作流程 三.LRU Cache 实战 1.HashMap ListNode 2.OrderedDict 四.总结 一.引言 LRU 即 Least Recently Used 意为最近使用,它是一种局部 Cache 的缓存方法,用于存储最近使用的元素,…

Java 实现双链表

文章目录 双链表(Doubly Linked List)是一种常用的数据结构,它与单链表相似,但每个节点除了包含指向下一个节点的指针外,还包含一个指向前一个节点的指针。 双链表的节点由三部分组成:数据域(存…