深入理解Logger日志——框架绑定原理

  说到Logger日志的动态绑定,主要归功与Slf4j,在之前的文章也说过,Slf4j是类似于Apache Common-Logging,英文为Simple Logging Facade,是一个简单的日志门面适配器,所有的日志代码都可以用slf4j方式,它会根据项目具体依赖的日志实现包进行日志操作,只需修改pom.xml文件中的日志实现依赖,对于Log4j、Log4j2和Logback等都有相应的桥接包,对相应的slf4j-api接口实现。

  那么slf4j是如何自动绑定上的呢。

  多个框架是如何选择的呢。


Slf4j框架架构原理

  日志的绑定原理主要是依赖Slf4j的静态加载,从相应的实现框架中获取Logger。需要自己动手一步步跟踪下去才会感触良多。

  Slf4j的实现流程

  Logger日志打印调用流程:

  在slf4j中主要是实现 LoggerFactoryBinder 的 StaticLoggerBinder 采用单例模式,编译时期静态加载方式,得到不同的ILoggerFactory工厂的实现类,最终拿到相应框架所匹配的Logger。

  对于Slf4j的源码分析我这边就不再过多的赘余,关键得自己去理解的看看,推荐一个:Java日志体系(slf4j)

  介绍一下slf4j中主要的几个类的作用:

  • Logger:slf4j日志接口类,提供了trace < debug < info < warn < error这5个级别对应的方法,主要提供了占位符{}的日志打印方式;
  • Log4jLoggerAdapter:Logger适配器,主要对org.apache.log4j.Logger对象的封装,占位符{}日志打印的方式在此类中实现;
  • LoggerFactory:日志工厂类,获取实际的日志工厂类,获取相应的日志实现对象;
  • lLoggerFactory:底层日志框架中日志工厂的中介,再其实现类中,通过底层日志框架中的日志工厂获取对应的日志对象;
  • StaticLoggerBinder:静态日志对象绑定,在编译期确定底层日志框架,获取实际的日志工厂,也就是lLoggerFactory的实现类;

  项目中有多种日志框架时会存在多个StaticLoggerBinder时候获取第一个,主要是采用类的顺序加载机制,与Pom文件中依赖的填写顺序有关(个人实践得到)。

  每一种日志框架都有相应的桥接包。

  首先先看Slf4j-api包结构:主要定义了一些接口做相应的适配,其包结构主要是 org.slf4j  其他实现框架都是根据其进行相应的桥接

  Log4j的桥接包形式:相同包名,StaticLoggerBinder采用构造器形式获取 Log4jLoggerFactory 工厂

  Logback的桥接包形式:相同包名,在StaticLoggerBinder调用时就已经静态初始化
   Logback的详细配置:https://cloud.tencent.com/developer/article/1445599

  Log4j2的桥接包形式:相同包名,与Log4j类似采用构造器形式获取 Log4jLoggerFactory 工厂
  Log4j2的详细配置:Java日志体系(log4j2)

  在官方文档中slf4j与其他日志框架如何绑定的示意图(大家都放我也放一下~)

  以下是个人收集一些比较简单好理解的绑定关系图,体现了StaticLoggerBinder绑定的重要性


绑定过程中所遇到的问题

  1、Log4j和Log4j2需要配置好log4j.xml和log4j2.xml文件,不然无法正常使用,Logback可以正常使用

  2、与SpringBoot的spring-boot-starter中的依赖spring-boot-starter-logging内部的依赖Logback产生冲突(可以自己点击查看一番)

Caused by: java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.Log4jLoggerFactory loaded from file:/Users/zhouguanglin/.m2/repository/org/slf4j/slf4j-log4j12/1.7.29/slf4j-log4j12-1.7.29.jar). If you are using WebLogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml: org.slf4j.impl.Log4jLoggerFactory
at org.springframework.util.Assert.instanceCheckFailed(Assert.java:699)
at org.springframework.util.Assert.isInstanceOf(Assert.java:599)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLoggerContext(LogbackLoggingSystem.java:284)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.beforeInitialize(LogbackLoggingSystem.java:104)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationStartingEvent(LoggingApplicationListener.java:232)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:213)

    主要原因是:SpringBoot所使用的搭配日志框架是Logback

    若是项目使用SpringBoot但搭配的是其他日志框架A,由StaticLoggerBinder.getSingleton().getLoggerFactory()获取的是搭配框架A的实现,导致与SpringBoot内部自身搭配的Logback产生冲突,可以进入报错地方查看。

  从代码逻辑中可以发现,Assert.isInstanceOf 判断获取得到的ILoggerFactory的实现类必须是LoggerContext 才OK,硬性规定不然就会报错。

  解决方案:只要在SpringBoot中排除Logback的依赖就OK,如下:

        <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
</exclusions>
</dependency>

  

 

深入理解Logger日志——框架绑定原理的更多相关文章

  1. slf4j日志框架绑定机制

    一.环境搭建 我们以log4j为例,探寻slf4j与log4j的绑定过程. 1.Java类 public class Slf4jBind { public static void main(Strin ...

  2. 深入理解List集合框架底层原理的实现

    前言: 此篇文章讲解ArrayList和LinkedList底层实现原理.for和foreach遍历集合哪个效率会更高一些! 讲讲什么是集合框架?集合框架是为表示和操作集合而规定的一种统一的标准的体系 ...

  3. Slf4j+Log4j日志框架入门

    (一).日志系统介绍 slf4j,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统.简答的讲就是slf4j是一系列的 ...

  4. Java日志框架Slf4j+Log4j入门

    一.日志系统介绍 slf4j,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统.简答的讲就是slf4j是一系列的日志 ...

  5. Java日志框架:slf4j作用及其实现原理

    简单回顾门面模式 slf4j是门面模式的典型应用,因此在讲slf4j前,我们先简单回顾一下门面模式, 门面模式,其核心为外部与一个子系统的通信必须通过一个统一的外观对象进行,使得子系统更易于使用.用一 ...

  6. SpringBoot系列之日志框架介绍及其原理简介

    SpringBoot系列之日志框架介绍及其原理简介 1.常用日志框架简介 市面上常用日志框架:JUL.JCL.jboss-logging.logback.log4j.log4j2.slf4j.etc. ...

  7. Moon转告给你一个比Log4net更好日志框架--TracerX Logger 及其对应的日志查看器

    一.介绍 TracerX logger是一个易于上手,且拥有众多高级特性的.NET日志框架. 它能够发送输出结果到多目的地(循环文件.事件日志等....).它也能生成文本和二进制文件.它拥有一个强大的 ...

  8. springBoot日志框架自动配置与原理

    1.日志框架 小张:开发一个大型系统: ​ 1.System.out.println(""):将关键数据打印在控制台:去掉?写在一个文件? ​ 2.框架来记录系统的一些运行时信息: ...

  9. 大幅度改变celery日志外观,修改成日志可点击跳转和鲜艳五彩日志,解决脚本中已添加handler的logger和框架日志重复记录问题。

    大幅度改变celery日志外观,修改成日志可点击跳转和鲜艳五彩日志,解决脚本中已添加handler的logger和框架日志重复记录问题.打猴子补丁. 先把脚本中的所有logger的handlers全部 ...

随机推荐

  1. 【Gin-API系列】守护进程和平滑重启(八)

    生产环境的API服务我们都会部署在Linux服务器上,为了不受终端状态的影响,启动服务的时候会让服务在后台运行.那么如何让服务在后台运行呢,目前有2种常见的方法. 1.nohub 运行 表示忽略SIG ...

  2. 跟着兄弟连系统学习Linux-【day02】

    day02-20200528 p6.vmvare安装与使用         官网下载安装包,个人学习的时候要求不高,所以不用安装最新版本,用不到那么多的功能,保证稳定版本就好了,然后傻瓜式安装.注意安 ...

  3. Activiti工作流概述

    本来打算看OCR的但是我手里有的资源是讲的PY的,涉及到CNN和RNN看得有的不太明白,捂脸,所以看看工作流吧,反正也都不会,干啥啥不会 工作流的概念 工作流的概念应该都差不多了解要不也不会搜索这个标 ...

  4. Solon详解(三)- Solon的web开发

    Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...

  5. centOS7 安装jdk压缩包版

    1.到官网下载jdk https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 2.将压 ...

  6. python中的一些内置函数

    1.布尔类型 2.求和sum 3.取全局变量和局部变量 4.ascii码和字符集 chr().ord() 5.看某个功能下有哪些方法 help(x).dir(x) 6.exec执行python代码 7 ...

  7. python列表,字典,元组常用方法和集合

    python 目录 一.列表 列表格式 1.添加 列表取数(按照下标取,下标从0开始) 获取长度 append添加(直接添加) extend添加(分别添加) insert()insert(index, ...

  8. hystrix文档翻译之运维

    hystrix不仅用作工程可靠性还可以用来运维. 这里将会分享一个拥有100+Hystrix命令,40+线程池,每天有100亿次线程请求,2000亿次信号量请求的系统是如何使用hystrix运维的.这 ...

  9. maven安装配置以及eclipse的配置

    一.需要准备的东西 JDK Eclipse Maven程序包 二.下载与安装 前往https://maven.apache.org/download.cgi下载最新版的Maven程序: 将文件解压到D ...

  10. 1.8HDFS细节