首页 > 编程语言 >Java日志系列:日志门面JCL、SLF4J

Java日志系列:日志门面JCL、SLF4J

时间:2023-08-17 22:58:20浏览次数:44  
标签:框架 实现 SLF4J slf4j JCL 日志 log4j

目录

一、日志门面说明

当我们的系统变的更加复杂的时候,我们的日志就容易发生混乱。随着系统开发的进行,可能会更新不同的日志框架,造成当前系统中存在不同的日志依赖,让我们难以统一的管理和控制。就算我们强制要求所有的模块使用相同的日志框架,系统中也难以避免使用其他类似 spring,mybatis 等其他的第三方框架,它们依赖于我们规定不同的日志框架,而且他们自身的日志系统就有着不一致性,依然会出来日志

体系的混乱。

所以我们需要借鉴 JDBC 的思想,为日志系统也提供一套门面,那么我们就可以面向这些接口规范来开发,避免了直接依赖具体的日志框架。这样我们的系统在日志中,就存在了日志的门面和日志的实现。

常见的日志门面 :

JCL、slf4j

常见的日志实现:

JUL、log4j、logback、log4j2

日志门面和日志实现的关系:

image

日志框架出现的历史顺序:

log4j -->JUL-->JCL--> slf4j --> logback --> log4j2

我们为什么要使用日志门面:

  1. 面向接口开发,不再依赖具体的实现类。减少代码的耦合

  2. 项目通过导入不同的日志实现类,可以灵活的切换日志框架

  3. 统一 API,方便开发者学习和使用

  4. 统一配置便于项目日志的管理

二、JCL 使用

全称为 Jakarta Commons Logging,是 Apache 提供的一个通用日志 API。

它是为 "所有的 Java 日志实现"提供一个统一的接口,它自身也提供一个日志的实现,但是功能非常常弱(SimpleLog)。所以一般不会单独使用它。他允许开发人员使用不同的具体日志实现工具: Log4j, Jdk 自带的日志(JUL)

JCL 有两个基本的抽象类:Log(基本记录器)和 LogFactory(负责创建 Log 实例)。

JCL 入门

1、添加依赖

    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.2</version>
    </dependency>

2、入门代码,基于自身的 SimpleLog

package com.mcode.logger;

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

/**
 * Hello world!
 */
public class JCLTest {
    /**
     * 快速入门JCL
     * @throws Exception
     */
    @Test
    public void testQuick() throws Exception {
        // 获取 log日志记录器对象
        Log log = LogFactory.getLog(JCLTest.class);
        // 日志记录输出
        log.info("hello jcl");
    }
}

image

3、添加 log4j 依赖

    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>

4、添加 log4j.properties

# 指定 RootLogger 顶级父元素默认配置信息
# 指定日志级别=trace,使用的 apeender 为=console
log4j.rootLogger = trace,console
# 指定控制台日志输出的 appender
log4j.appender.console = org.apache.log4j.ConsoleAppender
# 指定消息格式 layout
log4j.appender.console.layout = org.apache.log4j.PatternLayout
# 指定消息格式的内容
log4j.appender.console.layout.conversionPattern = [console]%r  %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n

5、基于 log4j 的测试结果

image

JCL 原理

1、通过 LogFactory 动态加载 Log 实现类

image

  • SimpleLog:JCL 的内置日志实现
  • Log4JLogger:log4j 日志框架
  • Jdk14Logger:JUL(Java Util Logging)
  • Jdk13LumberjackLogger:Jdk 老版本的内置日志实现

2、日志门面支持的日志实现数组

public class LogFactoryImpl extends LogFactory {
    .....

    private static final String[] classesToDiscover = new String[].
        {
         "org.apache.commons.logging.impl.Log4JLogger",
         "org.apache.commons.logging.impl.Jdk14Logger",
         "org.apache.commons.logging.impl.Jdk13LumberjackLogger",
         "org.apache.commons.logging.impl.SimpleLog"
        };

    .....
}

说明:日志工厂其内部有一个加载日志的数组,加载顺序是按照数组顺序来的,这也解释了为什么入门案例中引入了 Log4J,JCL 内部日志框架就从 JUL 切换至 Log4J 了

3、具体实现代码

for(int i = 0; i < classesToDiscover.length && result == null; ++i) {
    result = this.createLogFromClass(classesToDiscover[i], logCategory, true);
}

说明:通过日志数组顺序加载日志框架,如果没有找到,则继续加载下一个,否则直接返回

从原理中我们知道,JCL 是通过一个日志数组顺序加载,日志数组中包含:JCL 的内置日志实现 SimpleLog、log4j 、JUL(Java Util Logging)以及 Jdk 老版本的内置日志实现。

✷ 设计缺陷:如果后期又出现了新的日志实现主流框架,如果你想加载的话,就需要修改 JCL 源代码,实现 Log 接口,放入到日志加载数组中,因此 JCl 已经在 2014 年被 apache 淘汰了

三、SLF4J 使用

简单日志门面(Simple Logging Facade For Java) SLF4J 主要是为了给 Java 日志访问提供一套标准、规范的 API 框架,其主要意义在于提供接口,具体的实现可以交由其他日志框架,例如 log4j 和 logback 等。

当然 slf4j 自己也提供了功能较为简单的实现,但是一般很少用到。对于一般的 Java 项目而言,日志框架会选择 slf4j-api 作为门面,配上具体的实现框架(log4j、logback 等),中间使用桥接器完成桥接。

官方网站:

https://www.slf4j.org/

SLF4J 是目前市面上最流行的日志门面。现在的项目中,基本上都是使用 SLF4J 作为我们的日志系统。

SLF4J 日志门面主要提供两大功能:

  • 日志框架的绑定

  • 日志框架的桥接

image

application 下面的 SLF4J API 表示 slf4j 的日志门面,包含三种情况:

  • 若是只导入 slf4j 日志门面没有导入对应的日志实现框架,那么日志功能将会是默认关闭的,不会进行日志输出的。

  • 蓝色图里 Logback、slf4j-simple、slf4j-nop 出来的比较晚就遵循了 slf4j 的 API 规范,也就是说只要导入对应的实现就默认实现了对应的接口,来实现开发。

  • 对于中间两个日志实现框架 log4j(slf4j-log4j12)、JUL(slf4j-jdk14)由于出现的比 slf4j 早,所以就没有遵循 slf4j 的接口规范,所以无法进行直接绑定,中间需要加一个适配层(Adaptationlayer),通过对应的适配器来适配具体的日志实现框架,其对应的适配器其实就间接的实现了 slf4j-api 的接口规范。

注意:在图中对于 logback 需要引入两个 jar 包,不过在 maven 中有一个传递的思想,当配置 logback-classic 时就会默认传递 core 信息,所以我们只需要引入 logback-classic 的 jar 包即可。

配合自身简单日志实现(slf4j-simple)

若想使用自身的日志实现框架,需要引入第三方jarslf4j-simple(slf4j 自带实现类):

    <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-simple -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
      <version>2.0.7</version>
    </dependency>

其中该坐标包含了对应的slf4j-api的依赖,可以不用手动导入slf4j-api

image

测试

package com.mcode.logger;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class SLF4JTest
{
    //获取Logger实例
    private  static final Logger LOGGER = LoggerFactory.getLogger(SLF4JTest.class);
    @Test
    public void testQuick(){
        //打印日志记录
        LOGGER.error("error");
        LOGGER.warn("warn");
        LOGGER.info("info");
        LOGGER.debug("debug");
        LOGGER.trace("trace");
        //占位符输出
        String name = "mcode";
        int age = 20;
        LOGGER.info("报错,name:{},age:{}",name,age);
        //打印堆栈信息
        try {
            int i = 5/0;
        }catch (Exception e){
            LOGGER.error("报错",e);
        }
    }
}

结果

image

默认日志等级为INFO,能够实现占位符输出,并且可以在日志等级方法中传入异常实例,来打印对应的日志信息。

配置logback日志实现

引入logback-classic的jar包,其中包含有slf4j-api以及logback-core的依赖,所以只需要引入该依赖即可:

配置Log4J日志实现(需适配器)

首先添加日志框架实现依赖

之前介绍,对于Log4jJUL这些比较早出现的日志实现框架需要有对应的适配层,在这里我们引入对应的适配器slf4j-log412的依赖坐标:

配置JUL日志实现(需适配器)

添加slf4j-nop依赖(日志开关)

桥接旧的日志实现框架

标签:框架,实现,SLF4J,slf4j,JCL,日志,log4j
From: https://www.cnblogs.com/vic-tory/p/17639109.html

相关文章

  • 3.2.0 版本预告!远程日志解决 Worker 故障获取不到日志的问题
    ApacheDolphinScheduler3.2.0版本已经呼之欲出,8月中下旬,这个大版本就要和用户见面了。为了让大家提前了解到此版本更新的主要内容,我们已经制作了几期视频和内容做了大致介绍,包括《重磅预告!ApacheDolphinScheduler3.2.0新功能“剧透”》、《3.2.0版本预告!ApacheDolphinSc......
  • 3.2.0 版本预告!远程日志解决 Worker 故障获取不到日志的问题
    ApacheDolphinScheduler3.2.0版本已经呼之欲出,8月中下旬,这个大版本就要和用户见面了。为了让大家提前了解到此版本更新的主要内容,我们已经制作了几期视频和内容做了大致介绍,包括《重磅预告!ApacheDolphinScheduler3.2.0新功能“剧透”》、《3.2.0版本预告!ApacheDolphinS......
  • PowerShell Deep Drive 2-正则审查O365安装日志
    PowerShellDeepDrive2-正则审查O365安装日志前言最近遇到一个问题,在安装O365客户端的时候,遇到安装失败的情况,需要检查O365的安装日志,确定问题。在Office365(现在称为Microsoft365)的安装过程中,系统会生成安装日志以记录安装操作的详细信息。这些日志对于排查安装问题、分析错......
  • ELK EFLK日志平台基于ElastAlert的监控告警
    一、前言1.1、产生背景ElastAlert最初由Yelp开发并开源,旨在解决实时监控和告警的需求。由于Elasticsearch的日志处理能力强大,许多组织和企业使用它来存储和分析大量的日志数据。然而,仅仅存储和分析数据可能无法满足实时监控和快速响应的需求(XPACK收费),因此ElastAlert应运而生。1.2、......
  • 日志服务 SLS
    日志服务SLS是云原生观测分析平台,为Log/Metric/Trace等数据提供大规模、低成本、实时平台化服务。一站式提供数据采集、加工、分析、告警可视化与投递功能,全面提升研发、运维、运营和安全等场景数字化能力。......
  • 卸载页面时上报日志
    当刷新页面或关闭页面时,上报日志functionreport(){ letmyHeaders=newHeaders(); myHeaders.append("Accept","application/json"); myHeaders.append("Authorization","BearereyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vMT......
  • Eclipse控制台显示全部日志的方法
    window——preferences——run/debug——console,详细见下图  翻译搜索复制......
  • SqlServer开启了Always On可用性组后如何清理数据库日志
    1、首先,确保你已经备份了数据库,并且备份是完整的和成功的。备份是非常重要的,因为在清理日志文件之前,你需要确保数据库的完整备份已经完成。2、使用以下命令手动截断和清理日志文件:BACKUPLOG[数据库名称]TODISK='备份路径'WITHNOFORMAT,NOINIT,SKIP,NOREWIND,NOUNLOA......
  • 20230816python学习日志
    在初始化属性中的类#person_class.pyclassPerson:population=0#初始化属性,用于计数def__init__(self,myAge):self.age=myAgePerson.population+=1#计数器defget_population(self):returnPerson.population......
  • Java日志系列:Log4j使用和原理分析
    目录一、简介二、使用三、日志级别四、组件说明LoggersAppendersLayouts五、配置加载初始化配置配置文件加载查看日志记录器的详细信息六、Layout的格式七、Appender的输出FileAppenderRollingFileAppenderDailyRollingFileAppenderJDBCAppender八、日志记录器的层级关系一、简介......