Fail fast when a Logback configuration file is missing or malformed

Closes gh-3309
This commit is contained in:
Andy Wilkinson 2015-06-25 16:58:36 +01:00
parent 31336c2dce
commit c3d93f70b8
4 changed files with 53 additions and 10 deletions

View File

@ -206,10 +206,11 @@ public class LoggingApplicationListener implements GenericApplicationListener {
system.initialize(logConfig, logFile);
}
catch (Exception ex) {
this.logger.warn("Logging environment value '" + logConfig
+ "' cannot be opened and will be ignored "
+ "(using default location instead)");
system.initialize(null, logFile);
System.err
.println("Logging system failed to initialize using configuration from '"
+ logConfig + "'");
ex.printStackTrace(System.err);
throw new IllegalStateException(ex);
}
}
else {

View File

@ -21,6 +21,7 @@ import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.ILoggerFactory;
@ -40,6 +41,7 @@ import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.turbo.TurboFilter;
import ch.qos.logback.classic.util.ContextInitializer;
import ch.qos.logback.core.spi.FilterReply;
import ch.qos.logback.core.status.Status;
/**
* {@link LoggingSystem} for <a href="http://logback.qos.ch">logback</a>.
@ -122,6 +124,22 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem {
throw new IllegalStateException("Could not initialize Logback logging from "
+ location, ex);
}
List<Status> statuses = context.getStatusManager().getCopyOfStatusList();
if (containsError(statuses)) {
for (Status status : statuses) {
System.err.println(status);
}
throw new IllegalStateException("Logback configuration error detected");
}
}
private boolean containsError(List<Status> statuses) {
for (Status status : statuses) {
if (status.getLevel() == Status.ERROR) {
return true;
}
}
return false;
}
@Override

View File

@ -29,6 +29,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.slf4j.bridge.SLF4JBridgeHandler;
import org.springframework.boot.SpringApplication;
@ -56,6 +57,9 @@ public class LoggingApplicationListenerTests {
private static final String[] NO_ARGS = {};
@Rule
public ExpectedException thrown = ExpectedException.none();
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@ -129,14 +133,23 @@ public class LoggingApplicationListenerTests {
public void overrideConfigDoesNotExist() throws Exception {
EnvironmentTestUtils.addEnvironment(this.context,
"logging.config: doesnotexist.xml");
this.thrown.expect(IllegalStateException.class);
this.outputCapture
.expect(containsString("Logging system failed to initialize using configuration from 'doesnotexist.xml'"));
this.initializer.initialize(this.context.getEnvironment(),
this.context.getClassLoader());
}
@Test
public void overrideConfigBroken() throws Exception {
EnvironmentTestUtils.addEnvironment(this.context,
"logging.config: classpath:logback-broken.xml");
this.thrown.expect(IllegalStateException.class);
this.outputCapture
.expect(containsString("Logging system failed to initialize using configuration from 'classpath:logback-broken.xml'"));
this.outputCapture.expect(containsString("ConsolAppender"));
this.initializer.initialize(this.context.getEnvironment(),
this.context.getClassLoader());
// Should not throw
this.logger.info("Hello world");
String output = this.outputCapture.toString().trim();
assertTrue("Wrong output:\n" + output, output.contains("Hello world"));
assertFalse("Wrong output:\n" + output, output.contains("???"));
assertFalse(new File(tmpDir() + "/spring.log").exists());
}
@Test

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsolAppender">
<encoder>
<pattern>${LOG_FILE} [%t] ${PID:-????} %c{1}: %m%n BOOTBOOT</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</configuration>