Fail fast when a Logback configuration file is missing or malformed
Closes gh-3309
This commit is contained in:
@@ -206,10 +206,11 @@ public class LoggingApplicationListener implements GenericApplicationListener {
|
|||||||
system.initialize(logConfig, logFile);
|
system.initialize(logConfig, logFile);
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
this.logger.warn("Logging environment value '" + logConfig
|
System.err
|
||||||
+ "' cannot be opened and will be ignored "
|
.println("Logging system failed to initialize using configuration from '"
|
||||||
+ "(using default location instead)");
|
+ logConfig + "'");
|
||||||
system.initialize(null, logFile);
|
ex.printStackTrace(System.err);
|
||||||
|
throw new IllegalStateException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import java.security.CodeSource;
|
|||||||
import java.security.ProtectionDomain;
|
import java.security.ProtectionDomain;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.slf4j.ILoggerFactory;
|
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.turbo.TurboFilter;
|
||||||
import ch.qos.logback.classic.util.ContextInitializer;
|
import ch.qos.logback.classic.util.ContextInitializer;
|
||||||
import ch.qos.logback.core.spi.FilterReply;
|
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>.
|
* {@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 "
|
throw new IllegalStateException("Could not initialize Logback logging from "
|
||||||
+ location, ex);
|
+ 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
|
@Override
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import org.junit.After;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
import org.junit.rules.TemporaryFolder;
|
import org.junit.rules.TemporaryFolder;
|
||||||
import org.slf4j.bridge.SLF4JBridgeHandler;
|
import org.slf4j.bridge.SLF4JBridgeHandler;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
@@ -56,6 +57,9 @@ public class LoggingApplicationListenerTests {
|
|||||||
|
|
||||||
private static final String[] NO_ARGS = {};
|
private static final String[] NO_ARGS = {};
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public ExpectedException thrown = ExpectedException.none();
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||||
|
|
||||||
@@ -129,14 +133,23 @@ public class LoggingApplicationListenerTests {
|
|||||||
public void overrideConfigDoesNotExist() throws Exception {
|
public void overrideConfigDoesNotExist() throws Exception {
|
||||||
EnvironmentTestUtils.addEnvironment(this.context,
|
EnvironmentTestUtils.addEnvironment(this.context,
|
||||||
"logging.config: doesnotexist.xml");
|
"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.initializer.initialize(this.context.getEnvironment(),
|
||||||
this.context.getClassLoader());
|
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
|
@Test
|
||||||
|
|||||||
11
spring-boot/src/test/resources/logback-broken.xml
Normal file
11
spring-boot/src/test/resources/logback-broken.xml
Normal 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>
|
||||||
Reference in New Issue
Block a user