您现在的位置是:首页 >学无止境 >Springboot Logger日志适配网站首页学无止境

Springboot Logger日志适配

路人丁. 2024-06-12 18:01:02
简介Springboot Logger日志适配

专栏文章:
Java Util Logger源码分析
Log4j源码分析
Slf4j源码分析
Logback源码分析

spring不是框架的生产商,但spring是框架的搬运工,对于应用的日志系统,spring采用自适应方式自动适配classpath下添加的日志框架jar包。
springboot在启动中通过SPI的方式加载日志框架,在启动的各个事件环节中初始化日志框架相关配置属性。
image.png
LoggingApplicationListener监听器中根据spring上下文启动事件,实现日志系统加载及初始化。

LoggingApplicationListener

public class LoggingApplicationListener implements GenericApplicationListener {

    private static final ConfigurationPropertyName LOGGING_LEVEL = ConfigurationPropertyName.of("logging.level");
    private static final ConfigurationPropertyName LOGGING_GROUP = ConfigurationPropertyName.of("logging.group");
    private static final Bindable<Map<String, LogLevel>> STRING_LOGLEVEL_MAP = Bindable.mapOf(String.class, LogLevel.class);
    private static final Bindable<Map<String, List<String>>> STRING_STRINGS_MAP = Bindable
        .of(ResolvableType.forClassWithGenerics(MultiValueMap.class, String.class, String.class).asMap());
    public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 20;
    public static final String CONFIG_PROPERTY = "logging.config";
    public static final String REGISTER_SHUTDOWN_HOOK_PROPERTY = "logging.register-shutdown-hook";
    public static final String LOGGING_SYSTEM_BEAN_NAME = "springBootLoggingSystem";
    public static final String LOG_FILE_BEAN_NAME = "springBootLogFile";
    public static final String LOGGER_GROUPS_BEAN_NAME = "springBootLoggerGroups";

    private static final Map<String, List<String>> DEFAULT_GROUP_LOGGERS;
    private static final Map<LogLevel, List<String>> SPRING_BOOT_LOGGING_LOGGERS;
    private static final AtomicBoolean shutdownHookRegistered = new AtomicBoolean();
    private final Log logger = LogFactory.getLog(getClass());
    // 日志系统适配器
    private LoggingSystem loggingSystem;
    // 封装日志文件输出地
    private LogFile logFile;
    // 日志分组
    private LoggerGroups loggerGroups;
    // order
    private int order = DEFAULT_ORDER;
    // 解析参数
    private boolean parseArgs = true;
    // 日志级别
    private LogLevel springBootLogging = null;
}

主要定义了几个重要的对象引用:

  1. LoggingSystem具体日志适配层对象
  2. LogFile日志输出位置,通过解析logging.file.path/logging.file.name得到
  3. LoggerGroups日志分组
  4. LogLevel日志级别

事件回调

// 监听的上下文事件
@Override
public void onApplicationEvent(ApplicationEvent event) {
    // 应用启动中
    if (event instanceof ApplicationStartingEvent) {
        onApplicationStartingEvent((ApplicationStartingEvent) event);
    }
    // 环境准备完成事件
    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();
    }
}
ApplicationStartingEvent
private void onApplicationStartingEvent(ApplicationStartingEvent event) {
    // 加载类路径下的LoggingSystem实现类,根据一定的顺序取第一个
    this.loggingSystem = LoggingSystem.get(event.getSpringApplication().getClassLoader());
this.loggingSystem.beforeInitialize();
}

LoggingSystem.get()会通过SPI的方式加载spring.factoriers文件中配置的可用实现
image.png
通过工厂类适配加载classpath中合适的LoggerSystem实现。
image.png

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。