logback

logback部分

官网:http://logback.qos.ch/
这里忽略slf4j的外观模式

测试代码

测试代码:

jar版本
slfj 2.0.7
logback 1.4.7
    public static void main(String[] args) {
        Logger loggerFactory = LoggerFactory.getLogger("root");
        loggerFactory.debug("123");
    }

logback.xml

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level  aaa  %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

在这里插入图片描述

启动流程

入口:org.slf4j.LoggerFactory#getLogger(java.lang.String)

    static SLF4JServiceProvider getProvider() {
        if (INITIALIZATION_STATE == UNINITIALIZED) {
            //当没有初始化时,进行同步初始化
            synchronized (LoggerFactory.class) {
                if (INITIALIZATION_STATE == UNINITIALIZED) {
                    INITIALIZATION_STATE = ONGOING_INITIALIZATION;
                    performInitialization();
                }
            }
        }
        // INITIALIZATION_STATE 记录初始化状态
    }

sl4j的外观模式主要通过下面3和4的实现,重点放到3上

    private final static void bind() {
        try {
            //1.通过classLoader加载可能存在的SLF4JServiceProvider实现类
            List<SLF4JServiceProvider> providersList = findServiceProviders();
            //2.sout控制台报告获取到的实现类
            reportMultipleBindingAmbiguity(providersList);
            if (providersList != null && !providersList.isEmpty()) {
                //3.如果有组件实现SLF4JServiceProvider接口,则取第一个实现类
                PROVIDER = providersList.get(0);
                // SLF4JServiceProvider.initialize() is intended to be called here and nowhere else.
                 //3.1 子类实现进行初始化
                PROVIDER.initialize();
                INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
                reportActualBinding(providersList);
            } else {
                INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
                Util.report("No SLF4J providers were found.");
                Util.report("Defaulting to no-operation (NOP) logger implementation");
                Util.report("See " + NO_PROVIDERS_URL + " for further details.");
				 //4.如果没有,获取是否存在指定路径的类org/slf4j/impl/StaticLoggerBinder.class,这种将初始化将完成交由组件
                Set<URL> staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
                reportIgnoredStaticLoggerBinders(staticLoggerBinderPathSet);
            }
            postBindCleanUp();
        ...
    }

logback中的提供服务实现类 ch.qos.logback.classic.spi.LogbackServiceProvider

    @Override
    public void initialize() {
        ...
        //进行初始化
        initializeLoggerContext();
        ...
    }

上线文初始化执行类 ch.qos.logback.classic.util.ContextInitializer

    public void autoConfig(ClassLoader classLoader) throws JoranException {
        ...
        StatusListenerConfigHelper.installIfAsked(loggerContext);
        //⭐获取Configurator配置实现类,这里十分重要,配置文件读取
        List<Configurator> configuratorList = ClassicEnvUtil.loadFromServiceLoader(Configurator.class, classLoader);
        //排序
        sortByPriority(configuratorList);
        ...
        //省略依次执行配置实现类的代码
        ...
        // at this stage invoke basicConfigurator
        fallbackOnToBasicConfigurator();
    }


logback.xml、logback-test.xml配置文件读取的实现 ch.qos.logback.classic.util.DefaultJoranConfigurator

衍生一点:org.springframework.boot.logging.logback.RootLogLevelConfigurator,springboot3开始默认log级别info的实现,借鉴点可以通过实现configura来达到改变loggerContext的目的在这里插入图片描述

日志打印流程

在这里插入图片描述

其他

springboot-logging部分

https://springdoc.cn/spring-boot/features.html#features.logging

启动加载流程

启动监听LoggingApplicationListener
org.springframework.boot.context.logging.LoggingApplicationListener#onApplicationStartingEvent

	private void onApplicationStartingEvent(ApplicationStartingEvent event) {
	    //获取指定log组件
		this.loggingSystem = LoggingSystem.get(event.getSpringApplication().getClassLoader());
		//初始化
		this.loggingSystem.beforeInitialize();
	}

在这里插入图片描述
springboot中为了适配多个日志组件,设计了代理类DelegatingLoggingSystemFactory,

	@Override
	public LoggingSystem getLoggingSystem(ClassLoader classLoader) {
		List<LoggingSystemFactory> delegates = (this.delegates != null) ? this.delegates.apply(classLoader) : null;
		if (delegates != null) {
			for (LoggingSystemFactory delegate : delegates) {
			   // 依次遍历多个组件是否存在
				LoggingSystem loggingSystem = delegate.getLoggingSystem(classLoader);
				if (loggingSystem != null) {
					return loggingSystem;
				}
			}
		}
		return null;
	}

具体初始化实现部分以LogbackLoggingSystem举例

	@Override
	public void beforeInitialize() {
		LoggerContext loggerContext = getLoggerContext();
		if (isAlreadyInitialized(loggerContext)) {
			return;
		}
		super.beforeInitialize();
		configureJdkLoggingBridgeHandler();
		loggerContext.getTurboFilterList().add(FILTER);
	}

最终会走到这

	private void initializeWithConventions(LoggingInitializationContext initializationContext, LogFile logFile) {
	    //1.先加载原生配置文件 logback.xml
		String config = getSelfInitializationConfig();
		if (config != null && logFile == null) {
			// self initialization has occurred, reinitialize in case of property changes
			reinitialize(initializationContext);
			return;
		}
		if (config == null) {
		//2.取原生配置文件名+-spring的配置文件
			config = getSpringInitializationConfig();
		}
		if (config != null) {
			loadConfiguration(initializationContext, config, logFile);
			return;
		}
		loadDefaults(initializationContext, logFile);
	}

其他

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值