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

文章目录

  • Pre
  • [Apache Commons](#Apache Commons)
    • [Apache Commons Proper](#Apache Commons Proper)
    • [Logging (Apache Commons Logging )](#Logging (Apache Commons Logging ))
  • [JCL 集成logback](#JCL 集成logback)
  • 源码分析
    • [`jcl-over-slf4j` 的工作原理](#jcl-over-slf4j 的工作原理)
      • [1. `LogFactory` 的实现](#1. LogFactory 的实现)
      • [2. `SLF4JLogFactory` 和 `Log` 的实例化过程](#2. SLF4JLogFactoryLog 的实例化过程)
      • [3. `SLF4JLog` 和 `SLF4JLocationAwareLog`](#3. SLF4JLogSLF4JLocationAwareLog)
      • [4. 日志输出的流程](#4. 日志输出的流程)
  • 小结

Pre

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

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

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

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

Java - 日志体系_Simple Logging Facade for Java (SLF4J)日志门面_SLF4J集成JUL 及 原理分析

Java - 日志体系_Simple Logging Facade for Java (SLF4J)日志门面_SLF4J集成Log4j1.x 及 原理分析

Java - 日志体系_Simple Logging Facade for Java (SLF4J)日志门面_SLF4J集成Log4j2.x 及 原理分析

Java - 日志体系_Simple Logging Facade for Java (SLF4J)日志门面_SLF4J集成logback 及 原理分析


Apache Commons

官网:Apache Commons

Apache Commons Proper

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

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

组件 描述 最新 Maven 版本 发布版本 发布日期
BCEL 字节码工程库 - 分析、创建和操作 Java 类文件 6.10.0 6.10.0 2024-07-23
BeanUtils Java 反射和 introspection API 的易用封装 1.9.4 1.9.4 2019-08-13
BSF Bean 脚本框架 - 提供对脚本语言的接口,包括 JSR-223 3.1 3.1 2010-06-24
CLI 命令行参数解析器 1.9.0 1.9.0 2024-08-14
Codec 通用的编码/解码算法(例如音标、base64、URL) 1.17.1 1.17.1 2024-07-15
Collections 扩展或增强 Java 集合框架 4.5.0-M3 4.5.0-M3 2024-12-18
Compress 定义用于处理 tar、zip 和 bzip2 文件的 API 1.27.1 1.27.1 2024-08-20
Configuration 用于读取各种格式的配置/偏好文件 2.11.0 2.11.0 2024-06-10
Crypto 一个针对 AES-NI 优化的加密库,包装了 OpenSSL 或 JCE 算法实现 1.2.0 1.2.0 2023-01-23
CSV 处理逗号分隔值文件的组件 1.12.0 1.12.0 2024-09-25
Daemon 为 Unix 守护进程般的 Java 代码提供替代调用机制 1.3.4 1.3.4 2023-05-12
DBCP 数据库连接池服务 2.13.0 2.13.0 2024-12-02
DbUtils JDBC 辅助库 1.8.1 1.8.1 2023-09-14
Digester XML 到 Java 对象的映射工具 3.2 3.2 2011-12-13
Email 用于从 Java 发送电子邮件的库 2.0.0-M1 2.0.0-M1 2024-06-27
Exec 用于处理外部进程执行和环境管理的 API 1.4.0 1.4.0 2024-01-05
FileUpload 为您的 servlets 和 Web 应用提供文件上传功能 1.5 1.5 2023-12-27
FileUpload2 为您的 servlets 和 Web 应用提供文件上传功能(版本 2) 2.0.0-M1 2.0.0-M1 2023-07-19
Geometry 空间和坐标处理 1.0 1.0 2021-08-21
Imaging 一个纯 Java 图像库(之前称为 Sanselan) 1.0.0-alpha5 1.0.0-alpha5 2024-04-18
IO 一组 I/O 工具类 2.18.0 2.18.0 2024-11-19
JCI Java 编译器接口 1.1 1.1 2013-10-14
JCS Java 缓存系统 3.2.1 3.2.1 2024-05-27
Jelly 基于 XML 的脚本和处理引擎 1.0.1 1.0.1 2017-09-25
Jexl 扩展 JSTL 表达式语言的表达式语言 3.4.0 3.4.0 2024-06-05
JXPath 使用 XPath 语法操作 Java Beans 的工具集 1.3 1.3 2008-08-14
Lang 为 java.lang 类提供额外的功能 3.17.0 3.17.0 2024-08-29
Logging 包装了多种日志 API 实现 1.3.4 1.3.4 2024-08-19
Math 轻量级、自包含的数学和统计学组件 4.0-beta1 4.0-beta1 2022-12-20
Net 一组网络工具类和协议实现 3.11.1 3.11.1 2024-06-10
Numbers 数字类型(复数、四元数、分数)和工具(数组、组合数学等) 1.2 1.2 2024-08-12
Pool 通用对象池组件 2.12.0 2.12.0 2023-09-30
RDF RDF 1.1 的通用实现,可由 JVM 上的系统实现 0.5.0 0.5.0 2017-12-23
RNG 随机数生成器的实现 1.6 1.6 2024-07-15
SCXML SCXML 规范的实现,旨在创建和维护 Java SCXML 引擎 0.9 0.9 2008-12-01
Statistics 统计学工具 1.1 1.1 2024-08-20
Text Apache Commons Text 是一个专注于字符串操作的算法库 1.13.0 1.13.0 2024-12-13
Validator 用于在 XML 文件中定义验证器和验证规则的框架 1.9.0 1.9.0 2024-05-28
VFS 虚拟文件系统组件,用于将文件、FTP、SMB、ZIP 等视为一个逻辑文件系统 2.9.0 2.9.0 2021-07-21
Weaver 提供一种简单的方式来增强(织入)已编译的字节码 2.0 2.0 2018-09-07

Logging (Apache Commons Logging )

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

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

JCL 集成logback

POM依赖

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

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

xml 复制代码
  <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 文件用于定义日志输出的格式和方式。

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 完成实际的日志输出。

java 复制代码
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

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

2. SLF4JLogFactoryLog 的实例化过程

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

java 复制代码
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。这两个类的源码大致如下:

java 复制代码
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,结合了两者的优势。
相关推荐
_UMR_21 小时前
Logback的使用
java·spring boot·logback
superCleanCoder3 天前
logback之自定义pattern使用的转换器
java·spring boot·logback
superCleanCoder3 天前
logback之pattern详解以及源码分析
spring boot·后端·logback
龙少95433 天前
【Logback详解】
java·spring boot·后端·logback
m0_748256343 天前
springboot整合Logback
spring boot·后端·logback
superCleanCoder3 天前
logback之自定义过滤器
logback
小小工匠4 天前
Java - 日志体系_Simple Logging Facade for Java (SLF4J)日志门面_SLF4J集成logback 及 原理分析
logback·slf4j
暮色里de白雪檐4 天前
基于 Slf4j 和 AOP 的自动化方法执行时间日志记录方案
logback·日志·slf4j·aop·日志打印
m0_748247554 天前
Spring Boot 3.3.4 升级导致 Logback 之前回滚策略配置不兼容问题解决
java·spring boot·logback
keep丶4 天前
Spring实现Logback日志模板设置动态参数
java·spring·logback