|
|
|
@ -9,45 +9,45 @@
|
|
|
|
|
|
|
|
|
|
- 日志级别: `org.springframework.boot.logging.LogLevel`
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
public enum LogLevel {
|
|
|
|
|
TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
```java
|
|
|
|
|
public enum LogLevel {
|
|
|
|
|
TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Java 日志实现
|
|
|
|
|
|
|
|
|
|
- `org.springframework.boot.logging.java.JavaLoggingSystem`
|
|
|
|
|
|
|
|
|
|
![image-20200323144523848](../../images/SpringBoot/image-20200323144523848.png)
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
static {
|
|
|
|
|
// KEY : springBoot 定义的日志级别, value: jdk 定义的日志级别
|
|
|
|
|
LEVELS.map(LogLevel.TRACE, Level.FINEST);
|
|
|
|
|
LEVELS.map(LogLevel.DEBUG, Level.FINE);
|
|
|
|
|
LEVELS.map(LogLevel.INFO, Level.INFO);
|
|
|
|
|
LEVELS.map(LogLevel.WARN, Level.WARNING);
|
|
|
|
|
LEVELS.map(LogLevel.ERROR, Level.SEVERE);
|
|
|
|
|
LEVELS.map(LogLevel.FATAL, Level.SEVERE);
|
|
|
|
|
LEVELS.map(LogLevel.OFF, Level.OFF);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
![image-20200323144523848](../../images/SpringBoot/image-20200323144523848.png)
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
static {
|
|
|
|
|
// KEY : springBoot 定义的日志级别, value: jdk 定义的日志级别
|
|
|
|
|
LEVELS.map(LogLevel.TRACE, Level.FINEST);
|
|
|
|
|
LEVELS.map(LogLevel.DEBUG, Level.FINE);
|
|
|
|
|
LEVELS.map(LogLevel.INFO, Level.INFO);
|
|
|
|
|
LEVELS.map(LogLevel.WARN, Level.WARNING);
|
|
|
|
|
LEVELS.map(LogLevel.ERROR, Level.SEVERE);
|
|
|
|
|
LEVELS.map(LogLevel.FATAL, Level.SEVERE);
|
|
|
|
|
LEVELS.map(LogLevel.OFF, Level.OFF);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- LEVELS 对象
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
protected static class LogLevels<T> {
|
|
|
|
|
/**
|
|
|
|
|
* key : SpringBoot 中定义的日志级别, value: 其他日志框架的日志级别
|
|
|
|
|
*/
|
|
|
|
|
private final Map<LogLevel, T> systemToNative;
|
|
|
|
|
/**
|
|
|
|
|
* key : 其他日志框架的日志级别 , value: springBoot 中定义中定义的日志级别
|
|
|
|
|
*/
|
|
|
|
|
private final Map<T, LogLevel> nativeToSystem;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
```java
|
|
|
|
|
protected static class LogLevels<T> {
|
|
|
|
|
/**
|
|
|
|
|
* key : SpringBoot 中定义的日志级别, value: 其他日志框架的日志级别
|
|
|
|
|
*/
|
|
|
|
|
private final Map<LogLevel, T> systemToNative;
|
|
|
|
|
/**
|
|
|
|
|
* key : 其他日志框架的日志级别 , value: springBoot 中定义中定义的日志级别
|
|
|
|
|
*/
|
|
|
|
|
private final Map<T, LogLevel> nativeToSystem;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## LoggingSystem
|
|
|
|
|
|
|
|
|
@ -56,33 +56,33 @@
|
|
|
|
|
|
|
|
|
|
- 一个 map 对象: `SYSTEMS`
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
/**
|
|
|
|
|
* key: 第三方日志框架的类 value: springBoot 中的处理类
|
|
|
|
|
*/
|
|
|
|
|
private static final Map<String, String> SYSTEMS;
|
|
|
|
|
|
|
|
|
|
static {
|
|
|
|
|
Map<String, String> systems = new LinkedHashMap<>();
|
|
|
|
|
systems.put("ch.qos.logback.core.Appender", "org.springframework.boot.logging.logback.LogbackLoggingSystem");
|
|
|
|
|
systems.put("org.apache.logging.log4j.core.impl.Log4jContextFactory",
|
|
|
|
|
"org.springframework.boot.logging.log4j2.Log4J2LoggingSystem");
|
|
|
|
|
systems.put("java.util.logging.LogManager", "org.springframework.boot.logging.java.JavaLoggingSystem");
|
|
|
|
|
SYSTEMS = Collections.unmodifiableMap(systems);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
```java
|
|
|
|
|
/**
|
|
|
|
|
* key: 第三方日志框架的类 value: springBoot 中的处理类
|
|
|
|
|
*/
|
|
|
|
|
private static final Map<String, String> SYSTEMS;
|
|
|
|
|
|
|
|
|
|
static {
|
|
|
|
|
Map<String, String> systems = new LinkedHashMap<>();
|
|
|
|
|
systems.put("ch.qos.logback.core.Appender", "org.springframework.boot.logging.logback.LogbackLoggingSystem");
|
|
|
|
|
systems.put("org.apache.logging.log4j.core.impl.Log4jContextFactory",
|
|
|
|
|
"org.springframework.boot.logging.log4j2.Log4J2LoggingSystem");
|
|
|
|
|
systems.put("java.util.logging.LogManager", "org.springframework.boot.logging.java.JavaLoggingSystem");
|
|
|
|
|
SYSTEMS = Collections.unmodifiableMap(systems);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- 各个抽象方法
|
|
|
|
|
|
|
|
|
|
| 方法名称 | 作用 |
|
|
|
|
|
| ----------------------- | ---------------------------------- |
|
|
|
|
|
| beforeInitialize | 初始化之前调用,目的是减少日志输出 |
|
|
|
|
|
| initialize | 初始化日志 |
|
|
|
|
|
| cleanUp | 清除日志 |
|
|
|
|
|
| getShutdownHandler | |
|
|
|
|
|
| getSupportedLogLevels | 获取支持的日志级别 |
|
|
|
|
|
| setLogLevel | 设置日志级别 |
|
|
|
|
|
| getLoggerConfigurations | 获取日志配置 |
|
|
|
|
|
| 方法名称 | 作用 |
|
|
|
|
|
| ----------------------- | ---------------------------------- |
|
|
|
|
|
| beforeInitialize | 初始化之前调用,目的是减少日志输出 |
|
|
|
|
|
| initialize | 初始化日志 |
|
|
|
|
|
| cleanUp | 清除日志 |
|
|
|
|
|
| getShutdownHandler | |
|
|
|
|
|
| getSupportedLogLevels | 获取支持的日志级别 |
|
|
|
|
|
| setLogLevel | 设置日志级别 |
|
|
|
|
|
| getLoggerConfigurations | 获取日志配置 |
|
|
|
|
|
|
|
|
|
|
### get
|
|
|
|
|
|
|
|
|
@ -136,27 +136,28 @@ private static LoggingSystem get(ClassLoader classLoader, String loggingSystemCl
|
|
|
|
|
![image-20200323154205484](../../images/SpringBoot/image-20200323154205484.png)
|
|
|
|
|
|
|
|
|
|
- 链路
|
|
|
|
|
1. `org.springframework.boot.context.logging.LoggingApplicationListener#onApplicationEvent`
|
|
|
|
|
2. `org.springframework.boot.context.logging.LoggingApplicationListener#onApplicationStartingEvent`
|
|
|
|
|
3. `org.springframework.boot.logging.LoggingSystem#beforeInitialize`
|
|
|
|
|
|
|
|
|
|
1. `org.springframework.boot.context.logging.LoggingApplicationListener#onApplicationEvent`
|
|
|
|
|
2. `org.springframework.boot.context.logging.LoggingApplicationListener#onApplicationStartingEvent`
|
|
|
|
|
3. `org.springframework.boot.logging.LoggingSystem#beforeInitialize`
|
|
|
|
|
|
|
|
|
|
- 因为前文中我们已知对象是:`org.springframework.boot.logging.logback.LogbackLoggingSystem` 直接看这个类的 `beforeInitialize` 方法
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
@Override
|
|
|
|
|
public void beforeInitialize() {
|
|
|
|
|
// 日志上下文
|
|
|
|
|
LoggerContext loggerContext = getLoggerContext();
|
|
|
|
|
// 是否初始化
|
|
|
|
|
if (isAlreadyInitialized(loggerContext)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 父类方法
|
|
|
|
|
super.beforeInitialize();
|
|
|
|
|
// 添加过滤器
|
|
|
|
|
loggerContext.getTurboFilterList().add(FILTER);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
```java
|
|
|
|
|
@Override
|
|
|
|
|
public void beforeInitialize() {
|
|
|
|
|
// 日志上下文
|
|
|
|
|
LoggerContext loggerContext = getLoggerContext();
|
|
|
|
|
// 是否初始化
|
|
|
|
|
if (isAlreadyInitialized(loggerContext)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 父类方法
|
|
|
|
|
super.beforeInitialize();
|
|
|
|
|
// 添加过滤器
|
|
|
|
|
loggerContext.getTurboFilterList().add(FILTER);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- 初始化之前的的操作完成了初始化方法开始
|
|
|
|
|
|
|
|
|
@ -286,26 +287,26 @@ private static LoggingSystem get(ClassLoader classLoader, String loggingSystemCl
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
@Override
|
|
|
|
|
public void initialize(LoggingInitializationContext initializationContext, String configLocation, LogFile logFile) {
|
|
|
|
|
LoggerContext loggerContext = getLoggerContext();
|
|
|
|
|
// 是否加载过
|
|
|
|
|
if (isAlreadyInitialized(loggerContext)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 日志初始化
|
|
|
|
|
super.initialize(initializationContext, configLocation, logFile);
|
|
|
|
|
// 删除 FILTER
|
|
|
|
|
loggerContext.getTurboFilterList().remove(FILTER);
|
|
|
|
|
// 初始化标记
|
|
|
|
|
markAsInitialized(loggerContext);
|
|
|
|
|
if (StringUtils.hasText(System.getProperty(CONFIGURATION_FILE_PROPERTY))) {
|
|
|
|
|
getLogger(LogbackLoggingSystem.class.getName()).warn("Ignoring '" + CONFIGURATION_FILE_PROPERTY
|
|
|
|
|
+ "' system property. Please use 'logging.config' instead.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
```java
|
|
|
|
|
@Override
|
|
|
|
|
public void initialize(LoggingInitializationContext initializationContext, String configLocation, LogFile logFile) {
|
|
|
|
|
LoggerContext loggerContext = getLoggerContext();
|
|
|
|
|
// 是否加载过
|
|
|
|
|
if (isAlreadyInitialized(loggerContext)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 日志初始化
|
|
|
|
|
super.initialize(initializationContext, configLocation, logFile);
|
|
|
|
|
// 删除 FILTER
|
|
|
|
|
loggerContext.getTurboFilterList().remove(FILTER);
|
|
|
|
|
// 初始化标记
|
|
|
|
|
markAsInitialized(loggerContext);
|
|
|
|
|
if (StringUtils.hasText(System.getProperty(CONFIGURATION_FILE_PROPERTY))) {
|
|
|
|
|
getLogger(LogbackLoggingSystem.class.getName()).warn("Ignoring '" + CONFIGURATION_FILE_PROPERTY
|
|
|
|
|
+ "' system property. Please use 'logging.config' instead.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- 标记 `markAsInitialized`
|
|
|
|
|
|
|
|
|
@ -332,49 +333,49 @@ private static LoggingSystem get(ClassLoader classLoader, String loggingSystemCl
|
|
|
|
|
|
|
|
|
|
- 添加依赖
|
|
|
|
|
|
|
|
|
|
```XML
|
|
|
|
|
<dependency>
|
|
|
|
|
<groupId>org.springframework.boot</groupId>
|
|
|
|
|
<artifactId>spring-boot-starter-logging</artifactId>
|
|
|
|
|
<version>${revision}</version>
|
|
|
|
|
</dependency>
|
|
|
|
|
```XML
|
|
|
|
|
<dependency>
|
|
|
|
|
<groupId>org.springframework.boot</groupId>
|
|
|
|
|
<artifactId>spring-boot-starter-logging</artifactId>
|
|
|
|
|
<version>${revision}</version>
|
|
|
|
|
</dependency>
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- 添加配置文件
|
|
|
|
|
|
|
|
|
|
![image-20200323161442058](../../images/SpringBoot/image-20200323161442058.png)
|
|
|
|
|
![image-20200323161442058](../../images/SpringBoot/image-20200323161442058.png)
|
|
|
|
|
|
|
|
|
|
![image-20200323161522570](../../images/SpringBoot/image-20200323161522570.png)
|
|
|
|
|
![image-20200323161522570](../../images/SpringBoot/image-20200323161522570.png)
|
|
|
|
|
|
|
|
|
|
- 此时配置文件地址出现了
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
protected String getSelfInitializationConfig() {
|
|
|
|
|
// 寻找配置文件
|
|
|
|
|
return findConfig(getStandardConfigLocations());
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
```java
|
|
|
|
|
protected String getSelfInitializationConfig() {
|
|
|
|
|
// 寻找配置文件
|
|
|
|
|
return findConfig(getStandardConfigLocations());
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
@Override
|
|
|
|
|
protected String[] getStandardConfigLocations() {
|
|
|
|
|
return new String[] { "logback-test.groovy", "logback-test.xml", "logback.groovy", "logback.xml" };
|
|
|
|
|
}
|
|
|
|
|
```java
|
|
|
|
|
@Override
|
|
|
|
|
protected String[] getStandardConfigLocations() {
|
|
|
|
|
return new String[] { "logback-test.groovy", "logback-test.xml", "logback.groovy", "logback.xml" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
private String findConfig(String[] locations) {
|
|
|
|
|
for (String location : locations) {
|
|
|
|
|
ClassPathResource resource = new ClassPathResource(location, this.classLoader);
|
|
|
|
|
if (resource.exists()) {
|
|
|
|
|
return "classpath:" + location;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
```java
|
|
|
|
|
private String findConfig(String[] locations) {
|
|
|
|
|
for (String location : locations) {
|
|
|
|
|
ClassPathResource resource = new ClassPathResource(location, this.classLoader);
|
|
|
|
|
if (resource.exists()) {
|
|
|
|
|
return "classpath:" + location;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- 此时自定义配置文件如何获取的已经明了。
|
|
|
|
|
|
|
|
|
|