Spring-Boot: v2.3.5.RELEASE Log4J2: 2.13.3 (spring-managed)
Display default configuration
$ curl http://$SERVER/actuator/loggers
json {"levels":["OFF","FATAL","ERROR","WARN","INFO","DEBUG","TRACE"],"loggers":{ "ROOT":{"configuredLevel":null,"effectiveLevel":"WARN"}, "de":{"configuredLevel":null, "effectiveLevel":"WARN"},
Configure
de
Log Level$ curl http://$SERVER/actuator/loggers/de -d '{"configuredLevel":"info"}' -H "Content-Type: application/json" $ curl http://$SERVER/actuator/loggers
json {"levels":["OFF","FATAL","ERROR","WARN","INFO","DEBUG","TRACE"],"loggers":{ "ROOT":{"configuredLevel":null,"effectiveLevel":"WARN"}, "de":{"configuredLevel":"INFO","effectiveLevel":"INFO"},
Reset/inherit
de
Log Level$ curl http://$SERVER/actuator/loggers/de -d '{"configuredLevel":null}' -H "Content-Type: application/json" $ curl http://$SERVER/actuator/loggers
json {"levels":["OFF","FATAL","ERROR","WARN","INFO","DEBUG","TRACE"],"loggers":{ "ROOT":{"configuredLevel":null,"effectiveLevel":"WARN"}, "de":{"configuredLevel":"WARN", "effectiveLevel":"WARN"},
Configure
ROOT
Log Level$ curl http://$SERVER/actuator/loggers/ROOT -d '{"configuredLevel":"error"}' -H "Content-Type: application/json" $ curl http://$SERVER/actuator/loggers
json {"levels":["OFF","FATAL","ERROR","WARN","INFO","DEBUG","TRACE"],"loggers":{ "ROOT":{"configuredLevel":null,"effectiveLevel":"ERROR"}, "de":{"configuredLevel":"ERROR", "effectiveLevel":"ERROR"},
As you can see the last two jsons display de
as configured, but the value (even for the configured flag) is inherited from ROOT
.
Comment From: snicoll
@ST-DDT thanks for the report. FTR, there is no need to specify a null
configuredLevel according to the documentation.
That's not a problem with the actuator as it merely get that information from the LoggingSystem
. When we reset the log level that doesn't remove the logging config but rather makes sure that the existing logging config inherits from its parent. Logback does not have the same behaviour so we need to investigate if we can request log4j to remove the logging config.
Comment From: snicoll
The problem can be reproduced by the following test:
@Test
void getLoggingConfigurationWithResetLevelShouldReturnLoggerWithNullConfiguredLevel() {
this.loggingSystem.beforeInitialize();
this.loggingSystem.initialize(null, null, null);
this.loggingSystem.setLogLevel("com.example", LogLevel.WARN);
this.loggingSystem.setLogLevel("com.example.test", LogLevel.DEBUG);
LoggerConfiguration configuration = this.loggingSystem.getLoggerConfiguration("com.example.test");
assertThat(configuration).isEqualTo(new LoggerConfiguration("com.example.test", LogLevel.DEBUG, LogLevel.DEBUG));
this.loggingSystem.setLogLevel("com.example.test", null);
LoggerConfiguration updatedConfiguration = this.loggingSystem.getLoggerConfiguration("com.example.test");
assertThat(updatedConfiguration).isEqualTo(new LoggerConfiguration("com.example.test", null, LogLevel.WARN));
}
Comment From: mbhave
Log4J2 LoggerConfig
, returns the parent's log level if the log level for that logger is null
. I'm not sure how we can tell if the logLevel
itself is null
without reflection.
Comment From: philwebb
I've had a go at fixing this one in https://github.com/philwebb/spring-boot/tree/gh-24298. The commit message describes the idea behind the fix.
I'm not confident enough to merge it without a review.
Comment From: snicoll
I did review that commit back then and I seem to remember that LevelSetLoggerConfig
could be a problem if AsyncLoggerConfig
is used. Reading the commit again, I am not so sure anymore. Or maybe it was for a different issue?