likes
comments
collection
share

如何5分钟读懂 Slf4j + Logback 启动流程源码

作者站长头像
站长
· 阅读数 30

大家好,我是摸鱼总工,懒惰是程序员的美德,摸鱼才能成为总工。

今天给大家介绍一下,我是如何 5 分钟读懂 Slf4j 启动流程的。

第一步 用 AI 写一个简单的Demo

让大模型写个完整的软件差点意思,但是写个Demo是最擅长不过了。

这一步比较简单,也不是本文的重点,这里就简单描述一下,引入下述依赖:

<dependency>
     <groupId>ch.qos.logback</groupId>
     <artifactId>logback-classic</artifactId>
     <version>1.2.13</version>
</dependency>

然后写个Main方法,就两行代码,跑起来就完事了。

 Logger logger = LoggerFactory.getLogger(LoggerRunner.class);
 logger.info("This is logger runner");

第一步,耗时最多 1 分钟。但这个过程也很重要,有一个清晰干净的环境,是读代码的重要前提。

第二步 利用 XCodeMap 生成序列图

把程序跑起来实在是太简单了,但是这程序跑起来的背后,都做了些什么呢?总不能翻代码一行行去看吧?

哈哈,不用,XCodeMap 可以帮你一键绘制实时序列图,让你马上拥有上帝视角!

如何5分钟读懂 Slf4j + Logback 启动流程源码 通过 “Run With XCodeMap”,你立即可以得到一张下面这样的图,它是通过采集程序内部的运行时数据生成的,你可以把它理解为程序的 X 光图。

如何5分钟读懂 Slf4j + Logback 启动流程源码 有了这张图,可以认为你朝着 “ 5 分钟读懂 Slf4j 流程”的成就迈出了一大步。

如果之前逐行 Debug 需要2小时,那你现在估计需要 20 分钟,虽然快了不少,但是还远远不够!

因为,面对错综复杂的程序,你还需要识别出主链路!

第三步 识别主链路

如果你看过一些”高效能人士“之类的职场书籍,书中都会告诉你,达成目标的关键就是要找出关键步骤。

读代码也一样!

那我们如何找出代码的关键链路呢?这个话题比较复杂,值得专门写一篇文章来阐述。

但”二八法则“告诉我们,一般都有一些简单的杀手锏可以解决 80% 的问题。

没错,这个方法被我找到了!

那就是,直接根据耗时进行筛选!如果A函数的耗时是100ms,它调用了 B C D 函数,其中B函数消耗了90ms,那我们根本不必去做太多业务语义分析,直觉就可以断定 B 函数是关键链路。

真的是这样吗,我们可以试一下,筛选出 “costMs > 100”的函数,效果图如下。

如何5分钟读懂 Slf4j + Logback 启动流程源码 是不是非常清晰了!

如果熟练运用 XCodeMap,这第二步和第三步,加起来最多1分钟。

我们还剩 3 分钟。

第四步 目标减负

关键函数都找出了,总共也就10个函数左右,在这些函数处打上断点,稍微花点时间,我相信你肯定是可以搞明白整个流程的。但你想在3分钟内,就搞明白,还是很有挑战!

XCodeMap 可以帮我们代码减负,但要达成“5分钟读懂Slf4j启动流程”的成就,还需要目标减负。

我们读代码,到底读的是啥呢?

首先当然是为了解决开发问题。

我们在工作中大量使用开源组件,这些开源组件大部分也都是质量较高的,也就是说,严重的 Bug 一般不太常见。那是不是意味着,我们使用起来就没有问题了呢?非也,问题大大的多!

其中,至少有一半的问题,跟配置和输入有关。

这不难理解,程序本质可以理解为一个“输入输出”的过程,就算程序本身质量极高,那也得是正确的输入,才能得到正确的输出。

说了这么多,落实到本文,我们的程序还有一个配置文件,那就是 logback.xml,通常放在src/main/resources下面。很显然,这个配置文件,是给日志组件的输入,也是唯一的输入,我们理解启动流程的最关键步骤,自然也是要搞明白以下问题:

  • 这个配置文件是在哪里加载的?
  • 怎么加载的?
  • 有哪些加载方式?
  • 优先级如何?

带着这个目标,我们再扫一下上面的程序图,你会发现,最关键的函数就是autoConfig

如何5分钟读懂 Slf4j + Logback 启动流程源码 花个1分钟,扫描下这个函数的源码,可以发现 findURLOfDefaultConfigurationFile:

如何5分钟读懂 Slf4j + Logback 启动流程源码

这个函数就是,整个启动流程之关键的关键!

这个函数其实很简单,稍微阅读下,就可以搞明白以下问题:

  • 先看,有没有“-Dlogback.configurationFile” 的配置,如果有,从这里加载配置文件
  • 再看,classpath下有无 logback-test.xml
  • 最后看,classpath下有无 logback.xml

到这里,整个流程其实已经大致清楚。有这个基础知识,如果再出现离奇的日志不生效问题,就可以轻松搞定啦。

后记

为什么突然开始读日志启动源码呢?还是源于一个线上问题啊。

最近项目中,因为不小心升级了 Slf4j 版本,日志配置全部失效,导致日志全部以 debug 级别打印到 nohup.out,把线上硬盘打爆了。后通过排查发现,Slf4j 在 2.x 之后的 bind 方式出现了变化,需要升级对应 logback 的版本。于是,乘着这个契机,把这些源码梳理了一下。

本文讲述的是 slf4j 1.7.32 + logback 1.2.13 的启动流程,有兴趣的同学,可以试试挑战 “5 分钟读懂 slf4j 2.x 的启动流程” 哈!我相信你可以的。

参考:

  1. xcodemap.tech
转载自:https://juejin.cn/post/7375928754146672667
评论
请登录