日志门面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对象

源代码如下:

编译之后的类:

相关推荐
谭欣辰2 分钟前
LCS(最长公共子序列)详解
开发语言·c++·算法
RPGMZ10 分钟前
RPGMakerMZ 地图存档点制作 标题继续游戏直接读取存档
开发语言·javascript·游戏·游戏引擎·rpgmz·rpgmakermz
计算机_毕业设计16 分钟前
java-springboot数字藏品系统 基于 SpringBoot 的区块链数字艺术品交易平台 Java 微服务架构下的加密藏品展示与拍卖系统计算机毕业设计
java·spring boot·课程设计
ONVO ncen17 分钟前
Redis6.2.6下载和安装
java
丑八怪大丑19 分钟前
JDK8-17新特性
java·开发语言
京师20万禁军教头30 分钟前
37面向对象(高级)-main方法
java
书源丶30 分钟前
三十五、Java 泛型——类型安全的「万能模板」
java·开发语言·安全
EF@蛐蛐堂42 分钟前
【js】浏览器滚动条优化组件OverlayScrollbars
开发语言·javascript·ecmascript
dovens1 小时前
SpringBoot集成MQTT客户端
java·spring boot·后端
❀͜͡傀儡师1 小时前
Spring Boot 集成 RocksDB 实战:打造高性能 KV 存储加速层
java·spring boot·后端·rocksdb