序
本文主要研究下springboot2的LoggersEndpoint
实例
- GET /actuator/loggers
{
"levels": [
"OFF",
"ERROR",
"WARN",
"INFO",
"DEBUG",
"TRACE"
],
"loggers": {
"ROOT": {
"configuredLevel": "INFO",
"effectiveLevel": "INFO"
},
"com": {
"configuredLevel": null,
"effectiveLevel": "INFO"
},
"com.example": {
"configuredLevel": null,
"effectiveLevel": "INFO"
},
"com.example.config": {
"configuredLevel": null,
"effectiveLevel": "INFO"
}
}
}
- GET /actuator/loggers/com.example
{
"configuredLevel": null,
"effectiveLevel": "INFO"
}
- POST
curl -i -X POST -H 'Content-Type: application/json' -d '{"configuredLevel": "ERROR"}' http://localhost:8080/actuator/loggers/com.example
HTTP/1.1 204
Date: Wed, 25 Apr 2018 14:54:41 GMT
LoggersEndpointAutoConfiguration
spring-boot-actuator-autoconfigure-2.0.1.RELEASE-sources.jar!/org/springframework/boot/actuate/autoconfigure/logging/LoggersEndpointAutoConfiguration.java
@Configuration
public class LoggersEndpointAutoConfiguration {
@Bean
@ConditionalOnBean(LoggingSystem.class)
@Conditional(OnEnabledLoggingSystemCondition.class)
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint
public LoggersEndpoint loggersEndpoint(LoggingSystem loggingSystem) {
return new LoggersEndpoint(loggingSystem);
}
static class OnEnabledLoggingSystemCondition extends SpringBootCondition {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) {
ConditionMessage.Builder message = ConditionMessage
.forCondition("Logging System");
String loggingSystem = System.getProperty(LoggingSystem.SYSTEM_PROPERTY);
if (LoggingSystem.NONE.equals(loggingSystem)) {
return ConditionOutcome.noMatch(message.because("system property "
+ LoggingSystem.SYSTEM_PROPERTY + " is set to none"));
}
return ConditionOutcome.match(message.because("enabled"));
}
}
}
这里根据loggingSystem,来创建LoggersEndpoint;另外还使用了OnEnabledLoggingSystemCondition
LoggersEndpoint
spring-boot-actuator-2.0.1.RELEASE-sources.jar!/org/springframework/boot/actuate/logging/LoggersEndpoint.java
@Endpoint(id = "loggers")
public class LoggersEndpoint {
private final LoggingSystem loggingSystem;
/**
* Create a new {@link LoggersEndpoint} instance.
* @param loggingSystem the logging system to expose
*/
public LoggersEndpoint(LoggingSystem loggingSystem) {
Assert.notNull(loggingSystem, "LoggingSystem must not be null");
this.loggingSystem = loggingSystem;
}
@ReadOperation
public Map loggers() {
Collection configurations = this.loggingSystem
.getLoggerConfigurations();
if (configurations == null) {
return Collections.emptyMap();
}
Map result = new LinkedHashMap<>();
result.put("levels", getLevels());
result.put("loggers", getLoggers(configurations));
return result;
}
@ReadOperation
public LoggerLevels loggerLevels(@Selector String name) {
Assert.notNull(name, "Name must not be null");
LoggerConfiguration configuration = this.loggingSystem
.getLoggerConfiguration(name);
return (configuration == null ? null : new LoggerLevels(configuration));
}
@WriteOperation
public void configureLogLevel(@Selector String name,
@Nullable LogLevel configuredLevel) {
Assert.notNull(name, "Name must not be empty");
this.loggingSystem.setLogLevel(name, configuredLevel);
}
private NavigableSet getLevels() {
Set levels = this.loggingSystem.getSupportedLogLevels();
return new TreeSet<>(levels).descendingSet();
}
private Map getLoggers(
Collection configurations) {
Map loggers = new LinkedHashMap<>(configurations.size());
for (LoggerConfiguration configuration : configurations) {
loggers.put(configuration.getName(), new LoggerLevels(configuration));
}
return loggers;
}
/**
* Levels configured for a given logger exposed in a JSON friendly way.
*/
public static class LoggerLevels {
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());
}
public String getConfiguredLevel() {
return this.configuredLevel;
}
public String getEffectiveLevel() {
return this.effectiveLevel;
}
}
}
通过loggingSystem.getLoggerConfigurations()获取Collection
,然后getLoggers方法将configurations转换为Map
小结
LoggersEndpoint提供两个readOperation和一个writeOperation,分别用来读取和更改logger的level,非常实用。
doc
- Spring Boot Reference Guide