Java - 日志体系_Apache Commons Logging(JCL)日志接口库_桥接Logback 及 源码分析

news2024/12/30 14:17:44

文章目录

  • Pre
  • Apache Commons
    • Apache Commons Proper
    • Logging (Apache Commons Logging )
  • JCL 集成logback
    • POM依赖
    • 配置文件 `logback.xml`
    • 使用
  • 源码分析
    • `jcl-over-slf4j` 的工作原理
      • 1. `LogFactory` 的实现
      • 2. `SLF4JLogFactory` 和 `Log` 的实例化过程
      • 3. `SLF4JLog` 和 `SLF4JLocationAwareLog`
      • 4. 日志输出的流程
  • 小结

在这里插入图片描述


Pre

Java - 日志体系_Apache Commons Logging(JCL)日志接口库

Java - 日志体系_Apache Commons Logging(JCL)日志接口库_适配Log4j2 及 源码分析


Apache Commons

官网:Apache Commons

在这里插入图片描述

Apache Commons Proper

Commons Proper 致力于一个主要目标: 创建和维护可重用的 Java 组件。这 Commons Proper 是一个协作和共享的地方,其中 来自整个 Apache 社区的开发人员都可以 一起讨论由 Apache 项目共享的项目,以及 Apache 用户。

共享资源开发人员将努力确保他们的 组件对其他库的依赖性最小,因此 这些组件可以轻松部署。此外,共享资源 组件将尽可能保持其接口稳定,因此 Apache 用户(包括其他 Apache 项目)可以实现 这些组件。

在这里插入图片描述

组件描述最新 Maven 版本发布版本发布日期
BCEL字节码工程库 - 分析、创建和操作 Java 类文件6.10.06.10.02024-07-23
BeanUtilsJava 反射和 introspection API 的易用封装1.9.41.9.42019-08-13
BSFBean 脚本框架 - 提供对脚本语言的接口,包括 JSR-2233.13.12010-06-24
CLI命令行参数解析器1.9.01.9.02024-08-14
Codec通用的编码/解码算法(例如音标、base64、URL)1.17.11.17.12024-07-15
Collections扩展或增强 Java 集合框架4.5.0-M34.5.0-M32024-12-18
Compress定义用于处理 tar、zip 和 bzip2 文件的 API1.27.11.27.12024-08-20
Configuration用于读取各种格式的配置/偏好文件2.11.02.11.02024-06-10
Crypto一个针对 AES-NI 优化的加密库,包装了 OpenSSL 或 JCE 算法实现1.2.01.2.02023-01-23
CSV处理逗号分隔值文件的组件1.12.01.12.02024-09-25
Daemon为 Unix 守护进程般的 Java 代码提供替代调用机制1.3.41.3.42023-05-12
DBCP数据库连接池服务2.13.02.13.02024-12-02
DbUtilsJDBC 辅助库1.8.11.8.12023-09-14
DigesterXML 到 Java 对象的映射工具3.23.22011-12-13
Email用于从 Java 发送电子邮件的库2.0.0-M12.0.0-M12024-06-27
Exec用于处理外部进程执行和环境管理的 API1.4.01.4.02024-01-05
FileUpload为您的 servlets 和 Web 应用提供文件上传功能1.51.52023-12-27
FileUpload2为您的 servlets 和 Web 应用提供文件上传功能(版本 2)2.0.0-M12.0.0-M12023-07-19
Geometry空间和坐标处理1.01.02021-08-21
Imaging一个纯 Java 图像库(之前称为 Sanselan)1.0.0-alpha51.0.0-alpha52024-04-18
IO一组 I/O 工具类2.18.02.18.02024-11-19
JCIJava 编译器接口1.11.12013-10-14
JCSJava 缓存系统3.2.13.2.12024-05-27
Jelly基于 XML 的脚本和处理引擎1.0.11.0.12017-09-25
Jexl扩展 JSTL 表达式语言的表达式语言3.4.03.4.02024-06-05
JXPath使用 XPath 语法操作 Java Beans 的工具集1.31.32008-08-14
Lang为 java.lang 类提供额外的功能3.17.03.17.02024-08-29
Logging包装了多种日志 API 实现1.3.41.3.42024-08-19
Math轻量级、自包含的数学和统计学组件4.0-beta14.0-beta12022-12-20
Net一组网络工具类和协议实现3.11.13.11.12024-06-10
Numbers数字类型(复数、四元数、分数)和工具(数组、组合数学等)1.21.22024-08-12
Pool通用对象池组件2.12.02.12.02023-09-30
RDFRDF 1.1 的通用实现,可由 JVM 上的系统实现0.5.00.5.02017-12-23
RNG随机数生成器的实现1.61.62024-07-15
SCXMLSCXML 规范的实现,旨在创建和维护 Java SCXML 引擎0.90.92008-12-01
Statistics统计学工具1.11.12024-08-20
TextApache Commons Text 是一个专注于字符串操作的算法库1.13.01.13.02024-12-13
Validator用于在 XML 文件中定义验证器和验证规则的框架1.9.01.9.02024-05-28
VFS虚拟文件系统组件,用于将文件、FTP、SMB、ZIP 等视为一个逻辑文件系统2.9.02.9.02021-07-21
Weaver提供一种简单的方式来增强(织入)已编译的字节码2.02.02018-09-07

Logging (Apache Commons Logging )

https://commons.apache.org/proper/commons-logging/

组件描述最新 Maven 版本发布版本发布日期
Logging包装了多种日志 API 实现1.3.41.3.42024-08-19

JCL 集成logback

在这里插入图片描述

POM依赖

  • jcl-over-slf4j (替代了 commons-logging)
  • slf4j-api
  • logback-core
  • logback-classic

通过 jcl-over-slf4j 替换 commons-logging,从而让 commons-logging 使用 SLF4J 作为底层日志实现。

  <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl-over-slf4j</artifactId>
      <version>2.0.16</version>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>2.0.16</version>
    </dependency>

    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>1.5.15</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.5.15</version>
    </dependency>

  • jcl-over-slf4j:这个依赖项将 commons-logging 的日志请求转发到 SLF4J 框架。
  • slf4j-api:SLF4J 的接口库,负责提供日志记录的 API。
  • logback-corelogback-classic:这是 Logback 的核心和实现,负责具体的日志输出。

配置文件 logback.xml

logback.xml 文件用于定义日志输出的格式和方式。

 <configuration>
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} |||  %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 文件输出 -->
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>application.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 可选:配置日志文件滚动 -->
    <appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>application.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 按天滚动日志文件 -->
            <fileNamePattern>application-%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 最多保留 30 天的日志文件 -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 根日志记录器 -->
    <root level="debug">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="ROLLING_FILE" />
    </root>

    <!-- 可选:配置特定包的日志级别 -->
    <logger name="com.artisan" level="info" />
</configuration>

使用

在代码中,通过 commons-logging 的 API 来记录日志,并且通过 SLF4J 和 Logback 完成实际的日志输出。

package com.artisan;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 *  commons-logging 与 logback 集成
 *
 */
public class JclBridgeLogbackExample {
    // commons logging 的 Log 和  LogFactory
    private static final Log logger= LogFactory.getLog(JclBridgeLogbackExample.class);


    public static void main( String[] args ) {
        logger.trace("JclBridgeLogbackExample This is a trace message");
        logger.debug("JclBridgeLogbackExample This is a debug message");
        logger.info("JclBridgeLogbackExample This is an info message");
        logger.warn("JclBridgeLogbackExample This is a warning message");
        logger.error("JclBridgeLogbackExample This is an error message");
        logger.fatal("JclBridgeLogbackExample This is a fatal message");
    }
}

在这里插入图片描述


源码分析

在这里插入图片描述

jcl-over-slf4j 的工作原理

jcl-over-slf4j 的作用是将 commons-logging 的日志接口(例如 LogLogFactory)转换为 SLF4J 的实现。具体地,它将 commons-logging 的日志请求转发给 SLF4J,而 SLF4J 则可以根据配置选择底层的日志框架(如 logback)。

在这里插入图片描述

  1. 步骤一:将 commons-logging 转向 SLF4J

    • jcl-over-slf4j 提供了一个 LogFactory 类,该类实现了 commons-loggingLogFactory 接口,负责创建 Log 实例。
    • 该类内部,LogFactory 被静态化为 SLF4JLogFactory,即它总是创建 SLF4JLogFactory 的实例,而不再使用 commons-logging 自带的实现。
  2. 步骤二:使用 SLF4J 作为底层日志实现

    • SLF4JLogFactory 内部调用 LoggerFactory.getLogger(name) 来获取 SLF4JLogger 实例。LoggerFactorySLF4J 提供的工厂类,负责返回一个底层日志记录器实例。
    • 一旦获取到 SLF4JLogger 实例,jcl-over-slf4j 将其封装成 commons-logging 定义的 Log 接口的实现,即 SLF4JLogSLF4JLocationAwareLog
    • SLF4JLogSLF4JLocationAwareLog 通过委托的方式将实际的日志调用转发给 SLF4JLogger,而 Logger 决定了最终使用哪个底层日志框架(如 logback)。

1. LogFactory 的实现

jcl-over-slf4j 中,LogFactory 被静态化为 SLF4JLogFactory

public abstract class LogFactory {
    static LogFactory logFactory = new SLF4JLogFactory();
    // 其他代码...
}
  • SLF4JLogFactoryLogFactory 的实现,它负责创建 Log 实例。
  • LogFactory.getLog() 方法调用 SLF4JLogFactory 中的 newInstance() 方法来创建 Log 实例。

2. SLF4JLogFactoryLog 的实例化过程

SLF4JLogFactory 实现了 LogFactory 接口,并重写了 newInstance() 方法来创建 Log 对象:

public class SLF4JLogFactory extends LogFactory {
    public Log newInstance(String name) {
        Logger slf4jLogger = LoggerFactory.getLogger(name);
        Log newInstance;
        if (slf4jLogger instanceof LocationAwareLogger) {
            newInstance = new SLF4JLocationAwareLog((LocationAwareLogger) slf4jLogger);
        } else {
            newInstance = new SLF4JLog(slf4jLogger);
        }
        return newInstance;
    }
}
  • LoggerFactory.getLogger(name) 创建了一个 SLF4JLogger 实例(这背后通常是 logback)。
  • 如果 Logger 实现了 LocationAwareLogger,则会使用 SLF4JLocationAwareLog,它提供了更加详细的日志信息(如日志位置等)。
  • 否则,使用普通的 SLF4JLog 实现。

3. SLF4JLogSLF4JLocationAwareLog

SLF4JLogSLF4JLocationAwareLogLog 接口的实现,它们负责将 commons-logging 的日志方法(如 debug(), info() 等)委托给 SLF4JLogger。这两个类的源码大致如下:

public class SLF4JLog implements Log {
    private final Logger slf4jLogger;

    public SLF4JLog(Logger slf4jLogger) {
        this.slf4jLogger = slf4jLogger;
    }

    @Override
    public void trace(Object message) {
        slf4jLogger.trace(String.valueOf(message));
    }

    @Override
    public void debug(Object message) {
        slf4jLogger.debug(String.valueOf(message));
    }

    @Override
    public void info(Object message) {
        slf4jLogger.info(String.valueOf(message));
    }

    // 其他日志级别方法...
}

SLF4JLocationAwareLog 类似,只不过它会获取日志的调用位置(如类名、行号等)以提供更详细的日志信息。

4. 日志输出的流程

  1. 通过 commons-logging API 写日志

    • 使用 commons-logging 提供的 Log 接口进行日志编写(例如 LogFactory.getLog() 获取日志实例)。
    • 调用 trace(), debug(), info() 等方法。
  2. 日志请求转发给 SLF4J

    • jcl-over-slf4j 将这些日志请求转发到 SLF4JLogger 实例。
  3. 最终日志输出

    • SLF4J 根据底层的配置选择具体的日志框架(如 logback),并将日志输出到目标(控制台、文件等)。

小结

  • jcl-over-slf4j 使 commons-logging 可以使用 SLF4J 作为底层日志实现,进而可以通过 SLF4J 配置选择 logback 作为实际的日志框架。
  • LogFactoryLog 被重定向到 SLF4JLogFactorySLF4JLog,这些类将日志请求转发给 SLF4J,而 SLF4J 决定底层日志框架(如 logback)的使用。
  • 这种方式允许我们继续使用 commons-logging API 进行日志记录,而底层的日志实现却是 logback,结合了两者的优势。

在这里插入图片描述

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

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

相关文章

多模态论文笔记——LLaVA

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍多模态模型&#xff1a;LLaVA。处理包含图像和文本的多模态数据&#xff0c;并生成合理准确的回答。 文章目录 论文模型架构视觉编码器语言模型多模态融…

汽车的hmi设计还能有哪些创新?要从哪些方面下手

随着科技的不断发展&#xff0c;汽车的人机交互界面&#xff08;HMI&#xff09;设计也在不断演进。目前&#xff0c;汽车 HMI 已经从传统的物理按钮和仪表盘发展到了数字化、智能化的交互系统。然而&#xff0c;仍有许多创新的空间等待探索。那么&#xff0c;汽车的 HMI 设计还…

基于深度学习(HyperLPR3框架)的中文车牌识别系统-前言

参考链接&#xff1a; GitHub - szad670401/HyperLPR: 基于深度学习高性能中文车牌识别 High Performance Chinese License Plate Recognition Framework.基于深度学习高性能中文车牌识别 High Performance Chinese License Plate Recognition Framework. - szad670401/HyperL…

Python库中各种插值函数的使用

文章目录 Python库中各种插值函数的使用数据1&#xff1a; 随机的数据数据2&#xff1a; 从 cos轨迹中取值B样条三次样条Akmia画图显示数据1 的比较结果位置比较示意图速度比较示意图加速度比较示意图 数据2 的比较结果位置比较示意图速度比较示意图加速度比较示意图 全部代码如…

ip归属地怎么判定?如何查看自己ip属地

在当今数字化时代&#xff0c;IP地址作为互联网通信的基础&#xff0c;扮演着至关重要的角色。而IP归属地的判定与查看&#xff0c;不仅关乎网络安全、隐私保护&#xff0c;还直接影响到社交平台的信任机制与信息传播的真实性。本文将深入探讨IP归属地的判定原理以及如何查看自…

soular使用教程

用 soular 配置你的组织&#xff0c;工作更高效&#xff01;以下是快速上手的简单步骤&#xff1a; &#xfeff; 1. 账号管理 可以对账号信息进行多方面管理&#xff0c;包括分配不同的部门、用户组等&#xff0c;从而确保账号权限和职责的清晰分配。 &#xfeff; 1.1 用…

JS媒体查询之matchMedia API 实现跟随系统主题色切换效果

&#x1f4ca;写在前面 在网页设计中&#xff0c;跟随系统主题切换可以通过CSS和JavaScript实现。可以通过定义两套CSS变量&#xff0c;根据系统主题的颜色来切换变量的生效&#xff0c;从而实现不同主题下的页面样式变化。 例如&#xff0c;可以使用媒体查询API来获取系统主题…

客户案例:基于慧集通的致远OA与海康威视智能会议设备集成方案

一、引言 本案例原型公司是我国生产纺织原料的大型上市企业&#xff0c;主导产品为再生纤维素长丝、氨纶等系列产品。公司产品不仅得到国内客户认可&#xff0c;还远销海外&#xff0c;合作伙伴遍布德国、意大利、日本、韩国、土耳其、印度等30多个国家和地区。 二、简介 &am…

【Leetcode】3046. 分割数组

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果 题目 题目链接&#x1f517; 给你一个长度为 偶数 的整数数组 n u m s nums nums 。你需要将这个数组分割成 n u m s 1 nums1 nums1 和 n u m s 2 nums2 nums2 两部分&#xff0c;要求&#xff1a; n u m s 1. l…

掌握软件工程基础:知识点全面解析【chap07、chap10】

chap07 软件设计基础 1.信息隐藏、内聚度和耦合度&#xff08;在七种级别里应该注意什么原则&#xff09;的概念 1.信息隐藏 模块独立的概念 o 模块应该设计得使其所含信息(过程和数据)对于那些不需要这些信息的模块不可访问; o 每个模块只完成一个相对独立的特定功能; o 模…

操作系统实验三 存储管理

实验三 存储管理 一、实验目的 通过实验使学生了解可变式分区管理使用的主要数据结构&#xff0c;分配、回收的主要技术&#xff0c;了解最优适应分配、最坏适应分配、最先适应分配和循环适应分配等分配算法。基本能达到下列具体的目标&#xff1a; 掌握初步进程在内存中的映…

40.2 预聚合和prometheus-record使用

本节重点介绍 : downsample降采样可以降低查询数据量 prometheus原生不支持downsample 实时查询/聚合 VS 预查询/聚合的优缺点 实时查询/聚合条件随意组合&#xff0c;性能差预查询/聚合 性能好&#xff0c;聚合条件需要提前定义 prometheus的预查询/聚合配置举例 downsample…

win11中win加方向键失效的原因

1、可能是你把win键锁了&#xff1a; 解决办法&#xff1a;先按Fn键&#xff0c;再按win键 2、可能是可能是 贴靠窗口设置 中将贴靠窗口关闭了&#xff0c;只需要将其打开就好了

【Rust自学】7.4. use关键字 Pt.2 :重导入与换国内镜像源教程

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 7.4.1. 使用pub use重新导入名称 使用use将路径导入作用域内后。该名称在词作用域内是私有的。 以上一篇文章的代码为例&#xff1a; m…

算法练习——模拟题

前言&#xff1a;模拟题的特点在于没有什么固定的技巧&#xff0c;完全考验自己的代码能力&#xff0c;因此有助于提升自己的代码水平。如果说一定有什么技巧的话&#xff0c;那就是有的模拟题能够通过找规律来简化算法。 一&#xff1a;替换所有问号 题目要求&#xff1a; 解…

三层交换机配置

✍作者&#xff1a;柒烨带你飞 &#x1f4aa;格言&#xff1a;生活的情况越艰难&#xff0c;我越感到自己更坚强&#xff1b;我这个人走得很慢&#xff0c;但我从不后退。 &#x1f4dc;系列专栏&#xff1a;网路安全入门系列 目录 一&#xff0c;三层交换二&#xff0c;实验案…

TCP-UDP调试工具推荐:Socket通信测试教程(附详细图解)

前言 在网络编程与应用开发中&#xff0c;调试始终是一项不可忽视的重要环节。尤其是在涉及TCP/IP、UDP等底层网络通信协议时&#xff0c;如何确保数据能够准确无误地在不同节点间传输&#xff0c;是许多开发者关注的核心问题。 调试的难点不仅在于定位连接建立、数据流控制及…

登录时的校验Token接口开发(Interceptor)

// 拦截器校验所有非登录请求时的token&#xff0c;校验成功之后解析出用户信息存入ThreadLocal中便于本次请求中共享该用户的信息&#xff0c;这个信息只能在本线程中拿到 一、需求分析 在用户登录后的请求交互中&#xff0c;Token 的校验是保障用户身份合法性和数据安全的重…

Hyper-V如何将文件复制到虚拟机

创建Hyper-V共享文件夹 通过创建共享文件夹的方式&#xff0c;能够帮助我们在主机与虚拟机之间轻松地进行数据交换共享&#xff0c;那么具体该如何通过网络共享来将文件复制到虚拟机呢&#xff1f;请您接着往下看。 步骤1. 在Hyper-V主机中创建一个文件夹&#xff0c;并将您想…

Linux(Centos 7.6)yum源配置

yum是rpm包的管理工具&#xff0c;可以自动安装、升级、删除软件包的功能&#xff0c;可以自动解决软件包之间的依赖关系&#xff0c;使得用户更方便软件包的管理。要使用yum必须要进行配置&#xff0c;个人将其分为三类&#xff0c;本地yum源、局域网yum源、第三方yum源&#…