SOFABoot源码解析之日志空间隔离

本文详细解析了SOFABoot如何实现日志空间隔离,介绍了InfraHealthCheckLoggerFactory类及其相关方法,包括获取日志对象的逻辑。SOFABoot利用日志空间隔离确保中间件和应用日志的独立打印,依赖于sofa-common-tools包提供的功能。通过SLF4J接口,实现了不同日志实现(如Logback)的适配,确保在启动时正确记录日志信息。
摘要由CSDN通过智能技术生成

一、简述

        SOFABoot提供了日志空间隔离能力。

        SOFABoot中间件能自动发现SOFABoot应用的日志实现依赖,并独立打印日志,解耦SOFABoot中间件日志和SOFABoot应用日志。

        SOFABoot通过其sofa-common-tools包提供日志空间隔离功能。

        首先看一下sofa-common-tools包中与日志空间隔离功能相关类的类图:

        通过上述类图可以看出,其抽象日志空间工厂类AbstractLoggerSpaceFactory实现了org.slf4j.ILoggerFactory接口,所以,SOFABoot基于SLF4J(Simple logging Facade forJava)日志组件实现日志空间隔离功能。对于SLF4J,它不同于其他日志类库,不是一个真正的日志实现,而是一个抽象层,它允许你在后台使用任意一个日志类库。相信大多数Java开发人员都使用过,在此不详述。

        SOFABoot日志空间隔离功能实现的基本原理如下:

        SOFABoot通过各种日志空间工厂Builder,根据SOFABoot中间件依赖的日志类库(SOFA支持的日志类库:logback、log4j2、log4j、commons-logging),为每个SOFABoot中间件创建各自的日志空间工厂类(抽象类AbstractLoggerSpaceFactory的匿名实现类)。在每个日志空间工厂类中,每个SOFABoot中间件及SOFABoot应用拥有其独有的日志空间(logback和log4j2使用ch.qos.logback.classic.LoggerContext类,log4j和commons-logging使用org.apache.log4j.spi.LoggerRepository实现类),并使用日志空间管理该中间件使用的所有logger,从而实现各SOFABoot中间件之间,以及其与SOFABoot应用之间的日志空间隔离,彼此独立配置,独立管理,互不影响。

        总结一下,主要包括两个方面的内容:

        1.  根据classpath路径上所包含的日志类库Jar包,自动选择所使用的日志类库;

        2.  根据所选的日志类库,为SOFABoot 应用和中间件创建独立的日志空间,管理各自的logger对象; 

二、使用方式

        (一)编写日志配置文件

        针对每种日志类库,SOFABoot中间件需要提供相应的日志配置文件

        分别编写logback、log4j2、log4j格式的日志配置文件log-conf.xml,然后按照日志类库的别名,分别存储在项目资源主目录src/main/resources下不同子目录中。

        子目录创建规则如下:

        子目录格式:中间件日志空间名称转换路径/log/不同日志类库的名字。

        其中:

        1.  中间件日志空间名称转换路径为把中间件日志空间名称中的.转换为/。例如:com.alipay.sofa.infra转换为路径com/alipay/sofa/infra。

        2.  不同日志类库的名字分别为logback、log4j2、log4j。

        在Infra模块中,日志配置文件的存储路径依次为:

        /com/alipay/sofa/infra/log/logback/log-conf.xml;

        /com/alipay/sofa/infra/log/log4j2/log-conf.xml;

        /com/alipay/sofa/infra/log/log4j /log-conf.xml;

        (二)编写一个Logger工厂类

        此类主要功能是从spaceName的空间里寻找指定名字的logger对象,这些 logger是从该spaceName下的日志实现配置中解析而来。

        例如:在SOFABoot中,Infra模块com.alipay.sofa.infra.log.InfraHealthCheckLoggerFactory,Healthcheck模块com.alipay.sofa.healthcheck.log.SofaBootHealthCheckLoggerFactory,Runtime模块的com.alipay.sofa.runtime.spi.log.SofaRuntimeLoggerFactory。

        以InfraHealthCheckLoggerFactory类为例,详细说明基本实现方式(如果没有其它特殊需求,除了红色代码需要根据具体SOFABoot中间件的日志空间名字修改外,其它保持不变):

1.  public class InfraHealthCheckLoggerFactory{
2.   
3.      public static final StringINFRASTRUCTURE_LOG_SPACE = "com.alipay.sofa.infra";
4.   
5.      /***
6.       * 获取日志对象
7.       *
8.       * @param clazz 日志的名字
9.       * @return 日志实现
10.      */
11.     public static org.slf4j.LoggergetLogger(Class<?> clazz) {
12.         if (clazz == null) {
13.             return null;
14.         }
15.         returngetLogger(clazz.getCanonicalName());
16.     }
17.  
18.     /**
19.      * 获取日志对象
20.      *
21.      * @param name 日志的名字
22.      * @return 日志实现
23.      */
24.     public static org.slf4j.LoggergetLogger(String name) {
25.         if (name == null || name.isEmpty()) {
26.             return null;
27.         }
28.         returnLoggerSpaceManager.getLoggerBySpace(name, INFRASTRUCTURE_LOG_SPACE);
29.     }
30. }

        设置Infra模块的日志空间名称。一般为含模块名称的包路径,此处为:com.alipay.sofa.infra。

        调用LoggerSpaceManager类getLoggerBySpace方法,从spaceName的空间里寻找指定名字的logger对象。

        (三)使用logger记录日志信息

        当我们需要在SOFABoot中间件的某个类中记录日志时,直接使用该中间件的Logger工厂类获取其日志空间中指定logger名称的logger对象,然后像使用SLF4J的logger一样,记录日志信息。

        例如,在Infra模块SofaBootVersionEndpoint类中,代码如下:

1.  private static final Logger logger =InfraHealthCheckLoggerFactory
2.                                             .getLogger(SofaBootVersionEndpoint.class);

三、源码解析

        以SOFABoot研发框架的基础模块infra-sofa-boot-starter为例,详细描述日志空间隔离功能的实现原理。

        在此提前说明,源码分析主要分析主流程,以及本人认为比较重要的一些内容,对于其它部分,大家可以基于本文档,自行研读。

        还是以SOFABoot自带的sofa-boot-sample为例,它依赖于infra-sofa-boot-starter模块。

        与SpringBoot最主要的特性自动配置AutoConfig一样,SOFABoot也是通过提供infra-sofa-boot-starter为我们自动配置。

        我们只需要在项目sofa-boot-sample的pom.xml文件中,添加infra-sofa-boot-starter到项目依赖中即可。

1.          <dependency>
2.              <groupId>com.alipay.sofa</groupId>
3.              <artifactId>infra-sofa-boot-starter</artifactId>
4.          </dependency>

        而infra-sofa-boot-starter依赖于sofa-common-tools包。

1.          <dependency>
2.              <groupId>com.alipay.sofa.common</groupId>
3.              <artifactId>sofa-common-tools</artifactId>
4.          </dependency>

        通过SpringApplication类run方法,启动项目

1.  @SpringBootApplication
2.  public class DemoApplication {
3.      public static void main(String[] args) {
4.          SpringApplication.run(DemoApplication.class,args);
5.      }
6.  }

        本文主要详述日志空间隔离相关的内容,SOFABoot的启动原理可以参考《启动原理》,在此不在详述。

        由于SOFABoot 基于SpringBoot进行构建,所以完全兼容SpringBoot。作为一个遵循SpringBoot规范的Jar包,也是通过自动配置(spring.factories)和SOFABootInfrastructureSpringContextInitializer(实现了ApplicationContextInitializer接口)完成infra的初始化工作。

        infra-sofa-boot-starter模块的spring.factories文件内容如下:

1.  # Initializers
2.  org.springframework.context.ApplicationContextInitializer=\
3.  com.alipay.sofa.infra.initializer.SOFABootInfrastructureSpringContextInitializer
4.   
5.  # Auto Configure
6.  org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
7.  com.alipay.sofa.infra.autoconfigure.SofaBootInfraAutoConfiguration
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

任性之闲来无事

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值