spring中日志相关对象的创建过程

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: spring中日志相关对象的创建过程,logback的扩展标签支持
  1. 容器在启动的过程中会实例化org.springframework.context.ApplicationListener的实现类,其中包括org.springframework.boot.context.logging.LoggingApplicationListener
  2. LoggingApplicationListener通过监听容器的生命周期事件来实例化和配置org.springframework.boot.logging.LoggingSystem对象的。
  3. 抽象类LoggingSystem指定了日志相关实例的生命周期和默认支持的日志框架。

    /**
     * 其支持默认支持Logback,Log4J,JavaLogging
     */
    public abstract class LoggingSystem {
        /**
         * 返回用户指定使用的或者默认的LoggingSystem,
         * 默认返回LogbackLoggingSystem
         */
        public static LoggingSystem get(ClassLoader classLoader) {
            String loggingSystem = System.getProperty(SYSTEM_PROPERTY);
            if (StringUtils.hasLength(loggingSystem)) {
                if (NONE.equals(loggingSystem)) {
                    return new NoOpLoggingSystem();
                }
                return get(classLoader, loggingSystem);
            }
            return SYSTEMS.entrySet().stream()
                    .filter((entry) -> ClassUtils.isPresent(entry.getKey(), classLoader))
                    .map((entry) -> get(classLoader, entry.getValue())).findFirst()
                    .orElseThrow(() -> new IllegalStateException(
                            "No suitable logging system located"));
        }
    }
  4. LoggingApplicationListener来调用LoggingSystem相关生命周期方法

    public class LoggingApplicationListener {
    
          //确定了具体使用哪个日志框架,默认使用Logback
          private void onApplicationStartingEvent(ApplicationStartingEvent event) {
              this.loggingSystem = LoggingSystem
                      .get(event.getSpringApplication().getClassLoader());
              this.loggingSystem.beforeInitialize();
          }
    
          //对LoggingSystem进行初始化
          private void onApplicationEnvironmentPreparedEvent(
                  ApplicationEnvironmentPreparedEvent event) {
              if (this.loggingSystem == null) {
                  this.loggingSystem = LoggingSystem
                          .get(event.getSpringApplication().getClassLoader());
              }
              initialize(event.getEnvironment(), event.getSpringApplication().getClassLoader());
          }
          //将LoggingSystem注册到容器中
          private void onApplicationPreparedEvent(ApplicationPreparedEvent event) {
              ConfigurableListableBeanFactory beanFactory = event.getApplicationContext()
                      .getBeanFactory();
              if (!beanFactory.containsBean(LOGGING_SYSTEM_BEAN_NAME)) {
                  beanFactory.registerSingleton(LOGGING_SYSTEM_BEAN_NAME, this.loggingSystem);
              }
          }
          //做一些清理相关的工作
          private void onContextClosedEvent() {
              if (this.loggingSystem != null) {
                  this.loggingSystem.cleanUp();
              }
          }   
      }
  5. Springboot中使用Logback框架进行日志打印,其配置文件是如何支持springProperty标签的?
    LogbackLoggingSystem在初始化的过程中会加载相关的xml配置文件,
    通过logback相关的解析器进行解析,并对解析器进行来扩展(SpringBootJoranConfigurator),使其支持pringProperty标签。

    SpringBootJoranConfigurator 中定义了扩展的标签和对该标签的解析方式

    class SpringBootJoranConfigurator extends JoranConfigurator {
    
            private LoggingInitializationContext initializationContext;
    
            SpringBootJoranConfigurator(LoggingInitializationContext initializationContext) {
                this.initializationContext = initializationContext;
            }
    
            @Override
            public void addInstanceRules(RuleStore rs) {
                super.addInstanceRules(rs);
                Environment environment = this.initializationContext.getEnvironment();
                rs.addRule(new ElementSelector("configuration/springProperty"),
                        new SpringPropertyAction(environment));
                rs.addRule(new ElementSelector("*/springProfile"),
                        new SpringProfileAction(this.initializationContext.getEnvironment()));
                rs.addRule(new ElementSelector("*/springProfile/*"), new NOPAction());
            }
    
        }
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
1月前
|
XML Java 测试技术
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
这篇文章介绍了Spring5框架的三个新特性:支持@Nullable注解以明确方法返回、参数和属性值可以为空;引入函数式风格的GenericApplicationContext进行对象注册和管理;以及如何整合JUnit5进行单元测试,同时讨论了JUnit4与JUnit5的整合方法,并提出了关于配置文件加载的疑问。
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
|
27天前
[Azure Developer]把Azure Function中ILogger对象静态化为静态方法提供日志记录
[Azure Developer]把Azure Function中ILogger对象静态化为静态方法提供日志记录
|
1月前
|
XML Java Maven
Spring5入门到实战------16、Spring5新功能 --整合日志框架(Log4j2)
这篇文章是Spring5框架的入门到实战教程,介绍了Spring5的新功能——整合日志框架Log4j2,包括Spring5对日志框架的通用封装、如何在项目中引入Log4j2、编写Log4j2的XML配置文件,并通过测试类展示了如何使用Log4j2进行日志记录。
Spring5入门到实战------16、Spring5新功能 --整合日志框架(Log4j2)
|
20天前
|
人工智能 Java Spring
Spring框架下,如何让你的日志管理像‘AI’一样智能,提升开发效率的秘密武器!
【8月更文挑战第31天】日志管理在软件开发中至关重要,不仅能帮助开发者追踪问题和调试程序,还是系统监控和运维的重要工具。在Spring框架下,通过合理配置Logback等日志框架,可大幅提升日志管理效率。本文将介绍如何引入日志框架、配置日志级别、在代码中使用Logger,以及利用ELK等工具进行日志聚合和分析,帮助你构建高效、可靠的日志管理系统,为开发和运维提供支持。
27 0
|
26天前
|
监控 Java Serverless
美团 Flink 大作业部署问题之想在Serverless平台上实时查看Spring Boot应用的日志要怎么操作
美团 Flink 大作业部署问题之想在Serverless平台上实时查看Spring Boot应用的日志要怎么操作
|
27天前
|
存储 Java Spring
【Azure Spring Cloud】Azure Spring Cloud服务,如何获取应用程序日志文件呢?
【Azure Spring Cloud】Azure Spring Cloud服务,如何获取应用程序日志文件呢?
|
27天前
|
Java Linux C++
【Azure 应用服务】App Service For Linux 部署Java Spring Boot应用后,查看日志文件时的疑惑
【Azure 应用服务】App Service For Linux 部署Java Spring Boot应用后,查看日志文件时的疑惑
|
30天前
|
安全 Java C#
Spring创建的单例对象,存在线程安全问题吗?
Spring框架提供了多种Bean作用域,包括单例(Singleton)、原型(Prototype)、请求(Request)、会话(Session)、全局会话(GlobalSession)等。单例是默认作用域,保证每个Spring容器中只有一个Bean实例;原型作用域则每次请求都会创建一个新的Bean实例;请求和会话作用域分别与HTTP请求和会话绑定,在Web应用中有效。 单例Bean在多线程环境中可能面临线程安全问题,Spring容器虽然确保Bean的创建过程是线程安全的,但Bean的使用安全性需开发者自行保证。保持Bean无状态是最简单的线程安全策略;
|
1月前
|
Java Windows Spring
Spring Boot CMD 运行日志输出中文乱码
Spring Boot CMD 运行日志输出中文乱码
25 0
|
4月前
|
存储 Java 数据库
Spring的使用-Bean对象的储存和获取/Bea对象的作用域与生命周期
Spring的使用-Bean对象的储存和获取/Bea对象的作用域与生命周期