Allow to reset a log level
This commit ensures that `setLogLevel` on the `LoggingSystem` accepts a `null` level. A `null` level means any customization sets on that level should be removed and the default configuration should be used instead. Effectively, the level of the parent logger is going to be used when `setLevel` is called with `null` for a given logger. Most JMX clients do not accept to pass `null` for an argument so an empty String is translated to null in that specific case. Closes gh-8776
This commit is contained in:
parent
bdf2b2e810
commit
605dee4700
|
|
@ -24,12 +24,15 @@ import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
|
|||
import org.springframework.boot.logging.LogLevel;
|
||||
import org.springframework.jmx.export.annotation.ManagedAttribute;
|
||||
import org.springframework.jmx.export.annotation.ManagedOperation;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.jmx.export.annotation.ManagedOperationParameter;
|
||||
import org.springframework.jmx.export.annotation.ManagedOperationParameters;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Adapter to expose {@link LoggersEndpoint} as an {@link MvcEndpoint}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class LoggersEndpointMBean extends EndpointMBean {
|
||||
|
|
@ -45,15 +48,25 @@ public class LoggersEndpointMBean extends EndpointMBean {
|
|||
}
|
||||
|
||||
@ManagedOperation(description = "Get log level for a given logger")
|
||||
@ManagedOperationParameters({
|
||||
@ManagedOperationParameter(name = "loggerName", description = "Name of the logger") })
|
||||
public Object getLogger(String loggerName) {
|
||||
return convert(getEndpoint().invoke(loggerName));
|
||||
}
|
||||
|
||||
@ManagedOperation(description = "Set log level for a given logger")
|
||||
@ManagedOperationParameters({
|
||||
@ManagedOperationParameter(name = "loggerName", description = "Name of the logger"),
|
||||
@ManagedOperationParameter(name = "logLevel", description = "New log level (can be null or empty String to remove the custom level)") })
|
||||
public void setLogLevel(String loggerName, String logLevel) {
|
||||
Assert.notNull(logLevel, "LogLevel must not be null");
|
||||
LogLevel level = LogLevel.valueOf(logLevel.toUpperCase());
|
||||
getEndpoint().setLogLevel(loggerName, level);
|
||||
getEndpoint().setLogLevel(loggerName, determineLogLevel(logLevel));
|
||||
}
|
||||
|
||||
private LogLevel determineLogLevel(String logLevel) {
|
||||
if (StringUtils.hasText(logLevel)) {
|
||||
return LogLevel.valueOf(logLevel.toUpperCase());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -80,6 +80,12 @@ public class LoggersEndpointTests extends AbstractEndpointTests<LoggersEndpoint>
|
|||
verify(getLoggingSystem()).setLogLevel("ROOT", LogLevel.DEBUG);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setLogLevelToNull() {
|
||||
getEndpointBean().setLogLevel("ROOT", null);
|
||||
verify(getLoggingSystem()).setLogLevel("ROOT", null);
|
||||
}
|
||||
|
||||
private LoggingSystem getLoggingSystem() {
|
||||
return this.context.getBean(LoggingSystem.class);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||
* @author Ben Hale
|
||||
* @author Phillip Webb
|
||||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
|
|
@ -181,6 +182,22 @@ public class LoggersMvcEndpointTests {
|
|||
verifyZeroInteractions(this.loggingSystem);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setLoggerWithNullLogLevel() throws Exception {
|
||||
this.mvc.perform(post(PATH + "/ROOT").contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{\"configuredLevel\": null}"))
|
||||
.andExpect(status().isNoContent());
|
||||
verify(this.loggingSystem).setLogLevel("ROOT", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setLoggerWithNoLogLevel() throws Exception {
|
||||
this.mvc.perform(post(PATH + "/ROOT").contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{}"))
|
||||
.andExpect(status().isNoContent());
|
||||
verify(this.loggingSystem).setLogLevel("ROOT", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logLevelForLoggerWithNameThatCouldBeMistakenForAPathExtension()
|
||||
throws Exception {
|
||||
|
|
|
|||
|
|
@ -927,6 +927,9 @@ In order to configure a given logger, you `POST` a partial entity to the resourc
|
|||
}
|
||||
----
|
||||
|
||||
TIP: You can also pass a `null` `configuredLevel` to "reset" the specific level of the
|
||||
logger (and use the default configuration instead).
|
||||
|
||||
|
||||
|
||||
[[production-ready-metrics]]
|
||||
|
|
|
|||
|
|
@ -116,7 +116,8 @@ public abstract class LoggingSystem {
|
|||
* Sets the logging level for a given logger.
|
||||
* @param loggerName the name of the logger to set ({@code null} can be used for the
|
||||
* root logger).
|
||||
* @param level the log level
|
||||
* @param level the log level ({@code null} can be used to remove any custom level
|
||||
* for the logger and use the default configuration instead)
|
||||
*/
|
||||
public void setLogLevel(String loggerName, LogLevel level) {
|
||||
throw new UnsupportedOperationException("Unable to set log level");
|
||||
|
|
|
|||
|
|
@ -117,7 +117,6 @@ public class JavaLoggingSystem extends AbstractLoggingSystem {
|
|||
|
||||
@Override
|
||||
public void setLogLevel(String loggerName, LogLevel level) {
|
||||
Assert.notNull(level, "Level must not be null");
|
||||
if (loggerName == null || ROOT_LOGGER_NAME.equals(loggerName)) {
|
||||
loggerName = "";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -168,6 +168,19 @@ public class JavaLoggingSystemTests extends AbstractLoggingSystemTests {
|
|||
.isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setLevelToNull() throws Exception {
|
||||
this.loggingSystem.beforeInitialize();
|
||||
this.loggingSystem.initialize(null, null, null);
|
||||
this.logger.fine("Hello");
|
||||
this.loggingSystem.setLogLevel("org.springframework.boot", LogLevel.DEBUG);
|
||||
this.logger.fine("Hello");
|
||||
this.loggingSystem.setLogLevel("org.springframework.boot", null);
|
||||
this.logger.fine("Hello");
|
||||
assertThat(StringUtils.countOccurrencesOf(this.output.toString(), "Hello"))
|
||||
.isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLoggingConfigurations() throws Exception {
|
||||
this.loggingSystem.beforeInitialize();
|
||||
|
|
|
|||
|
|
@ -141,6 +141,19 @@ public class Log4J2LoggingSystemTests extends AbstractLoggingSystemTests {
|
|||
.isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setLevelToNull() throws Exception {
|
||||
this.loggingSystem.beforeInitialize();
|
||||
this.loggingSystem.initialize(null, null, null);
|
||||
this.logger.debug("Hello");
|
||||
this.loggingSystem.setLogLevel("org.springframework.boot", LogLevel.DEBUG);
|
||||
this.logger.debug("Hello");
|
||||
this.loggingSystem.setLogLevel("org.springframework.boot", null);
|
||||
this.logger.debug("Hello");
|
||||
assertThat(StringUtils.countOccurrencesOf(this.output.toString(), "Hello"))
|
||||
.isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLoggingConfigurations() throws Exception {
|
||||
this.loggingSystem.beforeInitialize();
|
||||
|
|
|
|||
|
|
@ -184,6 +184,19 @@ public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
|||
.isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setLevelToNull() throws Exception {
|
||||
this.loggingSystem.beforeInitialize();
|
||||
this.loggingSystem.initialize(this.initializationContext, null, null);
|
||||
this.logger.debug("Hello");
|
||||
this.loggingSystem.setLogLevel("org.springframework.boot", LogLevel.DEBUG);
|
||||
this.logger.debug("Hello");
|
||||
this.loggingSystem.setLogLevel("org.springframework.boot", null);
|
||||
this.logger.debug("Hello");
|
||||
assertThat(StringUtils.countOccurrencesOf(this.output.toString(), "Hello"))
|
||||
.isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLoggingConfigurations() throws Exception {
|
||||
this.loggingSystem.beforeInitialize();
|
||||
|
|
|
|||
Loading…
Reference in New Issue