Java - 日志体系_Simple Logging Facade for Java (SLF4J)日志门面_SLF4J实现原理分析

news2025/4/13 18:06:14

文章目录

  • 官网
  • SLF4J 简单使用案例分析
  • SLF4J 获取 `Logger` 的原理
    • 获取 `ILoggerFactory` 的过程
    • 获取 `Logger` 的过程
    • SLF4J 与底层日志框架的集成
  • 小结

在这里插入图片描述


官网

https://slf4j.org/

在这里插入图片描述

Simple Logging Facade for Java (SLF4J) 用作各种日志记录框架(e.g. java.util.logging、logback、log4j)的简单外观或抽象,允许最终用户在部署时插入所需的日志记录框架 时间。

请注意,启用 SLF4J 的库意味着仅添加一个强制依赖项,即 slf4j-api.jar。 如果在类路径上找不到绑定/提供程序,则 SLF4J 将 default 为 no-operation 实现。


SLF4J user manual:https://slf4j.org/manual.html

在这里插入图片描述


SLF4J 简单使用案例分析

在这个简单的使用案例中,SLF4J 的 LoggerFactory.getLogger() 被用来获取一个 Logger 实例,用于记录不同级别的日志信息。


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


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

public static void main(String[] args) {
    if (logger.isDebugEnabled()) {
        logger.debug("slf4j-log4j debug message");
    }
    if (logger.isInfoEnabled()) {
        logger.info("slf4j-log4j info message");
    }
    if (logger.isTraceEnabled()) {
        logger.trace("slf4j-log4j trace message");
    }
}
  • LoggerFactory.getLogger() 是获取日志记录器的入口方法,它返回一个实现了 Logger 接口的对象。
  • 日志级别通过 isDebugEnabled(), isInfoEnabled(), 和 isTraceEnabled() 方法进行判断。

SLF4J 获取 Logger 的原理

LoggerFactory.getLogger() 方法的核心实现如下:

/**
 * 获取指定名称的日志记录器
 * 
 * @param name 日志记录器的名称,通常与类名或模块名相对应
 * @return 返回一个具有指定名称的Logger对象
 * 
 * 此方法通过委托给全局的ILoggerFactory实例来获取Logger对象
 * 使用工厂模式允许日志实现的灵活配置和扩展
 */
public static Logger getLogger(String name) {
    // 获取ILoggerFactory实例,该实例负责创建和管理Logger对象
    ILoggerFactory iLoggerFactory = getILoggerFactory();
    // 调用工厂的getLogger方法,根据名称获取对应的Logger对象
    return iLoggerFactory.getLogger(name);
}

获取 ILoggerFactory 的过程

/**
 * 获取ILoggerFactory实例
 * 该方法通过调用getProvider()方法获取一个日志工厂提供者,并从该提供者中获取一个ILoggerFactory实例
 * 主要用于日志功能的配置和管理
 * 
 * @return ILoggerFactory 实例,用于创建和管理日志记录器
 */
public static ILoggerFactory getILoggerFactory() {
    return getProvider().getLoggerFactory();
}

获取 ILoggerFactory 实例的过程较为复杂,它涉及到以下几个步骤:

  1. 查找 StaticLoggerBinder
    SLF4J 需要通过 ClassLoader 查找 org/slf4j/impl/StaticLoggerBinder.class 类。StaticLoggerBinder 是 SLF4J 与底层日志框架(如 logbacklog4j)绑定的核心类。

    ClassLoader.getSystemResources("org/slf4j/impl/StaticLoggerBinder.class");
    
  2. 检查是否存在多个绑定
    如果类路径中存在多个 StaticLoggerBinder 类文件,SLF4J 会输出警告信息,告诉用户存在多个日志框架绑定的情况。例如:

    SLF4J: Class path contains multiple SLF4J bindings.
    SLF4J: Found binding in [slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: Found binding in [logback-classic-1.1.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: Found binding in [slf4j-jdk14-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
    SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
    

    上述警告表示类路径中找到多个绑定,SLF4J 会随机选择一个日志框架进行绑定。最终的实际绑定类型会在警告中明确标示。


  1. 获取 StaticLoggerBinder 的单例
    SLF4J 会通过 StaticLoggerBinder.getSingleton() 方法获取 StaticLoggerBinder 的单例实例。

    StaticLoggerBinder.getSingleton();
    

  1. 获取 ILoggerFactory 实例
    StaticLoggerBinder 的单例中,获取实际的 ILoggerFactory 实例。

    StaticLoggerBinder.getSingleton().getLoggerFactory();
    

获取 Logger 的过程

ILoggerFactory 是一个工厂类,负责根据指定的名称返回 Logger 实例。它的实现类(例如 Log4jLoggerFactory, LogbackLoggerFactory)根据所绑定的日志框架不同返回不同类型的 Logger

public interface ILoggerFactory {
    Logger getLogger(String name);
}

SLF4J 与底层日志框架的集成

SLF4J 的设计允许它与多种底层日志框架进行集成。通常,SLF4J 会提供 org/slf4j/impl/StaticLoggerBinder.class 类来绑定一个具体的日志框架(如 log4jlogback)。以下是 SLF4J 如何与常见的日志框架集成的原理:

  1. Logback 集成
    SLF4J 默认与 logback 集成。logback-classic 包含了 StaticLoggerBinder 类,该类会返回一个 LogbackLoggerFactory 实例,进一步返回 LogbackLogger

  2. Log4j 集成
    如果类路径中包含 slf4j-log4j12 包,SLF4J 会将日志记录请求转发给 Log4j,而 StaticLoggerBinder 会返回 Log4jLoggerFactory 实例。

  3. 多个绑定警告
    如果类路径中包含多个日志框架的绑定(如 logbacklog4j),SLF4J 会随机选择其中一个框架进行绑定。这个选择是由 JVM 的类加载机制决定的,并且会在控制台输出警告。


小结

  • SLF4J 通过 StaticLoggerBinder 类在运行时决定与哪个底层日志框架(如 logbacklog4j)绑定。
  • LoggerFactory.getLogger() 会通过 ILoggerFactory 获取具体的 Logger 实例,这个过程包括查找 StaticLoggerBinder 类并获取其单例。
  • SLF4J 允许同时存在多个日志框架的绑定,但只会选择其中一个,并通过警告通知用户存在多个绑定的情况。
  • 在 SLF4J 中,日志框架的选择是通过类路径中 StaticLoggerBinder 类的存在与否来决定的,最终的日志实现由 LoggerFactory 返回的 Logger 实例确定。

在这里插入图片描述

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

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

相关文章

HALCON中用于分类的高斯混合模型create_class_gmm

目录 一、创建用于分类的高斯混合模型函数二、代码和效果展示三、相关函数 一、创建用于分类的高斯混合模型函数 create_class_gmm( : : NumDim, NumClasses, NumCenters, CovarType, Preprocessing, NumComponents, RandSeed : GMMHandle)create_class_gmm创建用于分类的高斯…

在实际开发中,如何权衡选择使用哪种数据结构和算法?

学习数据结构与算法有一段时间了,听音频、看视频、看专栏、看书、抄书,尝试了很多种方法,今天在 专栏 中看到一篇文章,觉得很不错,摘抄如下。 学习数据结构和算法,不要停留在学院派的思维中,只把…

Airbnb/Booking 系统设计(high level architecture)

原文地址 CodeKarle: Airbnb System Design | Booking.com System Design B站搜 “Airbnb System Design” 有视频版本 需求: 功能性需求 系统用户包括商家和客人。 Hotel - 商家(拥有hotel的人) onboarding - 商家可以入住系统。 update…

如何在谷歌浏览器中清理无效的扩展

谷歌浏览器是一款功能强大且广受欢迎的网络浏览器,它允许用户安装各种扩展来增强功能。然而,随着时间的推移,一些扩展可能变得无效或不再需要,这时就需要清理这些无效的扩展以减少浏览器的负担并提升性能。 一、步骤详解 1. 打开…

MySQLOCP考试过了,题库很稳,经验分享。

前几天,本人参加了Oracle认证 MySQLOCP工程师认证考试 ,先说下考这个证书的初衷: 1、首先本人是从事数据库运维的,今年开始单位逐步要求DBA持证上岗。 2、本人的工作是涉及数据库维护,对这块的内容比较熟悉&#xff…

艾体宝产品丨加速开发:Redis 首款 VS Code 扩展上线!

Redis 宣布推出其首款专为 VS Code 设计的 Redis 扩展。这一扩展将 Redis 功能直接整合进您的集成开发环境(IDE),旨在简化您的工作流程,提升工作效率。 我们一直致力于构建强大的开发者生态系统,并在您工作的每一步提…

银河麒麟系统安装Wireshark抓包工具

麒麟系统安装Wireshark抓包工具 1. 麒麟SP1安装Wireshark 【1】. 安装Wireshark 在线安装wireshark 命令如下: apt-get install wireshark-qt软件包设置 弹出对话框,选择【是】选项。 安装完成。 【2】. 使用Wireshark 如果是普通用户,…

WPF 绘制过顶点的圆滑曲线 (样条,贝塞尔)

在一个WPF项目中要用到样条曲线,必须过顶点,圆滑后还不能太走样,捣鼓一番,发现里面颇有玄机,于是把我多方抄来改造的方法发出来,方便新手: 如上图,看代码吧: ----------…

Redis--持久化策略(AOF与RDB)

持久化策略(AOF与RDB) 持久化Redis如何实现数据不丢失?RDB 快照是如何实现的呢?执行时机RDB原理执行快照时,数据能被修改吗? AOF持久化是怎么实现的?AOF原理三种写回策略AOF重写机制 RDB和AOF合…

学习路之VScode--自定义按键写注释(插件)

1. 安装 "KoroFileHeader" 插件 首先,在 VScode 中搜索并安装名为 "KoroFileHeader" 的插件。你可以通过在扩展商店中搜索插件名称来找到并安装它。 2. 进入 VScode 设置页面 点击 VScode 左下角的设置图标,然后选择 "设置&q…

开源电子书转有声书整合包ebook2audiobookV2.0.0

ebook2audiobook:将电子书转换为有声书的开源项目 项目地址 GitHub - DrewThomasson/ebook2audiobook 整合包下载 更新至v2.0.0 https://pan.quark.cn/s/22956c5559d6 修改:页面已转为中文 项目简介 ebook2audiobook 是一个开源项目,它能够将电子…

3.5mm耳机接口硬件连接

结构 以最复杂的结构为例 简单的结构无非就是没有MIC(麦克风)接口 上图的5就是Detect的作用 上面这两款产品都为3.5mm的音频插座,图一 为连接4节的音频座,而且有两个开关,1接地,2接MIC,3接左声…

【贪心算法】贪心算法七

贪心算法七 1.整数替换2.俄罗斯套娃信封问题3.可被三整除的最大和4.距离相等的条形码5.重构字符串 点赞👍👍收藏🌟🌟关注💖💖 你的支持是对我最大的鼓励,我们一起努力吧!😃&#x1f…

一文大白话讲清楚CSS元素的水平居中和垂直居中

文章目录 一文大白话讲清楚CSS元素的水平居中和垂直居中1.已知元素宽高的居中方案1.1 利用定位margin:auto1.2 利用定位margin负值1.3 table布局 2.未知元素宽高的居中方案2.1利用定位transform2.2 flex弹性布局2.3 grid网格布局 3. 内联元素的居中布局 一文大白话讲清楚CSS元素…

30. 区间交集

题目描述 给定一组闭区间,其中部分区间存在交集。 任意两个给定区间的交集,称为公共区间(如:[1,2],[2,3]的公共区间为[2,2],[3,5],[3,6]的公共区间为[3,5])公共区间之间若存在交集,则需要合并(如:[1,3],[3,5]区间存在交集[3,3],需合并为[1,5]…

redis cluster实验详解

华子目录 实验环境准备部署redis cluster添加节点删除节点redis cluster集群维护 实验 环境准备 再开3台主机 先把之前3台源码编译的redis删除 [rootredis-node1 ~]# cd /usr/local/redis/ [rootredis-node1 redis]# make uninstall[rootredis-node2 ~]# cd /usr/local/redi…

微服务-服务保护和分布式事务

假如微服务中某个服务出现了故障,那我们需要为这个服务做好一些兜底的方案,健壮性的处理,这就是服务保护.以前我们写的是单体项目,不论项目多复杂,操作多少张表,最终都能够满足事务ACID的特性,但是我们分成了很多个服务之后,由于很多的服务是独立的,有各自的数据库,破坏了事务A…

【已解决】PDF文档有密码怎么办(2024新)免费在线工具PDF2Go

强大的解密工具PDF2Go使用指南 一、PDF2Go简介 PDF2Go是由德国QaamGo公司开发的在线PDF工具箱,以其强大的功能和用户友好的界面而闻名。它不仅免费,而且不需要用户注册或安装任何软件,只需打开浏览器即可使用。 二、功能特点 1. 免费且无需…

Ashy的考研游记

文章目录 摘要12.1112.2012.21 DAY1(政治/英语)政治英语 12.22 DAY2(数学/专业课)数学专业课 结束估分 摘要 在24年的12月里,Ashy完成了他的考研冲刺,顺利的结束了他本年度的考研之旅。 在十二月里&#…

Flutter-插件 scroll-to-index 实现 listView 滚动到指定索引位置

scroll-to-index 简介 scroll_to_index 是一个 Flutter 插件,用于通过索引滚动到 ListView 中的某个特定项。这个库对复杂滚动需求(如动态高度的列表项)非常实用,因为它会自动计算需要滚动的目标位置。 使用 安装插件 flutte…