spring boot 源码解析30-LoggersEndpoint

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】

前言

之前花了3篇文章来讲解spring boot中的LoggingSystem,其目的是为了讲解这边文章的主题–LoggersEndpoint.现在我们就来解析吧

解析

LoggersEndpoint 继承自AbstractEndpoint. 用来暴露日志的信息.

  1. 字段,构造器如下:

        private final LoggingSystem loggingSystem;
    
        public LoggersEndpoint(LoggingSystem loggingSystem) {
            super("loggers");
            Assert.notNull(loggingSystem, "LoggingSystem must not be null");
            this.loggingSystem = loggingSystem;
        }
  2. invoke实现如下:

        public Map invoke() {
            // 1. 获得关于logger的配置
            Collection configurations = this.loggingSystem
                    .getLoggerConfigurations();
            if (configurations == null) {
                return Collections.emptyMap();
            }
    
            Map result = new LinkedHashMap();
            // 2. 设置key-->levels,value --> 该loggingSystem 支持的日志级别,降序排列
            result.put("levels", getLevels());
            // 3. 设置key-->loggers,value -->map{key--> loger名,value-->LoggerLevels}
            result.put("loggers", getLoggers(configurations));
            return result;
        }
    1. 获得关于logger的配置
    2. 设置key–>levels,value –> 该loggingSystem 支持的日志级别,降序排列.代码如下:

          private NavigableSet getLevels() {
              Set levels = this.loggingSystem.getSupportedLogLevels();
              // 返回降序排序的set : TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF
              return new TreeSet(levels).descendingSet();
          }

      由于我们默认配置的是LogbackLoggingSystem,其getSupportedLogLevels返回的是:

      OFF, ERROR, INFO, TRACE, WARN, DEBUG

      这里有个问题,LogbackLoggingSystem中配置的是如下:

          private static final LogLevels LEVELS = new LogLevels();
          static {
              LEVELS.map(LogLevel.TRACE, Level.TRACE);
              LEVELS.map(LogLevel.TRACE, Level.ALL);
              LEVELS.map(LogLevel.DEBUG, Level.DEBUG);
              LEVELS.map(LogLevel.INFO, Level.INFO);
              LEVELS.map(LogLevel.WARN, Level.WARN);
              LEVELS.map(LogLevel.ERROR, Level.ERROR);
              LEVELS.map(LogLevel.FATAL, Level.ERROR);
              LEVELS.map(LogLevel.OFF, Level.OFF);
          }

      为什么返回的结果少了FATAL?

      原因是在LogLevels#map中有如下代码:

          if (!this.nativeToSystem.containsKey(nativeLevel)) {
                      this.nativeToSystem.put(nativeLevel, system);
          }

      由于我们首先保存LogLevel.ERROR, Level.ERROR,此时nativeToSystem中没有Level.ERROR,进行保存,然后我们在保存LogLevel.FATAL, Level.ERROR时,由于nativeToSystem中已经有Level.ERROR了,所有不会进行保存.因此该方法返回会少了1个FATAL.

      经过降序排列后,返回的是 OFF, ERROR, WARN, INFO, DEBUG, TRACE(按照在LogLevel中声明的声明的属性降序排列)

    3. 设置key–>loggers,value –>map{key–> loger名,value–>LoggerLevels}.其中getLoggers方法如下:

          private Map getLoggers(
                      Collection configurations) {
                  Map loggers = new LinkedHashMap(
                          configurations.size());
                  for (LoggerConfiguration configuration : configurations) {
                      loggers.put(configuration.getName(), new LoggerLevels(configuration));
                  }
                  return loggers;
              }

      遍历LoggerConfiguration,依次将其Logger名称, LoggerLevels 放入到loggers中.

      其中LoggerLevels–> 封装了LoggerConfiguration 中的configuredLevel,effectiveLevel.字段,构造器如下:

          // 配置的日志级别
          private String configuredLevel;
      
          // 生效的日志级别
          private String effectiveLevel;
      
          public LoggerLevels(LoggerConfiguration configuration) {
              this.configuredLevel = getName(configuration.getConfiguredLevel());
              this.effectiveLevel = getName(configuration.getEffectiveLevel());
          }
      
          private String getName(LogLevel level) {
              return (level == null ? null : level.name());
          }
  3. 此外,该类还声明了1个方法–> 用于获取指定logger名称的LoggerLevels,在LoggersMvcEndpoint中会调用.代码如下:

        public LoggerLevels invoke(String name) {
            Assert.notNull(name, "Name must not be null");
            LoggerConfiguration configuration = this.loggingSystem
                    .getLoggerConfiguration(name);
            return (configuration == null ? null : new LoggerLevels(configuration));
        }
  4. 属性配置:

    由于该类声明了@ConfigurationProperties(prefix = “endpoints.loggers”),因此可以通过如下属性进行配置:

        endpoints.loggers.enabled=true # Enable the endpoint.
        endpoints.loggers.id= # Endpoint identifier.
        endpoints.loggers.sensitive=true # Mark if the endpoint exposes sensitive information.
  5. 自动装配:

    在EndpointAutoConfiguration中进行了配置,代码如下:

        @Bean
        @ConditionalOnBean(LoggingSystem.class)
        @ConditionalOnMissingBean
        public LoggersEndpoint loggersEndpoint(LoggingSystem loggingSystem) {
            return new LoggersEndpoint(loggingSystem);
        }
    • @Bean–> 注册1个id为loggersEndpoint,类型为LoggersEndpoint的bean
    • @ConditionalOnBean(LoggingSystem.class)–> 当beanFactory中存在LoggingSystem类型的bean时生效
    • @ConditionalOnMissingBean–> 当beanFactory中不存在LoggersEndpoint类型的bean时生效

来源:[]()

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » spring boot 源码解析30-LoggersEndpoint

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏