Add support for configuring logging groups via endpoint
See gh-17515
This commit is contained in:
parent
8197feac15
commit
b9047c22e0
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.logging;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
|
||||
import org.springframework.boot.actuate.logging.LoggersEndpoint;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
|
|
@ -24,6 +25,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
|||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
|
||||
import org.springframework.boot.logging.LoggingGroups;
|
||||
import org.springframework.boot.logging.LoggingSystem;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
|
|
@ -45,8 +47,9 @@ public class LoggersEndpointAutoConfiguration {
|
|||
@ConditionalOnBean(LoggingSystem.class)
|
||||
@Conditional(OnEnabledLoggingSystemCondition.class)
|
||||
@ConditionalOnMissingBean
|
||||
public LoggersEndpoint loggersEndpoint(LoggingSystem loggingSystem) {
|
||||
return new LoggersEndpoint(loggingSystem);
|
||||
public LoggersEndpoint loggersEndpoint(LoggingSystem loggingSystem,
|
||||
ObjectProvider<LoggingGroups> loggingGroupsObjectProvider) {
|
||||
return new LoggersEndpoint(loggingSystem, loggingGroupsObjectProvider.getIfAvailable());
|
||||
}
|
||||
|
||||
static class OnEnabledLoggingSystemCondition extends SpringBootCondition {
|
||||
|
|
|
|||
|
|
@ -17,14 +17,17 @@
|
|||
package org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.actuate.logging.LoggersEndpoint;
|
||||
import org.springframework.boot.logging.LogLevel;
|
||||
import org.springframework.boot.logging.LoggerConfiguration;
|
||||
import org.springframework.boot.logging.LoggingGroups;
|
||||
import org.springframework.boot.logging.LoggingSystem;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
|
@ -54,32 +57,60 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
|
|||
fieldWithPath("configuredLevel").description("Configured level of the logger, if any.").optional(),
|
||||
fieldWithPath("effectiveLevel").description("Effective level of the logger."));
|
||||
|
||||
private static final List<FieldDescriptor> groupLevelFields = Arrays.asList(
|
||||
fieldWithPath("configuredLevel").description("Configured level of the logger group"),
|
||||
fieldWithPath("members").description("Loggers that are part of this group").optional());
|
||||
|
||||
@MockBean
|
||||
private LoggingSystem loggingSystem;
|
||||
|
||||
@MockBean
|
||||
private ObjectProvider<LoggingGroups> loggingGroupsObjectProvider;
|
||||
|
||||
@MockBean
|
||||
LoggingGroups loggingGroups;
|
||||
|
||||
@Test
|
||||
void allLoggers() throws Exception {
|
||||
given(this.loggingSystem.getSupportedLogLevels()).willReturn(EnumSet.allOf(LogLevel.class));
|
||||
given(this.loggingSystem.getLoggerConfigurations())
|
||||
.willReturn(Arrays.asList(new LoggerConfiguration("ROOT", LogLevel.INFO, LogLevel.INFO),
|
||||
new LoggerConfiguration("com.example", LogLevel.DEBUG, LogLevel.DEBUG)));
|
||||
given(this.loggingGroupsObjectProvider.getIfAvailable()).willReturn(this.loggingGroups);
|
||||
given(this.loggingGroups.getLoggerGroupNames()).willReturn(Collections.singleton("test"));
|
||||
given(this.loggingGroups.getLoggerGroup("test")).willReturn(Arrays.asList("test.member"));
|
||||
given(this.loggingGroups.getLoggerGroupConfiguredLevel("test")).willReturn(LogLevel.INFO);
|
||||
this.mockMvc.perform(get("/actuator/loggers")).andExpect(status().isOk())
|
||||
.andDo(MockMvcRestDocumentation.document("loggers/all",
|
||||
responseFields(fieldWithPath("levels").description("Levels support by the logging system."),
|
||||
fieldWithPath("loggers").description("Loggers keyed by name."))
|
||||
.andWithPrefix("loggers.*.", levelFields)));
|
||||
fieldWithPath("loggers").description("Loggers keyed by name."),
|
||||
fieldWithPath("groups").description("Logger groups keyed by name"))
|
||||
.andWithPrefix("loggers.*.", levelFields)
|
||||
.andWithPrefix("groups.*.", groupLevelFields)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void logger() throws Exception {
|
||||
given(this.loggingGroupsObjectProvider.getIfAvailable()).willReturn(this.loggingGroups);
|
||||
given(this.loggingSystem.getLoggerConfiguration("com.example"))
|
||||
.willReturn(new LoggerConfiguration("com.example", LogLevel.INFO, LogLevel.INFO));
|
||||
this.mockMvc.perform(get("/actuator/loggers/com.example")).andExpect(status().isOk())
|
||||
.andDo(MockMvcRestDocumentation.document("loggers/single", responseFields(levelFields)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void loggerGroups() throws Exception {
|
||||
given(this.loggingGroupsObjectProvider.getIfAvailable()).willReturn(this.loggingGroups);
|
||||
given(this.loggingGroups.isGroup("com.example")).willReturn(true);
|
||||
given(this.loggingGroups.getLoggerGroup("com.example")).willReturn(Arrays.asList("com.member", "com.member2"));
|
||||
given(this.loggingGroups.getLoggerGroupConfiguredLevel("com.example")).willReturn(LogLevel.INFO);
|
||||
this.mockMvc.perform(get("/actuator/loggers/com.example")).andExpect(status().isOk())
|
||||
.andDo(MockMvcRestDocumentation.document("loggers/group", responseFields(groupLevelFields)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void setLogLevel() throws Exception {
|
||||
given(this.loggingGroupsObjectProvider.getIfAvailable()).willReturn(this.loggingGroups);
|
||||
this.mockMvc
|
||||
.perform(post("/actuator/loggers/com.example").content("{\"configuredLevel\":\"debug\"}")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
|
|
@ -89,8 +120,24 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
|
|||
verify(this.loggingSystem).setLogLevel("com.example", LogLevel.DEBUG);
|
||||
}
|
||||
|
||||
@Test
|
||||
void setLogLevelOfLoggerGroup() throws Exception {
|
||||
given(this.loggingGroupsObjectProvider.getIfAvailable()).willReturn(this.loggingGroups);
|
||||
given(this.loggingGroups.isGroup("com.example")).willReturn(true);
|
||||
this.mockMvc
|
||||
.perform(post("/actuator/loggers/com.example")
|
||||
.content("{\"configuredLevel\":\"debug\"}").contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isNoContent()).andDo(
|
||||
MockMvcRestDocumentation.document("loggers/setGroup",
|
||||
requestFields(fieldWithPath("configuredLevel").description(
|
||||
"Level for the logger group. May be omitted to clear the level of the loggers.")
|
||||
.optional())));
|
||||
verify(this.loggingGroups).setLoggerGroupLevel("com.example", LogLevel.DEBUG);
|
||||
}
|
||||
|
||||
@Test
|
||||
void clearLogLevel() throws Exception {
|
||||
given(this.loggingGroupsObjectProvider.getIfAvailable()).willReturn(this.loggingGroups);
|
||||
this.mockMvc
|
||||
.perform(post("/actuator/loggers/com.example").content("{}").contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isNoContent()).andDo(MockMvcRestDocumentation.document("loggers/clear"));
|
||||
|
|
@ -102,8 +149,9 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
|
|||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
LoggersEndpoint endpoint(LoggingSystem loggingSystem) {
|
||||
return new LoggersEndpoint(loggingSystem);
|
||||
LoggersEndpoint endpoint(LoggingSystem loggingSystem,
|
||||
ObjectProvider<LoggingGroups> loggingGroupsObjectProvider) {
|
||||
return new LoggersEndpoint(loggingSystem, loggingGroupsObjectProvider.getIfAvailable());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.actuate.logging;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.Set;
|
||||
|
|
@ -30,6 +31,7 @@ import org.springframework.boot.actuate.endpoint.annotation.Selector;
|
|||
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
|
||||
import org.springframework.boot.logging.LogLevel;
|
||||
import org.springframework.boot.logging.LoggerConfiguration;
|
||||
import org.springframework.boot.logging.LoggingGroups;
|
||||
import org.springframework.boot.logging.LoggingSystem;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
|
@ -39,6 +41,7 @@ import org.springframework.util.Assert;
|
|||
*
|
||||
* @author Ben Hale
|
||||
* @author Phillip Webb
|
||||
* @author HaiTao Zhang
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Endpoint(id = "loggers")
|
||||
|
|
@ -46,13 +49,17 @@ public class LoggersEndpoint {
|
|||
|
||||
private final LoggingSystem loggingSystem;
|
||||
|
||||
private final LoggingGroups loggingGroups;
|
||||
|
||||
/**
|
||||
* Create a new {@link LoggersEndpoint} instance.
|
||||
* @param loggingSystem the logging system to expose
|
||||
* @param loggingGroups the logging group to expose if it exists
|
||||
*/
|
||||
public LoggersEndpoint(LoggingSystem loggingSystem) {
|
||||
public LoggersEndpoint(LoggingSystem loggingSystem, LoggingGroups loggingGroups) {
|
||||
Assert.notNull(loggingSystem, "LoggingSystem must not be null");
|
||||
this.loggingSystem = loggingSystem;
|
||||
this.loggingGroups = loggingGroups;
|
||||
}
|
||||
|
||||
@ReadOperation
|
||||
|
|
@ -64,19 +71,32 @@ public class LoggersEndpoint {
|
|||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("levels", getLevels());
|
||||
result.put("loggers", getLoggers(configurations));
|
||||
if (this.loggingGroups != null && this.loggingGroups.getLoggerGroupNames() != null) {
|
||||
Set<String> groups = this.loggingGroups.getLoggerGroupNames();
|
||||
result.put("groups", getLoggerGroups(groups));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ReadOperation
|
||||
public LoggerLevels loggerLevels(@Selector String name) {
|
||||
Assert.notNull(name, "Name must not be null");
|
||||
if (this.loggingGroups != null && this.loggingGroups.isGroup(name)) {
|
||||
List<String> members = this.loggingGroups.getLoggerGroup(name);
|
||||
LogLevel groupConfiguredLevel = this.loggingGroups.getLoggerGroupConfiguredLevel(name);
|
||||
return new GroupLoggerLevels(groupConfiguredLevel, members);
|
||||
}
|
||||
LoggerConfiguration configuration = this.loggingSystem.getLoggerConfiguration(name);
|
||||
return (configuration != null) ? new LoggerLevels(configuration) : null;
|
||||
return (configuration != null) ? new SingleLoggerLevels(configuration) : null;
|
||||
}
|
||||
|
||||
@WriteOperation
|
||||
public void configureLogLevel(@Selector String name, @Nullable LogLevel configuredLevel) {
|
||||
Assert.notNull(name, "Name must not be empty");
|
||||
if (this.loggingGroups != null && this.loggingGroups.isGroup(name)) {
|
||||
this.loggingGroups.setLoggerGroupLevel(name, configuredLevel);
|
||||
return;
|
||||
}
|
||||
this.loggingSystem.setLogLevel(name, configuredLevel);
|
||||
}
|
||||
|
||||
|
|
@ -88,11 +108,21 @@ public class LoggersEndpoint {
|
|||
private Map<String, LoggerLevels> getLoggers(Collection<LoggerConfiguration> configurations) {
|
||||
Map<String, LoggerLevels> loggers = new LinkedHashMap<>(configurations.size());
|
||||
for (LoggerConfiguration configuration : configurations) {
|
||||
loggers.put(configuration.getName(), new LoggerLevels(configuration));
|
||||
loggers.put(configuration.getName(), new SingleLoggerLevels(configuration));
|
||||
}
|
||||
return loggers;
|
||||
}
|
||||
|
||||
private Map<String, LoggerLevels> getLoggerGroups(Set<String> groups) {
|
||||
Map<String, LoggerLevels> loggerGroups = new LinkedHashMap<>(groups.size());
|
||||
for (String name : groups) {
|
||||
List<String> members = this.loggingGroups.getLoggerGroup(name);
|
||||
LogLevel groupConfiguredLevel = this.loggingGroups.getLoggerGroupConfiguredLevel(name);
|
||||
loggerGroups.put(name, new GroupLoggerLevels(groupConfiguredLevel, members));
|
||||
}
|
||||
return loggerGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Levels configured for a given logger exposed in a JSON friendly way.
|
||||
*/
|
||||
|
|
@ -100,11 +130,8 @@ public class LoggersEndpoint {
|
|||
|
||||
private String configuredLevel;
|
||||
|
||||
private String effectiveLevel;
|
||||
|
||||
public LoggerLevels(LoggerConfiguration configuration) {
|
||||
this.configuredLevel = getName(configuration.getConfiguredLevel());
|
||||
this.effectiveLevel = getName(configuration.getEffectiveLevel());
|
||||
public LoggerLevels(LogLevel configuredLevel) {
|
||||
this.configuredLevel = getName(configuredLevel);
|
||||
}
|
||||
|
||||
private String getName(LogLevel level) {
|
||||
|
|
@ -113,6 +140,33 @@ public class LoggersEndpoint {
|
|||
|
||||
public String getConfiguredLevel() {
|
||||
return this.configuredLevel;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class GroupLoggerLevels extends LoggerLevels {
|
||||
|
||||
private List<String> members;
|
||||
|
||||
public GroupLoggerLevels(LogLevel configuredLevel, List<String> members) {
|
||||
super(configuredLevel);
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
public List<String> getMembers() {
|
||||
return this.members;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class SingleLoggerLevels extends LoggerLevels {
|
||||
|
||||
private String effectiveLevel;
|
||||
|
||||
public SingleLoggerLevels(LoggerConfiguration configuration) {
|
||||
super(configuration.getConfiguredLevel());
|
||||
this.effectiveLevel = super.getName(configuration.getEffectiveLevel());
|
||||
}
|
||||
|
||||
public String getEffectiveLevel() {
|
||||
|
|
|
|||
|
|
@ -23,9 +23,12 @@ import java.util.Set;
|
|||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.logging.LoggersEndpoint.GroupLoggerLevels;
|
||||
import org.springframework.boot.actuate.logging.LoggersEndpoint.LoggerLevels;
|
||||
import org.springframework.boot.actuate.logging.LoggersEndpoint.SingleLoggerLevels;
|
||||
import org.springframework.boot.logging.LogLevel;
|
||||
import org.springframework.boot.logging.LoggerConfiguration;
|
||||
import org.springframework.boot.logging.LoggingGroups;
|
||||
import org.springframework.boot.logging.LoggingSystem;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
|
@ -38,46 +41,110 @@ import static org.mockito.Mockito.verify;
|
|||
*
|
||||
* @author Ben Hale
|
||||
* @author Andy Wilkinson
|
||||
* @author HaiTao Zhang
|
||||
*/
|
||||
class LoggersEndpointTests {
|
||||
|
||||
private final LoggingSystem loggingSystem = mock(LoggingSystem.class);
|
||||
|
||||
private final LoggingGroups loggingGroups = mock(LoggingGroups.class);
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void loggersShouldReturnLoggerConfigurations() {
|
||||
void loggersShouldReturnLoggerConfigurationsWithNoLoggerGroups() {
|
||||
given(this.loggingSystem.getLoggerConfigurations())
|
||||
.willReturn(Collections.singletonList(new LoggerConfiguration("ROOT", null, LogLevel.DEBUG)));
|
||||
given(this.loggingSystem.getSupportedLogLevels()).willReturn(EnumSet.allOf(LogLevel.class));
|
||||
Map<String, Object> result = new LoggersEndpoint(this.loggingSystem).loggers();
|
||||
given(this.loggingGroups.getLoggerGroupNames()).willReturn(null);
|
||||
Map<String, Object> result = new LoggersEndpoint(this.loggingSystem, this.loggingGroups).loggers();
|
||||
Map<String, LoggerLevels> loggers = (Map<String, LoggerLevels>) result.get("loggers");
|
||||
Set<LogLevel> levels = (Set<LogLevel>) result.get("levels");
|
||||
LoggerLevels rootLevels = loggers.get("ROOT");
|
||||
SingleLoggerLevels rootLevels = (SingleLoggerLevels) 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);
|
||||
assertThat(result.get("groups")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void loggersShouldReturnLoggerConfigurationsWithLoggerGroups() {
|
||||
given(this.loggingSystem.getLoggerConfigurations())
|
||||
.willReturn(Collections.singletonList(new LoggerConfiguration("ROOT", null, LogLevel.DEBUG)));
|
||||
given(this.loggingSystem.getSupportedLogLevels()).willReturn(EnumSet.allOf(LogLevel.class));
|
||||
given(this.loggingGroups.getLoggerGroup("test")).willReturn(Collections.singletonList("test.member"));
|
||||
given(this.loggingGroups.getLoggerGroupNames()).willReturn(Collections.singleton("test"));
|
||||
given(this.loggingGroups.getLoggerGroupConfiguredLevel("test")).willReturn(LogLevel.DEBUG);
|
||||
Map<String, Object> result = new LoggersEndpoint(this.loggingSystem, this.loggingGroups).loggers();
|
||||
Map<String, LoggerLevels> loggerGroups = (Map<String, LoggerLevels>) result.get("groups");
|
||||
GroupLoggerLevels testLoggerLevel = (GroupLoggerLevels) loggerGroups.get("test");
|
||||
Map<String, LoggerLevels> loggers = (Map<String, LoggerLevels>) result.get("loggers");
|
||||
Set<LogLevel> levels = (Set<LogLevel>) result.get("levels");
|
||||
SingleLoggerLevels rootLevels = (SingleLoggerLevels) 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);
|
||||
assertThat(loggerGroups).isNotNull();
|
||||
assertThat(testLoggerLevel).isNotNull();
|
||||
assertThat(testLoggerLevel.getConfiguredLevel()).isEqualTo("DEBUG");
|
||||
assertThat(testLoggerLevel.getMembers()).isEqualTo(Collections.singletonList("test.member"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void loggerLevelsWhenNameSpecifiedShouldReturnLevels() {
|
||||
given(this.loggingGroups.isGroup("ROOT")).willReturn(false);
|
||||
given(this.loggingSystem.getLoggerConfiguration("ROOT"))
|
||||
.willReturn(new LoggerConfiguration("ROOT", null, LogLevel.DEBUG));
|
||||
LoggerLevels levels = new LoggersEndpoint(this.loggingSystem).loggerLevels("ROOT");
|
||||
SingleLoggerLevels levels = (SingleLoggerLevels) new LoggersEndpoint(this.loggingSystem, this.loggingGroups)
|
||||
.loggerLevels("ROOT");
|
||||
assertThat(levels.getConfiguredLevel()).isNull();
|
||||
assertThat(levels.getEffectiveLevel()).isEqualTo("DEBUG");
|
||||
}
|
||||
|
||||
@Test
|
||||
void groupNameSpecifiedShouldReturnConfiguredLevelAndMembers() {
|
||||
given(this.loggingGroups.isGroup("test")).willReturn(true);
|
||||
given(this.loggingGroups.getLoggerGroup("test")).willReturn(Collections.singletonList("test.member"));
|
||||
given(this.loggingGroups.getLoggerGroupConfiguredLevel("test")).willReturn(LogLevel.DEBUG);
|
||||
GroupLoggerLevels levels = (GroupLoggerLevels) new LoggersEndpoint(this.loggingSystem, this.loggingGroups)
|
||||
.loggerLevels("test");
|
||||
assertThat(levels.getConfiguredLevel()).isEqualTo("DEBUG");
|
||||
assertThat(levels.getMembers()).isEqualTo(Collections.singletonList("test.member"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void configureLogLevelShouldSetLevelOnLoggingSystem() {
|
||||
new LoggersEndpoint(this.loggingSystem).configureLogLevel("ROOT", LogLevel.DEBUG);
|
||||
given(this.loggingGroups.getLoggerGroup("ROOT")).willReturn(null);
|
||||
new LoggersEndpoint(this.loggingSystem, this.loggingGroups).configureLogLevel("ROOT", LogLevel.DEBUG);
|
||||
verify(this.loggingSystem).setLogLevel("ROOT", LogLevel.DEBUG);
|
||||
}
|
||||
|
||||
@Test
|
||||
void configureLogLevelWithNullSetsLevelOnLoggingSystemToNull() {
|
||||
new LoggersEndpoint(this.loggingSystem).configureLogLevel("ROOT", null);
|
||||
given(this.loggingGroups.getLoggerGroup("ROOT")).willReturn(null);
|
||||
new LoggersEndpoint(this.loggingSystem, this.loggingGroups).configureLogLevel("ROOT", null);
|
||||
verify(this.loggingSystem).setLogLevel("ROOT", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void configureLogLevelInLoggerGroupShouldSetLevelOnLoggingSystem() {
|
||||
given(this.loggingGroups.isGroup("test")).willReturn(true);
|
||||
given(this.loggingGroups.getLoggerGroup("test")).willReturn(Collections.singletonList("test.member"));
|
||||
new LoggersEndpoint(this.loggingSystem, this.loggingGroups).configureLogLevel("test", LogLevel.DEBUG);
|
||||
verify(this.loggingGroups).setLoggerGroupLevel("test", LogLevel.DEBUG);
|
||||
}
|
||||
|
||||
@Test
|
||||
void configureLogLevelWithNullInLoggerGroupShouldSetLevelOnLoggingSystem() {
|
||||
given(this.loggingGroups.isGroup("test")).willReturn(true);
|
||||
given(this.loggingGroups.getLoggerGroup("test")).willReturn(Collections.singletonList("test.member"));
|
||||
new LoggersEndpoint(this.loggingSystem, this.loggingGroups).configureLogLevel("test", null);
|
||||
verify(this.loggingGroups).setLoggerGroupLevel("test", null);
|
||||
}
|
||||
|
||||
// @Test
|
||||
// void
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,14 +21,17 @@ import java.util.Collections;
|
|||
import java.util.EnumSet;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
import org.hamcrest.collection.IsIterableContainingInAnyOrder;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.actuate.endpoint.http.ActuatorMediaType;
|
||||
import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest;
|
||||
import org.springframework.boot.logging.LogLevel;
|
||||
import org.springframework.boot.logging.LoggerConfiguration;
|
||||
import org.springframework.boot.logging.LoggingGroups;
|
||||
import org.springframework.boot.logging.LoggingSystem;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
|
@ -50,6 +53,7 @@ import static org.mockito.Mockito.verifyZeroInteractions;
|
|||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
* @author Andy Wilkinson
|
||||
* @author HaiTao Zhang
|
||||
*/
|
||||
class LoggersEndpointWebIntegrationTests {
|
||||
|
||||
|
|
@ -57,17 +61,26 @@ class LoggersEndpointWebIntegrationTests {
|
|||
|
||||
private LoggingSystem loggingSystem;
|
||||
|
||||
private LoggingGroups loggingGroups;
|
||||
|
||||
private ObjectProvider<LoggingGroups> loggingGroupsObjectProvider;
|
||||
|
||||
@BeforeEach
|
||||
@AfterEach
|
||||
void resetMocks(ConfigurableApplicationContext context, WebTestClient client) {
|
||||
this.client = client;
|
||||
this.loggingSystem = context.getBean(LoggingSystem.class);
|
||||
this.loggingGroups = context.getBean(LoggingGroups.class);
|
||||
this.loggingGroupsObjectProvider = context.getBean(ObjectProvider.class);
|
||||
Mockito.reset(this.loggingSystem);
|
||||
Mockito.reset(this.loggingGroups);
|
||||
given(this.loggingSystem.getSupportedLogLevels()).willReturn(EnumSet.allOf(LogLevel.class));
|
||||
given(this.loggingGroupsObjectProvider.getIfAvailable()).willReturn(this.loggingGroups);
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void getLoggerShouldReturnAllLoggerConfigurations() {
|
||||
given(this.loggingGroups.getLoggerGroupNames()).willReturn(null);
|
||||
given(this.loggingSystem.getLoggerConfigurations())
|
||||
.willReturn(Collections.singletonList(new LoggerConfiguration("ROOT", null, LogLevel.DEBUG)));
|
||||
this.client.get().uri("/actuator/loggers").exchange().expectStatus().isOk().expectBody().jsonPath("$.length()")
|
||||
|
|
@ -78,8 +91,27 @@ class LoggersEndpointWebIntegrationTests {
|
|||
.isEqualTo("DEBUG");
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void getLoggerShouldReturnAllLoggerConfigurationsWithLoggerGroups() {
|
||||
given(this.loggingGroups.getLoggerGroupNames()).willReturn(Collections.singleton("test"));
|
||||
given(this.loggingGroups.getLoggerGroup("test")).willReturn(Arrays.asList("test.member1", "test.member2"));
|
||||
given(this.loggingGroups.getLoggerGroupConfiguredLevel("test")).willReturn(LogLevel.DEBUG);
|
||||
given(this.loggingSystem.getLoggerConfigurations())
|
||||
.willReturn(Collections.singletonList(new LoggerConfiguration("ROOT", null, LogLevel.DEBUG)));
|
||||
this.client.get().uri("/actuator/loggers").exchange().expectStatus().isOk().expectBody().jsonPath("$.length()")
|
||||
.isEqualTo(3).jsonPath("levels")
|
||||
.isEqualTo(jsonArrayOf("OFF", "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"))
|
||||
.jsonPath("loggers.length()").isEqualTo(1).jsonPath("loggers.ROOT.length()").isEqualTo(2)
|
||||
.jsonPath("loggers.ROOT.configuredLevel").isEqualTo(null).jsonPath("loggers.ROOT.effectiveLevel")
|
||||
.isEqualTo("DEBUG").jsonPath("groups.length()").isEqualTo(1).jsonPath("groups.test.length()")
|
||||
.isEqualTo(2).jsonPath("groups.test.configuredLevel").isEqualTo("DEBUG")
|
||||
.jsonPath("groups.test.members.length()").isEqualTo(2).jsonPath("groups.test.members")
|
||||
.value(IsIterableContainingInAnyOrder.containsInAnyOrder("test.member1", "test.member2"));
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void getLoggerShouldReturnLogLevels() {
|
||||
given(this.loggingGroups.isGroup("ROOT")).willReturn(false);
|
||||
given(this.loggingSystem.getLoggerConfiguration("ROOT"))
|
||||
.willReturn(new LoggerConfiguration("ROOT", null, LogLevel.DEBUG));
|
||||
this.client.get().uri("/actuator/loggers/ROOT").exchange().expectStatus().isOk().expectBody()
|
||||
|
|
@ -88,12 +120,24 @@ class LoggersEndpointWebIntegrationTests {
|
|||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void getLoggersWhenLoggerNotFoundShouldReturnNotFound() {
|
||||
void getLoggersWhenLoggerAndLoggerGroupNotFoundShouldReturnNotFound() {
|
||||
this.client.get().uri("/actuator/loggers/com.does.not.exist").exchange().expectStatus().isNotFound();
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void getLoggerGroupShouldReturnConfiguredLogLevelAndMembers() {
|
||||
given(this.loggingGroups.isGroup("test")).willReturn(true);
|
||||
given(this.loggingGroups.getLoggerGroupConfiguredLevel("test")).willReturn(LogLevel.DEBUG);
|
||||
given(this.loggingGroups.getLoggerGroup("test")).willReturn(Arrays.asList("test.member1", "test.member2"));
|
||||
this.client.get().uri("actuator/loggers/test").exchange().expectStatus().isOk().expectBody()
|
||||
.jsonPath("$.length()").isEqualTo(2).jsonPath("members")
|
||||
.value(IsIterableContainingInAnyOrder.containsInAnyOrder("test.member1", "test.member2"))
|
||||
.jsonPath("configuredLevel").isEqualTo("DEBUG");
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void setLoggerUsingApplicationJsonShouldSetLogLevel() {
|
||||
given(this.loggingGroups.isGroup("ROOT")).willReturn(false);
|
||||
this.client.post().uri("/actuator/loggers/ROOT").contentType(MediaType.APPLICATION_JSON)
|
||||
.body(Collections.singletonMap("configuredLevel", "debug")).exchange().expectStatus().isNoContent();
|
||||
verify(this.loggingSystem).setLogLevel("ROOT", LogLevel.DEBUG);
|
||||
|
|
@ -101,6 +145,7 @@ class LoggersEndpointWebIntegrationTests {
|
|||
|
||||
@WebEndpointTest
|
||||
void setLoggerUsingActuatorV2JsonShouldSetLogLevel() {
|
||||
given(this.loggingGroups.isGroup("ROOT")).willReturn(false);
|
||||
this.client.post().uri("/actuator/loggers/ROOT")
|
||||
.contentType(MediaType.parseMediaType(ActuatorMediaType.V2_JSON))
|
||||
.body(Collections.singletonMap("configuredLevel", "debug")).exchange().expectStatus().isNoContent();
|
||||
|
|
@ -108,7 +153,26 @@ class LoggersEndpointWebIntegrationTests {
|
|||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void setLoggerWithWrongLogLevelResultInBadRequestResponse() {
|
||||
void setLoggerGroupUsingActuatorV2JsonShouldSetLogLevel() {
|
||||
given(this.loggingGroups.isGroup("test")).willReturn(true);
|
||||
given(this.loggingGroups.getLoggerGroup("test")).willReturn(Arrays.asList("test.member1", "test.member2"));
|
||||
this.client.post().uri("/actuator/loggers/test")
|
||||
.contentType(MediaType.parseMediaType(ActuatorMediaType.V2_JSON))
|
||||
.body(Collections.singletonMap("configuredLevel", "debug")).exchange().expectStatus().isNoContent();
|
||||
verify(this.loggingGroups).setLoggerGroupLevel("test", LogLevel.DEBUG);
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void setLoggerGroupUsingApplicationJsonShouldSetLogLevel() {
|
||||
given(this.loggingGroups.isGroup("test")).willReturn(true);
|
||||
given(this.loggingGroups.getLoggerGroup("test")).willReturn(Arrays.asList("test.member1", "test.member2"));
|
||||
this.client.post().uri("/actuator/loggers/test").contentType(MediaType.APPLICATION_JSON)
|
||||
.body(Collections.singletonMap("configuredLevel", "debug")).exchange().expectStatus().isNoContent();
|
||||
verify(this.loggingGroups).setLoggerGroupLevel("test", LogLevel.DEBUG);
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void setLoggerOrLoggerGroupWithWrongLogLevelResultInBadRequestResponse() {
|
||||
this.client.post().uri("/actuator/loggers/ROOT").contentType(MediaType.APPLICATION_JSON)
|
||||
.body(Collections.singletonMap("configuredLevel", "other")).exchange().expectStatus().isBadRequest();
|
||||
verifyZeroInteractions(this.loggingSystem);
|
||||
|
|
@ -116,6 +180,7 @@ class LoggersEndpointWebIntegrationTests {
|
|||
|
||||
@WebEndpointTest
|
||||
void setLoggerWithNullLogLevel() {
|
||||
given(this.loggingGroups.isGroup("ROOT")).willReturn(false);
|
||||
this.client.post().uri("/actuator/loggers/ROOT")
|
||||
.contentType(MediaType.parseMediaType(ActuatorMediaType.V2_JSON))
|
||||
.body(Collections.singletonMap("configuredLevel", null)).exchange().expectStatus().isNoContent();
|
||||
|
|
@ -124,12 +189,33 @@ class LoggersEndpointWebIntegrationTests {
|
|||
|
||||
@WebEndpointTest
|
||||
void setLoggerWithNoLogLevel() {
|
||||
given(this.loggingGroups.isGroup("ROOT")).willReturn(false);
|
||||
this.client.post().uri("/actuator/loggers/ROOT")
|
||||
.contentType(MediaType.parseMediaType(ActuatorMediaType.V2_JSON)).body(Collections.emptyMap())
|
||||
.exchange().expectStatus().isNoContent();
|
||||
verify(this.loggingSystem).setLogLevel("ROOT", null);
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void setLoggerGroupWithNullLogLevel() {
|
||||
given(this.loggingGroups.isGroup("test")).willReturn(true);
|
||||
given(this.loggingGroups.getLoggerGroup("test")).willReturn(Arrays.asList("test.member1", "test.member2"));
|
||||
this.client.post().uri("/actuator/loggers/test")
|
||||
.contentType(MediaType.parseMediaType(ActuatorMediaType.V2_JSON))
|
||||
.body(Collections.singletonMap("configuredLevel", null)).exchange().expectStatus().isNoContent();
|
||||
verify(this.loggingGroups).setLoggerGroupLevel("test", null);
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void setLoggerGroupWithNoLogLevel() {
|
||||
given(this.loggingGroups.isGroup("test")).willReturn(true);
|
||||
given(this.loggingGroups.getLoggerGroup("test")).willReturn(Arrays.asList("test.member1", "test.member2"));
|
||||
this.client.post().uri("/actuator/loggers/test")
|
||||
.contentType(MediaType.parseMediaType(ActuatorMediaType.V2_JSON)).body(Collections.emptyMap())
|
||||
.exchange().expectStatus().isNoContent();
|
||||
verify(this.loggingGroups).setLoggerGroupLevel("test", null);
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void logLevelForLoggerWithNameThatCouldBeMistakenForAPathExtension() {
|
||||
given(this.loggingSystem.getLoggerConfiguration("com.png"))
|
||||
|
|
@ -139,6 +225,16 @@ class LoggersEndpointWebIntegrationTests {
|
|||
.jsonPath("effectiveLevel").isEqualTo("DEBUG");
|
||||
}
|
||||
|
||||
@WebEndpointTest
|
||||
void logLevelForLoggerGroupWithNameThatCouldBeMistakenForAPathExtension() {
|
||||
given(this.loggingGroups.isGroup("com.png")).willReturn(true);
|
||||
given(this.loggingGroups.getLoggerGroupConfiguredLevel("com.png")).willReturn(LogLevel.DEBUG);
|
||||
given(this.loggingGroups.getLoggerGroup("com.png")).willReturn(Arrays.asList("test.member1", "test.member2"));
|
||||
this.client.get().uri("/actuator/loggers/com.png").exchange().expectStatus().isOk().expectBody()
|
||||
.jsonPath("$.length()").isEqualTo(2).jsonPath("configuredLevel").isEqualTo("DEBUG").jsonPath("members")
|
||||
.value(IsIterableContainingInAnyOrder.containsInAnyOrder("test.member1", "test.member2"));
|
||||
}
|
||||
|
||||
private JSONArray jsonArrayOf(Object... entries) {
|
||||
JSONArray array = new JSONArray();
|
||||
array.addAll(Arrays.asList(entries));
|
||||
|
|
@ -154,8 +250,19 @@ class LoggersEndpointWebIntegrationTests {
|
|||
}
|
||||
|
||||
@Bean
|
||||
LoggersEndpoint endpoint(LoggingSystem loggingSystem) {
|
||||
return new LoggersEndpoint(loggingSystem);
|
||||
ObjectProvider<LoggingGroups> loggingGroupsObjectProvider() {
|
||||
return mock(ObjectProvider.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
LoggingGroups loggingGroups() {
|
||||
return mock(LoggingGroups.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
LoggersEndpoint endpoint(LoggingSystem loggingSystem,
|
||||
ObjectProvider<LoggingGroups> loggingGroupsObjectProvider) {
|
||||
return new LoggersEndpoint(loggingSystem, loggingGroupsObjectProvider.getIfAvailable());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.springframework.boot.context.logging;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
|
@ -36,6 +37,7 @@ import org.springframework.boot.context.properties.bind.Binder;
|
|||
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
|
||||
import org.springframework.boot.logging.LogFile;
|
||||
import org.springframework.boot.logging.LogLevel;
|
||||
import org.springframework.boot.logging.LoggingGroups;
|
||||
import org.springframework.boot.logging.LoggingInitializationContext;
|
||||
import org.springframework.boot.logging.LoggingSystem;
|
||||
import org.springframework.boot.logging.LoggingSystemProperties;
|
||||
|
|
@ -126,6 +128,11 @@ public class LoggingApplicationListener implements GenericApplicationListener {
|
|||
*/
|
||||
public static final String LOGFILE_BEAN_NAME = "springBootLogFile";
|
||||
|
||||
/**
|
||||
* The name of the{@link LoggingGroups} bean.
|
||||
*/
|
||||
public static final String LOGGING_GROUPS_BEAN_NAME = "springBootLoggingGroups";
|
||||
|
||||
private static final Map<String, List<String>> DEFAULT_GROUP_LOGGERS;
|
||||
static {
|
||||
MultiValueMap<String, String> loggers = new LinkedMultiValueMap<>();
|
||||
|
|
@ -166,6 +173,8 @@ public class LoggingApplicationListener implements GenericApplicationListener {
|
|||
|
||||
private LoggingSystem loggingSystem;
|
||||
|
||||
private LoggingGroups loggingGroups;
|
||||
|
||||
private LogFile logFile;
|
||||
|
||||
private int order = DEFAULT_ORDER;
|
||||
|
|
@ -235,6 +244,9 @@ public class LoggingApplicationListener implements GenericApplicationListener {
|
|||
if (this.logFile != null && !beanFactory.containsBean(LOGFILE_BEAN_NAME)) {
|
||||
beanFactory.registerSingleton(LOGFILE_BEAN_NAME, this.logFile);
|
||||
}
|
||||
if (this.loggingGroups != null && !beanFactory.containsBean(LOGGING_GROUPS_BEAN_NAME)) {
|
||||
beanFactory.registerSingleton(LOGGING_GROUPS_BEAN_NAME, this.loggingGroups);
|
||||
}
|
||||
}
|
||||
|
||||
private void onContextClosedEvent() {
|
||||
|
|
@ -257,6 +269,7 @@ public class LoggingApplicationListener implements GenericApplicationListener {
|
|||
*/
|
||||
protected void initialize(ConfigurableEnvironment environment, ClassLoader classLoader) {
|
||||
new LoggingSystemProperties(environment).apply();
|
||||
this.loggingGroups = new LoggingGroups(this.loggingSystem);
|
||||
this.logFile = LogFile.get(environment);
|
||||
if (this.logFile != null) {
|
||||
this.logFile.applyToSystemProperties();
|
||||
|
|
@ -325,7 +338,8 @@ public class LoggingApplicationListener implements GenericApplicationListener {
|
|||
system.setLogLevel(logger, level);
|
||||
return;
|
||||
}
|
||||
groupLoggers.forEach((groupLogger) -> system.setLogLevel(groupLogger, level));
|
||||
this.loggingGroups.setLoggerGroup(logger, groupLoggers);
|
||||
this.loggingGroups.setLoggerGroupLevel(logger, level);
|
||||
}
|
||||
|
||||
protected void setLogLevels(LoggingSystem system, Environment environment) {
|
||||
|
|
@ -342,7 +356,7 @@ public class LoggingApplicationListener implements GenericApplicationListener {
|
|||
setLogLevel(system, name, level);
|
||||
}
|
||||
else {
|
||||
setLogLevel(system, groupedNames, level);
|
||||
setLogLevel(groupedNames, level, name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -353,9 +367,13 @@ public class LoggingApplicationListener implements GenericApplicationListener {
|
|||
return groups;
|
||||
}
|
||||
|
||||
private void setLogLevel(LoggingSystem system, String[] names, LogLevel level) {
|
||||
for (String name : names) {
|
||||
setLogLevel(system, name, level);
|
||||
private void setLogLevel(String[] names, LogLevel level, String groupName) {
|
||||
try {
|
||||
this.loggingGroups.setLoggerGroup(groupName, Arrays.asList(names));
|
||||
this.loggingGroups.setLoggerGroupLevel(groupName, level);
|
||||
}
|
||||
catch (RuntimeException ex) {
|
||||
this.logger.error("Cannot set level '" + level + "' for '" + groupName + "'");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.logging;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Manage logger groups.
|
||||
*
|
||||
* @author HaiTao Zhang
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class LoggingGroups {
|
||||
|
||||
private Map<String, LogLevel> loggerGroupConfigurations;
|
||||
|
||||
private Map<String, List<String>> loggerGroups;
|
||||
|
||||
private LoggingSystem loggingSystem;
|
||||
|
||||
public LoggingGroups(LoggingSystem loggingSystem) {
|
||||
this.loggerGroupConfigurations = new ConcurrentHashMap<>();
|
||||
this.loggerGroups = new ConcurrentHashMap<>();
|
||||
this.loggingSystem = loggingSystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a name to a list of logger's name to create a logger group.
|
||||
* @param groupName name of the logger group
|
||||
* @param members list of the members names
|
||||
*/
|
||||
public void setLoggerGroup(String groupName, List<String> members) {
|
||||
Assert.notNull(groupName, "Group name can not be null");
|
||||
Assert.notNull(members, "Members can not be null");
|
||||
this.loggerGroups.put(groupName, members);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the logging level for a given logger group.
|
||||
* @param groupName the name of the group to set
|
||||
* @param level the log level ({@code null}) can be used to remove any custom level
|
||||
* for the logger group and use the default configuration instead.
|
||||
*/
|
||||
public void setLoggerGroupLevel(String groupName, LogLevel level) {
|
||||
Assert.notNull(groupName, "Group name can not be null");
|
||||
List<String> members = this.loggerGroups.get(groupName);
|
||||
members.forEach((member) -> this.loggingSystem
|
||||
.setLogLevel(member.equalsIgnoreCase(LoggingSystem.ROOT_LOGGER_NAME) ? null : member, level));
|
||||
this.loggerGroupConfigurations.put(groupName, level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a groupName is associated to a logger group.
|
||||
* @param groupName name of the logger group
|
||||
* @return a boolean stating true when groupName is associated with a group of loggers
|
||||
*/
|
||||
public boolean isGroup(String groupName) {
|
||||
Assert.notNull(groupName, "Group name can not be null");
|
||||
return this.loggerGroups.containsKey(groupName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the all registered logger groups.
|
||||
* @return a Set of the names of the logger groups
|
||||
*/
|
||||
public Set<String> getLoggerGroupNames() {
|
||||
synchronized (this) {
|
||||
return this.loggerGroups.isEmpty() ? null : Collections.unmodifiableSet(this.loggerGroups.keySet());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a logger group's members.
|
||||
* @param groupName name of the logger group
|
||||
* @return list of the members names associated with this group
|
||||
*/
|
||||
public List<String> getLoggerGroup(String groupName) {
|
||||
Assert.notNull(groupName, "Group name can not be null");
|
||||
return Collections.unmodifiableList(this.loggerGroups.get(groupName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a logger group's configured level.
|
||||
* @param groupName name of the logger group
|
||||
* @return the logger groups configured level
|
||||
*/
|
||||
public LogLevel getLoggerGroupConfiguredLevel(String groupName) {
|
||||
Assert.notNull(groupName, "Group name can not be null");
|
||||
return this.loggerGroupConfigurations.get(groupName);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.logging;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link LoggingGroups}
|
||||
*
|
||||
* @author HaiTao Zhang
|
||||
*/
|
||||
public class LoggingGroupsTests {
|
||||
|
||||
private LoggingSystem loggingSystem = mock(LoggingSystem.class);
|
||||
|
||||
@Test
|
||||
void setLoggerGroupWithTheConfiguredLevelToAllMembers() {
|
||||
LoggingGroups loggingGroups = new LoggingGroups(this.loggingSystem);
|
||||
loggingGroups.setLoggerGroup("test", Arrays.asList("test.member", "test.member2"));
|
||||
loggingGroups.setLoggerGroupLevel("test", LogLevel.DEBUG);
|
||||
verify(this.loggingSystem).setLogLevel("test.member2", LogLevel.DEBUG);
|
||||
verify(this.loggingSystem).setLogLevel("test.member", LogLevel.DEBUG);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue