Skip to content

Commit f7fa180

Browse files
committed
Added LoggingGroups
1 parent ebe2f52 commit f7fa180

File tree

12 files changed

+305
-204
lines changed

12 files changed

+305
-204
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/logging/LoggersEndpointAutoConfiguration.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
2525
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2626
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
27+
import org.springframework.boot.logging.LoggingGroups;
2728
import org.springframework.boot.logging.LoggingSystem;
2829
import org.springframework.context.annotation.Bean;
2930
import org.springframework.context.annotation.ConditionContext;
@@ -45,8 +46,8 @@ public class LoggersEndpointAutoConfiguration {
4546
@ConditionalOnBean(LoggingSystem.class)
4647
@Conditional(OnEnabledLoggingSystemCondition.class)
4748
@ConditionalOnMissingBean
48-
public LoggersEndpoint loggersEndpoint(LoggingSystem loggingSystem) {
49-
return new LoggersEndpoint(loggingSystem);
49+
public LoggersEndpoint loggersEndpoint(LoggingSystem loggingSystem, LoggingGroups loggingGroups) {
50+
return new LoggersEndpoint(loggingSystem, loggingGroups);
5051
}
5152

5253
static class OnEnabledLoggingSystemCondition extends SpringBootCondition {

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/LoggersEndpointDocumentationTests.java

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation;
1818

1919
import java.util.Arrays;
20+
import java.util.Collections;
2021
import java.util.EnumSet;
2122
import java.util.List;
2223

@@ -25,6 +26,7 @@
2526
import org.springframework.boot.actuate.logging.LoggersEndpoint;
2627
import org.springframework.boot.logging.LogLevel;
2728
import org.springframework.boot.logging.LoggerConfiguration;
29+
import org.springframework.boot.logging.LoggingGroups;
2830
import org.springframework.boot.logging.LoggingSystem;
2931
import org.springframework.boot.test.mock.mockito.MockBean;
3032
import org.springframework.context.annotation.Bean;
@@ -54,20 +56,32 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
5456
fieldWithPath("configuredLevel").description("Configured level of the logger, if any.").optional(),
5557
fieldWithPath("effectiveLevel").description("Effective level of the logger."));
5658

59+
private static final List<FieldDescriptor> groupLevelFields = Arrays.asList(
60+
fieldWithPath("configuredLevel").description("Configured level of the logger group"),
61+
fieldWithPath("members").description("Loggers that are part of this group").optional());
62+
5763
@MockBean
5864
private LoggingSystem loggingSystem;
5965

66+
@MockBean
67+
private LoggingGroups loggingGroups;
68+
6069
@Test
6170
void allLoggers() throws Exception {
6271
given(this.loggingSystem.getSupportedLogLevels()).willReturn(EnumSet.allOf(LogLevel.class));
6372
given(this.loggingSystem.getLoggerConfigurations())
6473
.willReturn(Arrays.asList(new LoggerConfiguration("ROOT", LogLevel.INFO, LogLevel.INFO),
6574
new LoggerConfiguration("com.example", LogLevel.DEBUG, LogLevel.DEBUG)));
75+
given(this.loggingGroups.getLoggerGroupNames()).willReturn(Collections.singleton("test"));
76+
given(this.loggingGroups.getLoggerGroup("test")).willReturn(Arrays.asList("test.member"));
77+
given(this.loggingGroups.getLoggerGroupConfiguredLevel("test")).willReturn(LogLevel.INFO);
6678
this.mockMvc.perform(get("/actuator/loggers")).andExpect(status().isOk())
6779
.andDo(MockMvcRestDocumentation.document("loggers/all",
6880
responseFields(fieldWithPath("levels").description("Levels support by the logging system."),
69-
fieldWithPath("loggers").description("Loggers keyed by name."))
70-
.andWithPrefix("loggers.*.", levelFields)));
81+
fieldWithPath("loggers").description("Loggers keyed by name."),
82+
fieldWithPath("groups").description("Logger groups keyed by name"))
83+
.andWithPrefix("loggers.*.", levelFields)
84+
.andWithPrefix("groups.*.", groupLevelFields)));
7185
}
7286

7387
@Test
@@ -78,6 +92,15 @@ void logger() throws Exception {
7892
.andDo(MockMvcRestDocumentation.document("loggers/single", responseFields(levelFields)));
7993
}
8094

95+
@Test
96+
void loggerGroups() throws Exception {
97+
given(this.loggingGroups.isGroup("com.example")).willReturn(true);
98+
given(this.loggingGroups.getLoggerGroup("com.example")).willReturn(Arrays.asList("com.member", "com.member2"));
99+
given(this.loggingGroups.getLoggerGroupConfiguredLevel("com.example")).willReturn(LogLevel.INFO);
100+
this.mockMvc.perform(get("/actuator/loggers/com.example")).andExpect(status().isOk())
101+
.andDo(MockMvcRestDocumentation.document("loggers/group", responseFields(groupLevelFields)));
102+
}
103+
81104
@Test
82105
void setLogLevel() throws Exception {
83106
this.mockMvc
@@ -89,6 +112,20 @@ void setLogLevel() throws Exception {
89112
verify(this.loggingSystem).setLogLevel("com.example", LogLevel.DEBUG);
90113
}
91114

115+
@Test
116+
void setLogLevelOfLoggerGroup() throws Exception {
117+
given(this.loggingGroups.isGroup("com.example")).willReturn(true);
118+
this.mockMvc
119+
.perform(post("/actuator/loggers/com.example")
120+
.content("{\"configuredLevel\":\"debug\"}").contentType(MediaType.APPLICATION_JSON))
121+
.andExpect(status().isNoContent()).andDo(
122+
MockMvcRestDocumentation.document("loggers/setGroup",
123+
requestFields(fieldWithPath("configuredLevel").description(
124+
"Level for the logger group. May be omitted to clear the level of the loggers.")
125+
.optional())));
126+
verify(this.loggingGroups).setLoggerGroupLevel("com.example", LogLevel.DEBUG);
127+
}
128+
92129
@Test
93130
void clearLogLevel() throws Exception {
94131
this.mockMvc
@@ -102,8 +139,8 @@ void clearLogLevel() throws Exception {
102139
static class TestConfiguration {
103140

104141
@Bean
105-
LoggersEndpoint endpoint(LoggingSystem loggingSystem) {
106-
return new LoggersEndpoint(loggingSystem);
142+
LoggersEndpoint endpoint(LoggingSystem loggingSystem, LoggingGroups loggingGroups) {
143+
return new LoggersEndpoint(loggingSystem, loggingGroups);
107144
}
108145

109146
}

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/logging/LoggersEndpoint.java

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
3232
import org.springframework.boot.logging.LogLevel;
3333
import org.springframework.boot.logging.LoggerConfiguration;
34+
import org.springframework.boot.logging.LoggingGroups;
3435
import org.springframework.boot.logging.LoggingSystem;
3536
import org.springframework.lang.Nullable;
3637
import org.springframework.util.Assert;
@@ -40,26 +41,31 @@
4041
*
4142
* @author Ben Hale
4243
* @author Phillip Webb
44+
* @author HaiTao Zhang
4345
* @since 2.0.0
4446
*/
4547
@Endpoint(id = "loggers")
4648
public class LoggersEndpoint {
4749

4850
private final LoggingSystem loggingSystem;
4951

52+
private final LoggingGroups loggingGroups;
53+
5054
/**
5155
* Create a new {@link LoggersEndpoint} instance.
5256
* @param loggingSystem the logging system to expose
57+
* @param loggingGroups the logging groups to expose
5358
*/
54-
public LoggersEndpoint(LoggingSystem loggingSystem) {
59+
public LoggersEndpoint(LoggingSystem loggingSystem, LoggingGroups loggingGroups) {
5560
Assert.notNull(loggingSystem, "LoggingSystem must not be null");
5661
this.loggingSystem = loggingSystem;
62+
this.loggingGroups = loggingGroups;
5763
}
5864

5965
@ReadOperation
6066
public Map<String, Object> loggers() {
6167
Collection<LoggerConfiguration> configurations = this.loggingSystem.getLoggerConfigurations();
62-
Set<String> groups = this.loggingSystem.getLoggerGroupNames();
68+
Set<String> groups = this.loggingGroups.getLoggerGroupNames();
6369
if (configurations == null) {
6470
return Collections.emptyMap();
6571
}
@@ -75,10 +81,10 @@ public Map<String, Object> loggers() {
7581
@ReadOperation
7682
public LoggerLevels loggerLevels(@Selector String name) {
7783
Assert.notNull(name, "Name must not be null");
78-
LogLevel groupConfiguredLevel = this.loggingSystem.getLoggerGroupConfiguredLevel(name);
79-
if (groupConfiguredLevel != null) {
80-
List<String> members = this.loggingSystem.getLoggerGroup(name);
81-
return (groupConfiguredLevel != null) ? new GroupLoggerLevels(groupConfiguredLevel, members) : null;
84+
if (this.loggingGroups.isGroup(name)) {
85+
List<String> members = this.loggingGroups.getLoggerGroup(name);
86+
LogLevel groupConfiguredLevel = this.loggingGroups.getLoggerGroupConfiguredLevel(name);
87+
return new GroupLoggerLevels(groupConfiguredLevel, members);
8288
}
8389
LoggerConfiguration configuration = this.loggingSystem.getLoggerConfiguration(name);
8490
return (configuration != null) ? new SingleLoggerLevels(configuration) : null;
@@ -87,9 +93,8 @@ public LoggerLevels loggerLevels(@Selector String name) {
8793
@WriteOperation
8894
public void configureLogLevel(@Selector String name, @Nullable LogLevel configuredLevel) {
8995
Assert.notNull(name, "Name must not be empty");
90-
Set<String> loggerGroups = this.loggingSystem.getLoggerGroupNames();
91-
if (loggerGroups.contains(name)) {
92-
this.loggingSystem.setLoggerGroupLevel(name, configuredLevel);
96+
if (this.loggingGroups.isGroup(name)) {
97+
this.loggingGroups.setLoggerGroupLevel(name, configuredLevel);
9398
return;
9499
}
95100
this.loggingSystem.setLogLevel(name, configuredLevel);
@@ -111,8 +116,8 @@ private Map<String, LoggerLevels> getLoggers(Collection<LoggerConfiguration> con
111116
private Map<String, LoggerLevels> getLoggerGroups(Set<String> groups) {
112117
Map<String, LoggerLevels> loggerGroups = new LinkedHashMap<>(groups.size());
113118
for (String name : groups) {
114-
List<String> members = this.loggingSystem.getLoggerGroup(name);
115-
LogLevel groupConfiguredLevel = this.loggingSystem.getLoggerGroupConfiguredLevel(name);
119+
List<String> members = this.loggingGroups.getLoggerGroup(name);
120+
LogLevel groupConfiguredLevel = this.loggingGroups.getLoggerGroupConfiguredLevel(name);
116121
loggerGroups.put(name, new GroupLoggerLevels(groupConfiguredLevel, members));
117122
}
118123
return loggerGroups;

spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/logging/LoggersEndpointTests.java

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.boot.actuate.logging.LoggersEndpoint.SingleLoggerLevels;
2929
import org.springframework.boot.logging.LogLevel;
3030
import org.springframework.boot.logging.LoggerConfiguration;
31+
import org.springframework.boot.logging.LoggingGroups;
3132
import org.springframework.boot.logging.LoggingSystem;
3233

3334
import static org.assertj.core.api.Assertions.assertThat;
@@ -40,19 +41,22 @@
4041
*
4142
* @author Ben Hale
4243
* @author Andy Wilkinson
44+
* @author HaiTao Zhang
4345
*/
4446
class LoggersEndpointTests {
4547

4648
private final LoggingSystem loggingSystem = mock(LoggingSystem.class);
4749

50+
private final LoggingGroups loggingGroups = mock(LoggingGroups.class);
51+
4852
@Test
4953
@SuppressWarnings("unchecked")
5054
void loggersShouldReturnLoggerConfigurationsWithNoLoggerGroups() {
5155
given(this.loggingSystem.getLoggerConfigurations())
5256
.willReturn(Collections.singletonList(new LoggerConfiguration("ROOT", null, LogLevel.DEBUG)));
5357
given(this.loggingSystem.getSupportedLogLevels()).willReturn(EnumSet.allOf(LogLevel.class));
54-
given(this.loggingSystem.getLoggerGroupNames()).willReturn(null);
55-
Map<String, Object> result = new LoggersEndpoint(this.loggingSystem).loggers();
58+
given(this.loggingGroups.getLoggerGroupNames()).willReturn(null);
59+
Map<String, Object> result = new LoggersEndpoint(this.loggingSystem, this.loggingGroups).loggers();
5660
Map<String, LoggerLevels> loggers = (Map<String, LoggerLevels>) result.get("loggers");
5761
Set<LogLevel> levels = (Set<LogLevel>) result.get("levels");
5862
SingleLoggerLevels rootLevels = (SingleLoggerLevels) loggers.get("ROOT");
@@ -69,10 +73,10 @@ void loggersShouldReturnLoggerConfigurationsWithLoggerGroups() {
6973
given(this.loggingSystem.getLoggerConfigurations())
7074
.willReturn(Collections.singletonList(new LoggerConfiguration("ROOT", null, LogLevel.DEBUG)));
7175
given(this.loggingSystem.getSupportedLogLevels()).willReturn(EnumSet.allOf(LogLevel.class));
72-
given(this.loggingSystem.getLoggerGroup("test")).willReturn(Collections.singletonList("test.member"));
73-
given(this.loggingSystem.getLoggerGroupNames()).willReturn(Collections.singleton("test"));
74-
given(this.loggingSystem.getLoggerGroupConfiguredLevel("test")).willReturn(LogLevel.DEBUG);
75-
Map<String, Object> result = new LoggersEndpoint(this.loggingSystem).loggers();
76+
given(this.loggingGroups.getLoggerGroup("test")).willReturn(Collections.singletonList("test.member"));
77+
given(this.loggingGroups.getLoggerGroupNames()).willReturn(Collections.singleton("test"));
78+
given(this.loggingGroups.getLoggerGroupConfiguredLevel("test")).willReturn(LogLevel.DEBUG);
79+
Map<String, Object> result = new LoggersEndpoint(this.loggingSystem, this.loggingGroups).loggers();
7680
Map<String, LoggerLevels> loggerGroups = (Map<String, LoggerLevels>) result.get("groups");
7781
GroupLoggerLevels testLoggerLevel = (GroupLoggerLevels) loggerGroups.get("test");
7882
Map<String, LoggerLevels> loggers = (Map<String, LoggerLevels>) result.get("loggers");
@@ -90,48 +94,54 @@ void loggersShouldReturnLoggerConfigurationsWithLoggerGroups() {
9094

9195
@Test
9296
void loggerLevelsWhenNameSpecifiedShouldReturnLevels() {
97+
given(this.loggingGroups.isGroup("ROOT")).willReturn(false);
9398
given(this.loggingSystem.getLoggerConfiguration("ROOT"))
9499
.willReturn(new LoggerConfiguration("ROOT", null, LogLevel.DEBUG));
95-
SingleLoggerLevels levels = (SingleLoggerLevels) new LoggersEndpoint(this.loggingSystem).loggerLevels("ROOT");
100+
SingleLoggerLevels levels = (SingleLoggerLevels) new LoggersEndpoint(this.loggingSystem, this.loggingGroups)
101+
.loggerLevels("ROOT");
96102
assertThat(levels.getConfiguredLevel()).isNull();
97103
assertThat(levels.getEffectiveLevel()).isEqualTo("DEBUG");
98104
}
99105

100106
@Test
101107
void groupNameSpecifiedShouldReturnConfiguredLevelAndMembers() {
102-
given(this.loggingSystem.getLoggerGroup("test")).willReturn(Collections.singletonList("test.member"));
103-
given(this.loggingSystem.getLoggerGroupConfiguredLevel("test")).willReturn(LogLevel.DEBUG);
104-
GroupLoggerLevels levels = (GroupLoggerLevels) new LoggersEndpoint(this.loggingSystem).loggerLevels("test");
108+
given(this.loggingGroups.isGroup("test")).willReturn(true);
109+
given(this.loggingGroups.getLoggerGroup("test")).willReturn(Collections.singletonList("test.member"));
110+
given(this.loggingGroups.getLoggerGroupConfiguredLevel("test")).willReturn(LogLevel.DEBUG);
111+
GroupLoggerLevels levels = (GroupLoggerLevels) new LoggersEndpoint(this.loggingSystem, this.loggingGroups)
112+
.loggerLevels("test");
105113
assertThat(levels.getConfiguredLevel()).isEqualTo("DEBUG");
106114
assertThat(levels.getMembers()).isEqualTo(Collections.singletonList("test.member"));
107115
}
108116

109117
@Test
110118
void configureLogLevelShouldSetLevelOnLoggingSystem() {
111-
given(this.loggingSystem.getLoggerGroup("ROOT")).willReturn(null);
112-
new LoggersEndpoint(this.loggingSystem).configureLogLevel("ROOT", LogLevel.DEBUG);
119+
given(this.loggingGroups.getLoggerGroup("ROOT")).willReturn(null);
120+
new LoggersEndpoint(this.loggingSystem, this.loggingGroups).configureLogLevel("ROOT", LogLevel.DEBUG);
113121
verify(this.loggingSystem).setLogLevel("ROOT", LogLevel.DEBUG);
114122
}
115123

116124
@Test
117125
void configureLogLevelWithNullSetsLevelOnLoggingSystemToNull() {
118-
given(this.loggingSystem.getLoggerGroup("ROOT")).willReturn(null);
119-
new LoggersEndpoint(this.loggingSystem).configureLogLevel("ROOT", null);
126+
given(this.loggingGroups.getLoggerGroup("ROOT")).willReturn(null);
127+
new LoggersEndpoint(this.loggingSystem, this.loggingGroups).configureLogLevel("ROOT", null);
120128
verify(this.loggingSystem).setLogLevel("ROOT", null);
121129
}
122130

123131
@Test
124132
void configureLogLevelInLoggerGroupShouldSetLevelOnLoggingSystem() {
125-
given(this.loggingSystem.getLoggerGroup("test")).willReturn(Collections.singletonList("test.member"));
126-
new LoggersEndpoint(this.loggingSystem).configureLogLevel("test", LogLevel.DEBUG);
127-
verify(this.loggingSystem).setLoggerGroupLevel("test", LogLevel.DEBUG);
133+
given(this.loggingGroups.isGroup("test")).willReturn(true);
134+
given(this.loggingGroups.getLoggerGroup("test")).willReturn(Collections.singletonList("test.member"));
135+
new LoggersEndpoint(this.loggingSystem, this.loggingGroups).configureLogLevel("test", LogLevel.DEBUG);
136+
verify(this.loggingGroups).setLoggerGroupLevel("test", LogLevel.DEBUG);
128137
}
129138

130139
@Test
131140
void configureLogLevelWithNullInLoggerGroupShouldSetLevelOnLoggingSystem() {
132-
given(this.loggingSystem.getLoggerGroup("test")).willReturn(Collections.singletonList("test.member"));
133-
new LoggersEndpoint(this.loggingSystem).configureLogLevel("test", null);
134-
verify(this.loggingSystem).setLoggerGroupLevel("test", null);
141+
given(this.loggingGroups.isGroup("test")).willReturn(true);
142+
given(this.loggingGroups.getLoggerGroup("test")).willReturn(Collections.singletonList("test.member"));
143+
new LoggersEndpoint(this.loggingSystem, this.loggingGroups).configureLogLevel("test", null);
144+
verify(this.loggingGroups).setLoggerGroupLevel("test", null);
135145
}
136146

137147
// @Test

0 commit comments

Comments
 (0)