Springboot加载日志模块顺序

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: Springboot 加载 log4j2日志模块流程。

Springboot加载日志模块

Spring jcl

Spring jcl 是Springboot连接SLF4J的基础包,实现了对Log4j 2.x API是否存在,以及Spring框架类路径中的SLF4J 1.7api。

ServiceLoader

通过配置寻找接口的实现类,实现类的jar包的META-INF下新建一个文件夹services,并在services下新建一个文件,以接口的全限定名为文件名,内容为实现类的全限定名。

参考链接:
https://www.jianshu.com/p/7601ba434ff4
https://blog.csdn.net/shi2huang/article/details/80308531

Log4j获取ConfigurationFactory

核心代码

String ALL_TYPES = "*";
for (final ConfigurationFactory factory : getFactories()) {
    final String[] types = factory.getSupportedTypes();
    if (types != null) {
        for (final String type : types) {
            // 只有 XmlConfigurationFactory 符合条件
            if (type.equals(ALL_TYPES)) {
                final Configuration config = factory.getConfiguration(loggerContext, name, configLocation);
                if (config != null) {
                    return config;
                }
            }
        }
    }
}

Springboot加载log4j2的流程

Springboot 加载log4j2主要分为两个阶段,第一阶段成为start, 第二阶段为initalize

start阶段

start

  • LogAdapter利用Class.forName加载不同日志的实现,使用内部类进行调用
  • log4j 通过PluginProcess对 @Plugin注释识别ConfigurationFactory,具体可参考Springboot配置log4j2爬坑
initalize阶段

初始化阶段,SpringApplication.run()方法的 SpringApplicationRunListeners

initalize

  • beforeInitialize(), 判断是否以slf4j桥接。
if (isBridgeJulIntoSlf4j()) {
    removeJdkLoggingBridgeHandler();
    SLF4JBridgeHandler.install();
}

// ClassUtils.isPresent() Sping 实现的类似Class.forName功能
ClassUtils.isPresent(BRIDGE_HANDLER, getClassLoader());

  • LoggingApplicationListener 代码配置onApplicationEvent
public void onApplicationEvent(ApplicationEvent event) {
    // beforeInitalize 阶段
    if (event instanceof ApplicationStartingEvent) {
        onApplicationStartingEvent((ApplicationStartingEvent) event);
    }
    // 环境配置,即initalizeing阶段
    else if (event instanceof ApplicationEnvironmentPreparedEvent) {
        onApplicationEnvironmentPreparedEvent(
                (ApplicationEnvironmentPreparedEvent) event);
    }
    // 程序运行起来后,调用日志阶段
    else if (event instanceof ApplicationPreparedEvent) {
        onApplicationPreparedEvent((ApplicationPreparedEvent) event);
    }
    
    // 程序关闭
    else if (event instanceof ContextClosedEvent && ((ContextClosedEvent) event)
            .getApplicationContext().getParent() == null) {
        onContextClosedEvent();
    }
    
    // 失败
    else if (event instanceof ApplicationFailedEvent) {
        onApplicationFailedEvent();
    }
}
  • Log4j2判断日志是否为同一实例,利用了identityHashCoder给AppClassLoader做身份哈希判重
  • shutdownhook 学习(有时间在研究)
private void registerShutdownHookIfNecessary(Environment environment,
        LoggingSystem loggingSystem) {
    boolean registerShutdownHook = environment
            .getProperty(REGISTER_SHUTDOWN_HOOK_PROPERTY, Boolean.class, false);
    if (registerShutdownHook) {
        Runnable shutdownHandler = loggingSystem.getShutdownHandler();
        if (shutdownHandler != null
                && shutdownHookRegistered.compareAndSet(false, true)) {
            registerShutdownHook(new Thread(shutdownHandler));
        }
    }
}

void registerShutdownHook(Thread shutdownHook) {
    Runtime.getRuntime().addShutdownHook(shutdownHook);
}
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
4月前
|
Java 中间件
SpringBoot入门(6)- 添加Logback日志
SpringBoot入门(6)- 添加Logback日志
142 5
|
2月前
|
开发框架 运维 监控
Spring Boot中的日志框架选择
在Spring Boot开发中,日志管理至关重要。常见的日志框架有Logback、Log4j2、Java Util Logging和Slf4j。选择合适的日志框架需考虑性能、灵活性、社区支持及集成配置。本文以Logback为例,演示了如何记录不同级别的日志消息,并强调合理配置日志框架对提升系统可靠性和开发效率的重要性。
|
2月前
|
存储 安全 Java
Spring Boot 3 集成Spring AOP实现系统日志记录
本文介绍了如何在Spring Boot 3中集成Spring AOP实现系统日志记录功能。通过定义`SysLog`注解和配置相应的AOP切面,可以在方法执行前后自动记录日志信息,包括操作的开始时间、结束时间、请求参数、返回结果、异常信息等,并将这些信息保存到数据库中。此外,还使用了`ThreadLocal`变量来存储每个线程独立的日志数据,确保线程安全。文中还展示了项目实战中的部分代码片段,以及基于Spring Boot 3 + Vue 3构建的快速开发框架的简介与内置功能列表。此框架结合了当前主流技术栈,提供了用户管理、权限控制、接口文档自动生成等多项实用特性。
93 8
|
4月前
|
监控 IDE Java
如何在无需重新启动服务器的情况下在 Spring Boot 上重新加载我的更改?
如何在无需重新启动服务器的情况下在 Spring Boot 上重新加载我的更改?
222 8
|
4月前
|
Java 中间件
SpringBoot入门(6)- 添加Logback日志
SpringBoot入门(6)- 添加Logback日志
80 1
|
4月前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
84 1
|
5月前
|
架构师 Java 开发者
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
在40岁老架构师尼恩的读者交流群中,近期多位读者成功获得了知名互联网企业的面试机会,如得物、阿里、滴滴等。然而,面对“Spring Boot自动装配机制”等核心面试题,部分读者因准备不足而未能顺利通过。为此,尼恩团队将系统化梳理和总结这一主题,帮助大家全面提升技术水平,让面试官“爱到不能自已”。
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
|
5月前
|
Java Maven Spring
SpringBoot日志整合
SpringBoot日志整合
49 2
|
5月前
|
数据采集 监控 Java
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
本文是关于SpringBoot日志的详细教程,涵盖日志的定义、用途、SLF4J框架的使用、日志级别、持久化、文件分割及格式配置等内容。
320 0
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
|
5月前
|
SQL XML 监控
SpringBoot框架日志详解
本文详细介绍了日志系统的重要性及其在不同环境下的配置方法。日志用于记录系统运行时的问题,确保服务的可靠性。文章解释了各种日志级别(如 info、warn、error 等)的作用,并介绍了常用的日志框架如 SLF4J 和 Logback。此外,还说明了如何在 SpringBoot 中配置日志输出路径及日志级别,包括控制台输出与文件输出的具体设置方法。通过这些配置,开发者能够更好地管理和调试应用程序。