Return log levels in `/loggers` endpoint payload
Update `LoggersEndpoint` to additionally return the log levels actually supported by the system. Fixes gh-7396
This commit is contained in:
parent
764f13453a
commit
0e3a3df6f4
|
|
@ -338,6 +338,11 @@
|
|||
<artifactId>hsqldb</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.skyscreamer</groupId>
|
||||
<artifactId>jsonassert</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ import java.util.Collection;
|
|||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.logging.LogLevel;
|
||||
|
|
@ -35,8 +38,7 @@ import org.springframework.util.Assert;
|
|||
* @since 1.5.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "endpoints.loggers")
|
||||
public class LoggersEndpoint
|
||||
extends AbstractEndpoint<Map<String, LoggersEndpoint.LoggerLevels>> {
|
||||
public class LoggersEndpoint extends AbstractEndpoint<Map<String, Object>> {
|
||||
|
||||
private final LoggingSystem loggingSystem;
|
||||
|
||||
|
|
@ -51,18 +53,31 @@ public class LoggersEndpoint
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, LoggerLevels> invoke() {
|
||||
public Map<String, Object> invoke() {
|
||||
Collection<LoggerConfiguration> configurations = this.loggingSystem
|
||||
.getLoggerConfigurations();
|
||||
if (configurations == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<String, LoggerLevels> result = new LinkedHashMap<String, LoggerLevels>(
|
||||
Map<String, Object> result = new LinkedHashMap<String, Object>();
|
||||
result.put("levels", getLevels());
|
||||
result.put("loggers", getLoggers(configurations));
|
||||
return result;
|
||||
}
|
||||
|
||||
private NavigableSet<LogLevel> getLevels() {
|
||||
Set<LogLevel> levels = this.loggingSystem.getSupportedLogLevels();
|
||||
return new TreeSet<LogLevel>(levels).descendingSet();
|
||||
}
|
||||
|
||||
private Map<String, LoggerLevels> getLoggers(
|
||||
Collection<LoggerConfiguration> configurations) {
|
||||
Map<String, LoggerLevels> loggers = new LinkedHashMap<String, LoggerLevels>(
|
||||
configurations.size());
|
||||
for (LoggerConfiguration configuration : configurations) {
|
||||
result.put(configuration.getName(), new LoggerLevels(configuration));
|
||||
loggers.put(configuration.getName(), new LoggerLevels(configuration));
|
||||
}
|
||||
return result;
|
||||
return loggers;
|
||||
}
|
||||
|
||||
public LoggerLevels invoke(String name) {
|
||||
|
|
|
|||
|
|
@ -130,7 +130,9 @@ public class EndpointAutoConfigurationTests {
|
|||
public void loggersEndpointHasLoggers() throws Exception {
|
||||
load(CustomLoggingConfig.class, EndpointAutoConfiguration.class);
|
||||
LoggersEndpoint endpoint = this.context.getBean(LoggersEndpoint.class);
|
||||
Map<String, LoggerLevels> loggers = endpoint.invoke();
|
||||
Map<String, Object> result = endpoint.invoke();
|
||||
Map<String, LoggerLevels> loggers = (Map<String, LoggerLevels>) result
|
||||
.get("loggers");
|
||||
assertThat(loggers.size()).isGreaterThan(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@
|
|||
package org.springframework.boot.actuate.endpoint;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
|
@ -45,12 +48,21 @@ public class LoggersEndpointTests extends AbstractEndpointTests<LoggersEndpoint>
|
|||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void invokeShouldReturnConfigurations() throws Exception {
|
||||
given(getLoggingSystem().getLoggerConfigurations()).willReturn(Collections
|
||||
.singletonList(new LoggerConfiguration("ROOT", null, LogLevel.DEBUG)));
|
||||
LoggerLevels levels = getEndpointBean().invoke().get("ROOT");
|
||||
assertThat(levels.getConfiguredLevel()).isNull();
|
||||
assertThat(levels.getEffectiveLevel()).isEqualTo("DEBUG");
|
||||
given(getLoggingSystem().getSupportedLogLevels())
|
||||
.willReturn(EnumSet.allOf(LogLevel.class));
|
||||
Map<String, Object> result = getEndpointBean().invoke();
|
||||
Map<String, LoggerLevels> loggers = (Map<String, LoggerLevels>) result
|
||||
.get("loggers");
|
||||
Set<LogLevel> levels = (Set<LogLevel>) result.get("levels");
|
||||
LoggerLevels rootLevels = loggers.get("ROOT");
|
||||
assertThat(rootLevels.getConfiguredLevel()).isNull();
|
||||
assertThat(rootLevels.getEffectiveLevel()).isEqualTo("DEBUG");
|
||||
assertThat(levels).containsExactly(LogLevel.OFF, LogLevel.FATAL, LogLevel.ERROR,
|
||||
LogLevel.WARN, LogLevel.INFO, LogLevel.DEBUG, LogLevel.TRACE);
|
||||
}
|
||||
|
||||
public void invokeWhenNameSpecifiedShouldReturnLevels() throws Exception {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package org.springframework.boot.actuate.endpoint.mvc;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
|
@ -80,18 +81,23 @@ public class LoggersMvcEndpointTests {
|
|||
.alwaysDo(MockMvcResultHandlers.print()).build();
|
||||
}
|
||||
|
||||
@Before
|
||||
@After
|
||||
public void reset() {
|
||||
public void resetMocks() {
|
||||
Mockito.reset(this.loggingSystem);
|
||||
given(this.loggingSystem.getSupportedLogLevels())
|
||||
.willReturn(EnumSet.allOf(LogLevel.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLoggerShouldReturnAllLoggerConfigurations() throws Exception {
|
||||
given(this.loggingSystem.getLoggerConfigurations()).willReturn(Collections
|
||||
.singletonList(new LoggerConfiguration("ROOT", null, LogLevel.DEBUG)));
|
||||
String expected = "{\"levels\":[\"OFF\",\"FATAL\",\"ERROR\",\"WARN\",\"INFO\",\"DEBUG\",\"TRACE\"],"
|
||||
+ "\"loggers\":{\"ROOT\":{\"configuredLevel\":null,\"effectiveLevel\":\"DEBUG\"}}}";
|
||||
System.out.println(expected);
|
||||
this.mvc.perform(get("/loggers")).andExpect(status().isOk())
|
||||
.andExpect(content().string(equalTo("{\"ROOT\":{\"configuredLevel\":"
|
||||
+ "null,\"effectiveLevel\":\"DEBUG\"}}")));
|
||||
.andExpect(content().json(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@
|
|||
package org.springframework.boot.logging;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
|
@ -193,7 +195,9 @@ public abstract class AbstractLoggingSystem extends LoggingSystem {
|
|||
|
||||
public void map(LogLevel system, T nativeLevel) {
|
||||
this.systemToNative.put(system, nativeLevel);
|
||||
this.nativeToSystem.put(nativeLevel, system);
|
||||
if (!this.nativeToSystem.containsKey(nativeLevel)) {
|
||||
this.nativeToSystem.put(nativeLevel, system);
|
||||
}
|
||||
}
|
||||
|
||||
public LogLevel convertNativeToSystem(T level) {
|
||||
|
|
@ -204,6 +208,10 @@ public abstract class AbstractLoggingSystem extends LoggingSystem {
|
|||
return this.systemToNative.get(level);
|
||||
}
|
||||
|
||||
public Set<LogLevel> getSupported() {
|
||||
return new LinkedHashSet<LogLevel>(this.nativeToSystem.values());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,11 @@
|
|||
package org.springframework.boot.logging;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
|
@ -94,6 +96,15 @@ public abstract class LoggingSystem {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set of the {@link LogLevel LogLevels} that are actually supported by the
|
||||
* logging system.
|
||||
* @return the supported levels
|
||||
*/
|
||||
public Set<LogLevel> getSupportedLogLevels() {
|
||||
return EnumSet.allOf(LogLevel.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the logging level for a given logger.
|
||||
* @param loggerName the name of the logger to set
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogManager;
|
||||
import java.util.logging.Logger;
|
||||
|
|
@ -113,6 +114,11 @@ public class JavaLoggingSystem extends AbstractLoggingSystem {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<LogLevel> getSupportedLogLevels() {
|
||||
return LEVELS.getSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogLevel(String loggerName, LogLevel level) {
|
||||
Assert.notNull(level, "Level must not be null");
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import java.net.URL;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
|
@ -197,6 +198,11 @@ public class Log4J2LoggingSystem extends Slf4JLoggingSystem {
|
|||
getLoggerContext().reconfigure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<LogLevel> getSupportedLogLevels() {
|
||||
return LEVELS.getSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogLevel(String loggerName, LogLevel logLevel) {
|
||||
Level level = LEVELS.convertSystemToNative(logLevel);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import java.security.ProtectionDomain;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
|
|
@ -238,6 +239,11 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem {
|
|||
return new LoggerConfiguration(logger.getName(), level, effectiveLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<LogLevel> getSupportedLogLevels() {
|
||||
return LEVELS.getSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogLevel(String loggerName, LogLevel level) {
|
||||
ch.qos.logback.classic.Logger logger = getLogger(loggerName);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.logging.java;
|
|||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
|
|
@ -148,6 +149,13 @@ public class JavaLoggingSystemTests extends AbstractLoggingSystemTests {
|
|||
null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSupportedLevels() {
|
||||
assertThat(this.loggingSystem.getSupportedLogLevels())
|
||||
.isEqualTo(EnumSet.of(LogLevel.TRACE, LogLevel.DEBUG, LogLevel.INFO,
|
||||
LogLevel.WARN, LogLevel.ERROR, LogLevel.OFF));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setLevel() throws Exception {
|
||||
this.loggingSystem.beforeInitialize();
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import java.io.File;
|
|||
import java.io.FileReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
|
@ -122,6 +123,12 @@ public class Log4J2LoggingSystemTests extends AbstractLoggingSystemTests {
|
|||
this.loggingSystem.initialize(null, "classpath:log4j2-nonexistent.xml", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSupportedLevels() {
|
||||
assertThat(this.loggingSystem.getSupportedLogLevels())
|
||||
.isEqualTo(EnumSet.allOf(LogLevel.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setLevel() throws Exception {
|
||||
this.loggingSystem.beforeInitialize();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.springframework.boot.logging.logback;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.LogManager;
|
||||
|
|
@ -162,6 +163,13 @@ public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
|||
"classpath:logback-nonexistent.xml", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSupportedLevels() {
|
||||
assertThat(this.loggingSystem.getSupportedLogLevels())
|
||||
.isEqualTo(EnumSet.of(LogLevel.TRACE, LogLevel.DEBUG, LogLevel.INFO,
|
||||
LogLevel.WARN, LogLevel.ERROR, LogLevel.OFF));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setLevel() throws Exception {
|
||||
this.loggingSystem.beforeInitialize();
|
||||
|
|
|
|||
Loading…
Reference in New Issue