日志门面slf4j和各日志框架

简介

简单日志门面(Simple Logging Facade For Java)

SLF4J主要是为了给Java日志访问提供一套标准、规范的API框架,

其主要意义在于提供接口,具体的实现可以交由其他日志框架,如log4j、logback、log4j2。

对于一般的Java项目而言,日志框架会选择slf4j-api作为门面,配上具体的实现框架,中间使用桥接器完成桥接。

所以我们可以得出SLF4J最重要的两个功能就是对于日志框架的绑定以及日志框架的桥接。

slf4j+log4j

依赖

XML 复制代码
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.21</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.21</version>
        </dependency>

使用入口

java 复制代码
 Logger logger = LoggerFactory.getLogger(Slf4jAndLog4j.class);
 logger.info("this is slf4j&log4j test:{}",123);

log4j的配置文件参见:log4j日志框架的使用-CSDN博客

slf4j+logback

依赖

XML 复制代码
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.1.7</version>
</dependency>

使用入口

java 复制代码
Logger logger = LoggerFactory.getLogger(Slf4jAndLogback.class);
logger.info("this is slf4j&logback test:{}",123);

logback配置参见:logback日志框架使用-CSDN博客

slf4j+log4j2

依赖

XML 复制代码
        <!--sl4j日志门面-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>

        <!--log4j适配器-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.12.1</version>
        </dependency>

        <!--log4j2实现-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.12.1</version>
        </dependency>

使用入口

java 复制代码
Logger logger = LoggerFactory.getLogger(Slf4jAndLog4j2.class);
logger.info("this is slf4j&log4j2 test:{}",123);

log4j2的配置参见:log4j2日志框架使用-CSDN博客

实现原理

代码解析入口:

java 复制代码
LoggerFactory.getLogger(Slf4jAndLog4j2.class);

该段代码会寻找依赖中的日志实现

如何寻找日志依赖?

org.slf4j.LoggerFactory#findPossibleStaticLoggerBinderPathSet方法会读取依赖中所有的org.slf4j.impl.StaticLoggerBinder类所在的文件路径

在工作路径下,依赖下寻找文件名为:org/slf4j/impl/StaticLoggerBinder.class 的文件。其实说白一点,就只寻找各个日志框架的桥接引导类org.slf4j.impl.StaticLoggerBinder,如下是各个日志框架实现的桥接截图:

寻找到对应的日志框架桥接的引导类之后,调用初始化操作完成日志的加载和初始化动作。这就是slf4j门面模式和各日志框架实现的原理

log4j的引导操作截图如下:

在前面的关于log4j的源码浅析(log4j日志框架的使用-CSDN博客)中,log4j的初始化LogManager类中完成的。slf4j的桥接器(StaticLoggerBinder)引导完成初始化加载

log4j2的引导操作截图如下:

在前面的关于log4j2的源码浅析(log4j2日志框架使用-CSDN博客)中,log4j2的入口是LogManager的静态代码块加载。slf4j的桥接器(StaticLoggerBinder)引导完成初始化加载

logback的引导操作可以翻看前面的文章:logback日志框架使用-CSDN博客

各日志框架性能对比

引用一张log4j2的官方性能压测数据图:

log4j2的异步日志性能明显高于log4j和logback(由于日志框架出现的时间有先后,后面的日志肯定会规避前面日志框架的缺点而继承其优点)

log4j2全异步日志开启

1 引入依赖

XML 复制代码
<dependency>
  <groupId>com.lmax</groupId>
  <artifactId>disruptor</artifactId>
  <version>3.4.2</version>
</dependency>

2 增加启动参数

java 复制代码
-Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

或者

java 复制代码
System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector")

@slf4j注解实现原理

平时在使用slf4j门面日志配合其他日志框架时,很少会在类中通过编码定义Logger对象,而习惯性的使用@slf4j注解完成Logger定义。不知道大家想过没有,这个注解是如何实现的?

@slf4j注解是由lombok

依赖引入的,该依赖会将标注了@slf4j的类编程成形如:

复制代码
private static final Logger log = LoggerFactory.getLogger(Demo2.class);

的一个log对象

源代码如下:

编译之后的类:

相关推荐
开源技术1 分钟前
Python GeoPandas基础知识:地图、投影和空间连接
开发语言·ide·python
vx1_Biye_Design3 分钟前
基于Spring Boot+Vue的学生管理系统设计与实现-计算机毕业设计源码46223
java·vue.js·spring boot·spring·eclipse·tomcat·maven
vx_Biye_Design4 分钟前
基于Spring Boot+vue的湖北旅游景点门票预约平台的设计--毕设附源码29593
java·vue.js·spring boot·spring cloud·servlet·eclipse·课程设计
Cult Of5 分钟前
Alicea Wind的个人网站开发日志(2)
开发语言·python·vue
我找到地球的支点啦10 分钟前
通信扩展——扩频技术(超级详细,附带Matlab代码)
开发语言·matlab
hay_lee23 分钟前
Spring AI实现对话聊天-流式输出
java·人工智能·ollama·spring ai
Hx_Ma1629 分钟前
SpringBoot数据源自动管理
java·spring boot·spring
微小冷29 分钟前
Rust异步编程详解
开发语言·rust·async·await·异步编程·tokio
SunnyDays101130 分钟前
Java 高效实现 CSV 转 Excel
java·csv转excel
starfire_hit31 分钟前
JAVAWEB根据前台请求获取用户IP
java·服务器·网络