前言
调整日志等级有很多方法 比如: spring-boot-actuator
or spring-boot-admin
今天来说个 spring-cloud
的方法
一、添加依赖
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-boot.version>2.7.4</spring-boot.version>
<spring-cloud.version>2021.0.4</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
</dependency>
二、 配置
spring.application.name = dynamic
server.port = 808
management.server.port = 8081
management.endpoints.web.exposure.include = *
# 支持post请求
management.endpoint.env.post.enabled = true
# http://localhost:8081/management/
management.endpoints.web.basePath = /management
management.endpoints.jmx.exposure.include = *
三、actuator 查看日志等级
四、修改 org.springframework的日志等级
curl --location 'localhost:8081/management/env' \
--header 'Content-Type: application/json' \
--data '{
"name":"logging.level.org.springframework",
"value":"debug"
}'
修改成功
五、原理
核心类
org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder
org.springframework.cloud.context.environment.EnvironmentManager
org.springframework.cloud.logging.LoggingRebinder
1、日志初始化
org.springframework.boot.context.logging.LoggingApplicationListener#initialize
protected void initialize(ConfigurableEnvironment environment, ClassLoader classLoader) {
getLoggingSystemProperties(environment).apply();
this.logFile = LogFile.get(environment);
if (this.logFile != null) {
this.logFile.applyToSystemProperties();
}
this.loggerGroups = new LoggerGroups(DEFAULT_GROUP_LOGGERS);
initializeEarlyLoggingLevel(environment);
initializeSystem(environment, this.loggingSystem, this.logFile);
initializeFinalLoggingLevels(environment, this.loggingSystem);
registerShutdownHookIfNecessary(environment, this.loggingSystem);
}
2、在调用 actuator接口 localhost:8081/management/env
会进入
org.springframework.cloud.context.environment.WritableEnvironmentEndpointWebExtension#write
@WriteOperation
public Object write(String name, String value) {
this.environment.setProperty(name, value);
return Collections.singletonMap(name, value);
}
把最新的值 set environment中
org.springframework.cloud.context.environment.EnvironmentManager#setProperty
@ManagedOperation
public void setProperty(String name, String value) {
if (!this.environment.getPropertySources().contains(MANAGER_PROPERTY_SOURCE)) {
synchronized (this.map) {
if (!this.environment.getPropertySources().contains(MANAGER_PROPERTY_SOURCE)) {
MapPropertySource source = new MapPropertySource(MANAGER_PROPERTY_SOURCE, this.map);
this.environment.getPropertySources().addFirst(source);
}
}
}
if (!value.equals(this.environment.getProperty(name))) {
this.map.put(name, value);
publish(new EnvironmentChangeEvent(this.publisher, Collections.singleton(name)));
}
}
先去判断值是否和老的不相等 不相等 会把新的值 放到缓存中,然后发送 EnvironmentChangeEvent
事件
3、Logging事件监听 org.springframework.cloud.logging.LoggingRebinder#onApplicationEvent
@Override
public void onApplicationEvent(EnvironmentChangeEvent event) {
if (this.environment == null) {
return;
}
LoggingSystem system = LoggingSystem.get(LoggingSystem.class.getClassLoader());
setLogLevels(system, this.environment);
}
protected void setLogLevels(LoggingSystem system, Environment environment) {
Map<String, String> levels = Binder.get(environment).bind("logging.level", STRING_STRING_MAP)
.orElseGet(Collections::emptyMap);
for (Entry<String, String> entry : levels.entrySet()) {
setLogLevel(system, environment, entry.getKey(), entry.getValue().toString());
}
}
levels=[org.springframework=info, root=debug]
Map<String, String> levels = Binder.get(environment).bind("logging.level", STRING_STRING_MAP)
这个代码会在Environment
找到所有的 logging.level
的配置然后迭代修改而我实际可能就改了一个