Springboot加载日志模块顺序

简介: 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日志并进行多维度分析。
相关文章
|
1月前
|
XML Java 数据格式
【二十九】springboot整合logback实现日志管理
【二十九】springboot整合logback实现日志管理
53 1
|
3月前
|
Java Spring
【Spring Boot】logback和log4j日志异常处理
【1月更文挑战第25天】【Spring Boot】logback和log4j日志异常处理
|
3月前
|
JSON Java 数据格式
微服务框架(十三)Spring Boot Logstash日志采集
  本文为Spring Boot中Log4j2对接Logstash,进行日志采集。Logstah只支持log4j,使用log4j2时需要通过TCP插件调用 此系列文章将会描述Java框架Spring Boot、服务治理框架Dubbo、应用容器引擎Docker,及使用Spring Boot集成Dubbo、Mybatis等开源框架,其中穿插着Spring Boot中日志切面等技术的实现,然后通过gitlab-CI以持续集成为Docker镜像。
|
9天前
|
缓存 前端开发 Java
SpringBoot启动后加载初始化数据
SpringBoot启动后加载初始化数据
|
10天前
|
Java 测试技术 数据库
SpringBoot启动时设置不加载数据库
SpringBoot启动时设置不加载数据库
10 0
|
1月前
|
XML Java 数据格式
【springboot原理篇】Bean的加载方式,面试必看
【springboot原理篇】Bean的加载方式,面试必看
|
1月前
|
SQL NoSQL Java
【七】springboot整合AOP实现日志操作
【七】springboot整合AOP实现日志操作
41 0
|
2月前
|
消息中间件 存储 监控
利用Scala编写公司内部监控软件的实时日志监控模块
在当今的软件开发领域,监控是确保系统稳定性和性能的关键一环。随着公司业务的不断扩展,我们迫切需要一套高效、可靠的实时日志监控系统,以及能够自动提交数据到网站的解决方案。本文将介绍如何利用Scala编写公司内部监控软件的实时日志监控模块,并探讨如何自动将监控到的数据提交到网站。
140 2
QGS
|
3月前
|
Java 数据库连接 Apache
Springboot日志框架logback与log4j2
Springboot日志框架logback与log4j2
QGS
37 0
|
3月前
|
存储 监控 安全
【Spring】SpringBoot日志
【Spring】SpringBoot日志