Fix SystemStatusListener to prevent superfluous output
Fix `SystemStatusListener` so that superfluous output is not printed when starting an application. This change ensures that the `SystemStatusListener` is not added twice, and that retrospective logging only occurs when `debug` is true. See gh-43931 Signed-off-by: Dmytro Nosan <dimanosan@gmail.com>
This commit is contained in:
parent
fc01b011d5
commit
6ba8e9b089
@ -22,6 +22,7 @@ import ch.qos.logback.classic.LoggerContext;
|
|||||||
import ch.qos.logback.core.status.OnPrintStreamStatusListenerBase;
|
import ch.qos.logback.core.status.OnPrintStreamStatusListenerBase;
|
||||||
import ch.qos.logback.core.status.Status;
|
import ch.qos.logback.core.status.Status;
|
||||||
import ch.qos.logback.core.status.StatusListener;
|
import ch.qos.logback.core.status.StatusListener;
|
||||||
|
import ch.qos.logback.core.status.StatusManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link StatusListener} used to print appropriate status messages to {@link System#out}
|
* {@link StatusListener} used to print appropriate status messages to {@link System#out}
|
||||||
@ -36,6 +37,10 @@ final class SystemStatusListener extends OnPrintStreamStatusListenerBase {
|
|||||||
|
|
||||||
private SystemStatusListener(boolean debug) {
|
private SystemStatusListener(boolean debug) {
|
||||||
this.debug = debug;
|
this.debug = debug;
|
||||||
|
setResetResistant(false);
|
||||||
|
if (!this.debug) {
|
||||||
|
setRetrospective(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -57,9 +62,20 @@ final class SystemStatusListener extends OnPrintStreamStatusListenerBase {
|
|||||||
static void addTo(LoggerContext loggerContext, boolean debug) {
|
static void addTo(LoggerContext loggerContext, boolean debug) {
|
||||||
SystemStatusListener listener = new SystemStatusListener(debug);
|
SystemStatusListener listener = new SystemStatusListener(debug);
|
||||||
listener.setContext(loggerContext);
|
listener.setContext(loggerContext);
|
||||||
if (loggerContext.getStatusManager().add(listener)) {
|
StatusManager sm = loggerContext.getStatusManager();
|
||||||
|
if (!sm.getCopyOfStatusListenerList().contains(listener) && sm.add(listener)) {
|
||||||
listener.start();
|
listener.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return (obj != null) && (obj.getClass() == getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getClass().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,10 @@ import ch.qos.logback.core.encoder.LayoutWrappingEncoder;
|
|||||||
import ch.qos.logback.core.joran.spi.JoranException;
|
import ch.qos.logback.core.joran.spi.JoranException;
|
||||||
import ch.qos.logback.core.rolling.RollingFileAppender;
|
import ch.qos.logback.core.rolling.RollingFileAppender;
|
||||||
import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy;
|
import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy;
|
||||||
|
import ch.qos.logback.core.status.ErrorStatus;
|
||||||
|
import ch.qos.logback.core.status.InfoStatus;
|
||||||
|
import ch.qos.logback.core.status.StatusManager;
|
||||||
|
import ch.qos.logback.core.status.WarnStatus;
|
||||||
import ch.qos.logback.core.util.DynamicClassLoadingException;
|
import ch.qos.logback.core.util.DynamicClassLoadingException;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
@ -645,13 +649,20 @@ class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
|||||||
System.setProperty("logback.debug", "true");
|
System.setProperty("logback.debug", "true");
|
||||||
try {
|
try {
|
||||||
this.loggingSystem.beforeInitialize();
|
this.loggingSystem.beforeInitialize();
|
||||||
|
LoggerContext loggerContext = this.logger.getLoggerContext();
|
||||||
|
StatusManager statusManager = loggerContext.getStatusManager();
|
||||||
|
statusManager.add(new InfoStatus("INFO STATUS MESSAGE", getClass()));
|
||||||
|
statusManager.add(new WarnStatus("WARN STATUS MESSAGE", getClass()));
|
||||||
|
statusManager.add(new ErrorStatus("ERROR STATUS MESSAGE", getClass()));
|
||||||
File file = new File(tmpDir(), "logback-test.log");
|
File file = new File(tmpDir(), "logback-test.log");
|
||||||
LogFile logFile = getLogFile(file.getPath(), null);
|
LogFile logFile = getLogFile(file.getPath(), null);
|
||||||
initialize(this.initializationContext, null, logFile);
|
initialize(this.initializationContext, null, logFile);
|
||||||
assertThat(output).contains("LevelChangePropagator")
|
assertThat(output).contains("LevelChangePropagator")
|
||||||
.contains("SizeAndTimeBasedFileNamingAndTriggeringPolicy")
|
.contains("SizeAndTimeBasedFileNamingAndTriggeringPolicy")
|
||||||
.contains("DebugLogbackConfigurator");
|
.contains("DebugLogbackConfigurator")
|
||||||
LoggerContext loggerContext = this.logger.getLoggerContext();
|
.contains("INFO STATUS MESSAGE")
|
||||||
|
.contains("WARN STATUS MESSAGE")
|
||||||
|
.contains("ERROR STATUS MESSAGE");
|
||||||
assertThat(loggerContext.getStatusManager().getCopyOfStatusListenerList()).allSatisfy((listener) -> {
|
assertThat(loggerContext.getStatusManager().getCopyOfStatusListenerList()).allSatisfy((listener) -> {
|
||||||
assertThat(listener).isInstanceOf(SystemStatusListener.class);
|
assertThat(listener).isInstanceOf(SystemStatusListener.class);
|
||||||
assertThat(listener).hasFieldOrPropertyWithValue("debug", true);
|
assertThat(listener).hasFieldOrPropertyWithValue("debug", true);
|
||||||
@ -663,7 +674,7 @@ class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void logbackErrorStatusListenerShouldBeRegistered(CapturedOutput output) {
|
void logbackSystemStatusListenerShouldBeRegistered(CapturedOutput output) {
|
||||||
this.loggingSystem.beforeInitialize();
|
this.loggingSystem.beforeInitialize();
|
||||||
initialize(this.initializationContext, null, getLogFile(tmpDir() + "/tmp.log", null));
|
initialize(this.initializationContext, null, getLogFile(tmpDir() + "/tmp.log", null));
|
||||||
LoggerContext loggerContext = this.logger.getLoggerContext();
|
LoggerContext loggerContext = this.logger.getLoggerContext();
|
||||||
@ -680,7 +691,41 @@ class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void logbackErrorStatusListenerShouldBeRegisteredWhenUsingCustomLogbackXml(CapturedOutput output) {
|
void logbackSystemStatusListenerShouldBeRegisteredOnlyOnce() {
|
||||||
|
this.loggingSystem.beforeInitialize();
|
||||||
|
initialize(this.initializationContext, null, getLogFile(tmpDir() + "/tmp.log", null));
|
||||||
|
LoggerContext loggerContext = this.logger.getLoggerContext();
|
||||||
|
SystemStatusListener.addTo(loggerContext);
|
||||||
|
SystemStatusListener.addTo(loggerContext, true);
|
||||||
|
assertThat(loggerContext.getStatusManager().getCopyOfStatusListenerList()).satisfiesOnlyOnce((listener) -> {
|
||||||
|
assertThat(listener).isInstanceOf(SystemStatusListener.class);
|
||||||
|
assertThat(listener).hasFieldOrPropertyWithValue("debug", false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void logbackSystemStatusListenerShouldBeRegisteredAndIgnoreAnyRetrospectiveStatusesIfDebugDisabled(
|
||||||
|
CapturedOutput output) {
|
||||||
|
this.loggingSystem.beforeInitialize();
|
||||||
|
LoggerContext loggerContext = this.logger.getLoggerContext();
|
||||||
|
StatusManager statusManager = loggerContext.getStatusManager();
|
||||||
|
statusManager.add(new InfoStatus("INFO STATUS MESSAGE", getClass()));
|
||||||
|
statusManager.add(new WarnStatus("WARN STATUS MESSAGE", getClass()));
|
||||||
|
statusManager.add(new ErrorStatus("ERROR STATUS MESSAGE", getClass()));
|
||||||
|
initialize(this.initializationContext, null, getLogFile(tmpDir() + "/tmp.log", null));
|
||||||
|
assertThat(statusManager.getCopyOfStatusListenerList()).allSatisfy((listener) -> {
|
||||||
|
assertThat(listener).isInstanceOf(SystemStatusListener.class);
|
||||||
|
assertThat(listener).hasFieldOrPropertyWithValue("debug", false);
|
||||||
|
});
|
||||||
|
this.logger.info("Hello world");
|
||||||
|
assertThat(output).doesNotContain("INFO STATUS MESSAGE")
|
||||||
|
.doesNotContain("WARN STATUS MESSAGE")
|
||||||
|
.doesNotContain("ERROR STATUS MESSAGE")
|
||||||
|
.contains("Hello world");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void logbackSystemStatusListenerShouldBeRegisteredWhenUsingCustomLogbackXml(CapturedOutput output) {
|
||||||
this.loggingSystem.beforeInitialize();
|
this.loggingSystem.beforeInitialize();
|
||||||
initialize(this.initializationContext, "classpath:logback-include-defaults.xml", null);
|
initialize(this.initializationContext, "classpath:logback-include-defaults.xml", null);
|
||||||
LoggerContext loggerContext = this.logger.getLoggerContext();
|
LoggerContext loggerContext = this.logger.getLoggerContext();
|
||||||
|
@ -36,11 +36,12 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
class SampleStructuredLoggingApplicationTests {
|
class SampleStructuredLoggingApplicationTests {
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
void reset() {
|
void reset(CapturedOutput output) {
|
||||||
LoggingSystem.get(getClass().getClassLoader()).cleanUp();
|
LoggingSystem.get(getClass().getClassLoader()).cleanUp();
|
||||||
for (LoggingSystemProperty property : LoggingSystemProperty.values()) {
|
for (LoggingSystemProperty property : LoggingSystemProperty.values()) {
|
||||||
System.getProperties().remove(property.getEnvironmentVariableName());
|
System.getProperties().remove(property.getEnvironmentVariableName());
|
||||||
}
|
}
|
||||||
|
assertThat(output).doesNotContain("-INFO in ch.qos.logback.classic.LoggerContext");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
Loading…
x
Reference in New Issue
Block a user