您现在的位置是:首页 >学无止境 >Springboot Logger日志适配网站首页学无止境
Springboot Logger日志适配
简介Springboot Logger日志适配
专栏文章:
Java Util Logger源码分析
Log4j源码分析
Slf4j源码分析
Logback源码分析
spring不是框架的生产商,但spring是框架的搬运工,对于应用的日志系统,spring采用自适应方式自动适配classpath下添加的日志框架jar包。
springboot在启动中通过SPI的方式加载日志框架,在启动的各个事件环节中初始化日志框架相关配置属性。
在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;
}
主要定义了几个重要的对象引用:
- LoggingSystem具体日志适配层对象
- LogFile日志输出位置,通过解析
logging.file.path/logging.file.name
得到 - LoggerGroups日志分组
- 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文件中配置的可用实现
通过工厂类适配加载classpath中合适的LoggerSystem实现。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。