序
本文主要研究下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.exampleHTTP/1.1 204Date: 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
@Configurationpublic 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 Maploggers() { 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<String, LoggerLevels>
小结
LoggersEndpoint提供两个readOperation和一个writeOperation,分别用来读取和更改logger的level,非常实用。