Register Logback StatusListener when using custom Logback file
Update `LogbackLoggingSystem` so that the `OnErrorConsoleStatusListener` is also registered when loading a custom Logback configuration file. See gh-43931 Signed-off-by: Dmytro Nosan <dimanosan@gmail.com>
This commit is contained in:
parent
b9f3d522cf
commit
258eb29978
@ -216,6 +216,7 @@ public class LogbackLoggingSystem extends AbstractLoggingSystem implements BeanF
|
||||
LoggerContext loggerContext = getLoggerContext();
|
||||
stopAndReset(loggerContext);
|
||||
withLoggingSuppressed(() -> putInitializationContextObjects(loggerContext, initializationContext));
|
||||
addOnErrorConsoleStatusListener(loggerContext);
|
||||
SpringBootJoranConfigurator configurator = new SpringBootJoranConfigurator(initializationContext);
|
||||
configurator.setContext(loggerContext);
|
||||
boolean configuredUsingAotGeneratedArtifacts = configurator.configureUsingAotGeneratedArtifacts();
|
||||
@ -261,6 +262,7 @@ public class LogbackLoggingSystem extends AbstractLoggingSystem implements BeanF
|
||||
if (initializationContext != null) {
|
||||
applySystemProperties(initializationContext.getEnvironment(), logFile);
|
||||
}
|
||||
addOnErrorConsoleStatusListener(loggerContext);
|
||||
try {
|
||||
Resource resource = ApplicationResourceLoader.get().getResource(location);
|
||||
configureByResourceUrl(initializationContext, loggerContext, resource.getURL());
|
||||
@ -493,7 +495,7 @@ public class LogbackLoggingSystem extends AbstractLoggingSystem implements BeanF
|
||||
|
||||
private void addOnErrorConsoleStatusListener(LoggerContext context) {
|
||||
FilteringStatusListener listener = new FilteringStatusListener(new OnErrorConsoleStatusListener(),
|
||||
Status.ERROR);
|
||||
Status.WARN);
|
||||
listener.setContext(context);
|
||||
if (context.getStatusManager().add(listener)) {
|
||||
listener.start();
|
||||
|
@ -43,7 +43,6 @@ import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy;
|
||||
import ch.qos.logback.core.status.OnConsoleStatusListener;
|
||||
import ch.qos.logback.core.status.OnErrorConsoleStatusListener;
|
||||
import ch.qos.logback.core.status.Status;
|
||||
import ch.qos.logback.core.status.StatusListener;
|
||||
import ch.qos.logback.core.util.DynamicClassLoadingException;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@ -656,10 +655,8 @@ class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
||||
.contains("SizeAndTimeBasedFileNamingAndTriggeringPolicy")
|
||||
.contains("DebugLogbackConfigurator");
|
||||
LoggerContext loggerContext = this.logger.getLoggerContext();
|
||||
List<StatusListener> statusListeners = loggerContext.getStatusManager().getCopyOfStatusListenerList();
|
||||
assertThat(statusListeners).hasSize(1);
|
||||
StatusListener statusListener = statusListeners.get(0);
|
||||
assertThat(statusListener).isInstanceOf(OnConsoleStatusListener.class);
|
||||
assertThat(loggerContext.getStatusManager().getCopyOfStatusListenerList())
|
||||
.allSatisfy((listener) -> assertThat(listener).isInstanceOf(OnConsoleStatusListener.class));
|
||||
}
|
||||
finally {
|
||||
System.clearProperty("logback.debug");
|
||||
@ -671,25 +668,35 @@ class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
||||
this.loggingSystem.beforeInitialize();
|
||||
initialize(this.initializationContext, null, getLogFile(tmpDir() + "/tmp.log", null));
|
||||
LoggerContext loggerContext = this.logger.getLoggerContext();
|
||||
List<StatusListener> statusListeners = loggerContext.getStatusManager().getCopyOfStatusListenerList();
|
||||
assertThat(statusListeners).hasSize(1);
|
||||
StatusListener statusListener = statusListeners.get(0);
|
||||
assertThat(statusListener).isInstanceOf(FilteringStatusListener.class);
|
||||
assertThat(statusListener).hasFieldOrPropertyWithValue("levelThreshold", Status.ERROR);
|
||||
assertThat(statusListener).extracting("delegate").isInstanceOf(OnErrorConsoleStatusListener.class);
|
||||
AppenderBase<ILoggingEvent> appender = new AppenderBase<>() {
|
||||
|
||||
@Override
|
||||
protected void append(ILoggingEvent eventObject) {
|
||||
throw new IllegalStateException("Fail to append");
|
||||
}
|
||||
|
||||
};
|
||||
this.logger.addAppender(appender);
|
||||
assertThat(loggerContext.getStatusManager().getCopyOfStatusListenerList()).allSatisfy((listener) -> {
|
||||
assertThat(listener).isInstanceOf(FilteringStatusListener.class);
|
||||
assertThat(listener).hasFieldOrPropertyWithValue("levelThreshold", Status.WARN);
|
||||
assertThat(listener).extracting("delegate").isInstanceOf(OnErrorConsoleStatusListener.class);
|
||||
});
|
||||
AlwaysFailAppender appender = new AlwaysFailAppender();
|
||||
appender.setContext(loggerContext);
|
||||
appender.start();
|
||||
this.logger.addAppender(appender);
|
||||
this.logger.info("Hello world");
|
||||
assertThat(output).contains("Fail to append").contains("Hello world");
|
||||
assertThat(output).contains("Always Fail Appender").contains("Hello world");
|
||||
}
|
||||
|
||||
@Test
|
||||
void logbackErrorStatusListenerShouldBeRegisteredWhenUsingCustomLogbackXml(CapturedOutput output) {
|
||||
this.loggingSystem.beforeInitialize();
|
||||
initialize(this.initializationContext, "classpath:logback-include-defaults.xml", null);
|
||||
LoggerContext loggerContext = this.logger.getLoggerContext();
|
||||
assertThat(loggerContext.getStatusManager().getCopyOfStatusListenerList()).allSatisfy((listener) -> {
|
||||
assertThat(listener).isInstanceOf(FilteringStatusListener.class);
|
||||
assertThat(listener).hasFieldOrPropertyWithValue("levelThreshold", Status.WARN);
|
||||
assertThat(listener).extracting("delegate").isInstanceOf(OnErrorConsoleStatusListener.class);
|
||||
});
|
||||
AlwaysFailAppender appender = new AlwaysFailAppender();
|
||||
appender.setContext(loggerContext);
|
||||
appender.start();
|
||||
this.logger.addAppender(appender);
|
||||
this.logger.info("Hello world");
|
||||
assertThat(output).contains("Always Fail Appender").contains("Hello world");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -1042,4 +1049,13 @@ class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
||||
return (SizeAndTimeBasedRollingPolicy<?>) getFileAppender().getRollingPolicy();
|
||||
}
|
||||
|
||||
private static final class AlwaysFailAppender extends AppenderBase<ILoggingEvent> {
|
||||
|
||||
@Override
|
||||
protected void append(ILoggingEvent eventObject) {
|
||||
throw new RuntimeException("Always Fail Appender");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener"/>
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>[%p] - %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
</root>
|
||||
</configuration>
|
@ -10,3 +10,7 @@ logging.structured.format.console=smoketest.structuredlogging.CustomStructuredLo
|
||||
#---
|
||||
spring.config.activate.on-profile=on-error
|
||||
logging.structured.json.customizer=smoketest.structuredlogging.DuplicateJsonMembersCustomizer
|
||||
#---
|
||||
logging.config=classpath:custom-logback.xml
|
||||
spring.config.activate.on-profile=on-error-custom-logback-file
|
||||
logging.structured.json.customizer=smoketest.structuredlogging.DuplicateJsonMembersCustomizer
|
||||
|
@ -0,0 +1,11 @@
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder class="org.springframework.boot.logging.logback.StructuredLogEncoder">
|
||||
<format>ecs</format>
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
</configuration>
|
@ -71,4 +71,11 @@ class SampleStructuredLoggingApplicationTests {
|
||||
assertThat(output).contains("The name 'test' has already been written");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldCaptureCustomizerErrorWhenUsingCustomLogbackFile(CapturedOutput output) {
|
||||
SampleStructuredLoggingApplication
|
||||
.main(new String[] { "--spring.profiles.active=on-error-custom-logback-file" });
|
||||
assertThat(output).contains("The name 'test' has already been written");
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user