diff --git a/spring-boot-samples/spring-boot-sample-logback/src/main/resources/logback-spring.xml b/spring-boot-samples/spring-boot-sample-logback/src/main/resources/logback-spring.xml
index 3761cc62b63..e279b822768 100644
--- a/spring-boot-samples/spring-boot-sample-logback/src/main/resources/logback-spring.xml
+++ b/spring-boot-samples/spring-boot-sample-logback/src/main/resources/logback-spring.xml
@@ -1,5 +1,8 @@
-
-
+
+
+
+
+
diff --git a/spring-boot-samples/spring-boot-sample-logback/src/test/java/sample/logback/SampleLogbackApplicationTests.java b/spring-boot-samples/spring-boot-sample-logback/src/test/java/sample/logback/SampleLogbackApplicationTests.java
index b452efa7c4e..aa9b938c6c6 100644
--- a/spring-boot-samples/spring-boot-sample-logback/src/test/java/sample/logback/SampleLogbackApplicationTests.java
+++ b/spring-boot-samples/spring-boot-sample-logback/src/test/java/sample/logback/SampleLogbackApplicationTests.java
@@ -35,4 +35,12 @@ public class SampleLogbackApplicationTests {
this.outputCapture.expect(not(containsString("Sample Trace Message")));
}
+ @Test
+ public void testProfile() throws Exception {
+ SampleLogbackApplication
+ .main(new String[] { "--spring.profiles.active=staging" });
+ this.outputCapture.expect(containsString("Sample Debug Message"));
+ this.outputCapture.expect(containsString("Sample Trace Message"));
+ }
+
}
diff --git a/spring-boot/src/main/java/org/springframework/boot/logging/AbstractLoggingSystem.java b/spring-boot/src/main/java/org/springframework/boot/logging/AbstractLoggingSystem.java
index 9cce7b176bc..6e587ed2f72 100644
--- a/spring-boot/src/main/java/org/springframework/boot/logging/AbstractLoggingSystem.java
+++ b/spring-boot/src/main/java/org/springframework/boot/logging/AbstractLoggingSystem.java
@@ -40,31 +40,35 @@ public abstract class AbstractLoggingSystem extends LoggingSystem {
}
@Override
- public void initialize(String configLocation, LogFile logFile) {
+ public void initialize(LoggingInitializationContext initializationContext,
+ String configLocation, LogFile logFile) {
if (StringUtils.hasLength(configLocation)) {
- initializeWithSpecificConfig(configLocation, logFile);
+ initializeWithSpecificConfig(initializationContext, configLocation, logFile);
return;
}
- initializeWithConventions(logFile);
+ initializeWithConventions(initializationContext, logFile);
}
- private void initializeWithSpecificConfig(String configLocation, LogFile logFile) {
+ private void initializeWithSpecificConfig(
+ LoggingInitializationContext initializationContext, String configLocation,
+ LogFile logFile) {
configLocation = SystemPropertyUtils.resolvePlaceholders(configLocation);
- loadConfiguration(configLocation, logFile);
+ loadConfiguration(initializationContext, configLocation, logFile);
}
- private void initializeWithConventions(LogFile logFile) {
+ private void initializeWithConventions(
+ LoggingInitializationContext initializationContext, LogFile logFile) {
String config = getSelfInitializationConfig();
if (config != null && logFile == null) {
// self initialization has occurred, reinitialize in case of property changes
- reinitialize();
+ reinitialize(initializationContext);
return;
}
if (config == null) {
config = getSpringInitializationConfig();
}
if (config != null) {
- loadConfiguration(config, logFile);
+ loadConfiguration(initializationContext, config, logFile);
return;
}
loadDefaults(logFile);
@@ -131,18 +135,22 @@ public abstract class AbstractLoggingSystem extends LoggingSystem {
/**
* Load a specific configuration.
+ * @param initializationContext the logging initialization context
* @param location the location of the configuration to load (never {@code null})
* @param logFile the file to load or {@code null} if no log file is to be written
*/
- protected abstract void loadConfiguration(String location, LogFile logFile);
+ protected abstract void loadConfiguration(
+ LoggingInitializationContext initializationContext, String location,
+ LogFile logFile);
/**
* Reinitialize the logging system if required. Called when
* {@link #getSelfInitializationConfig()} is used and the log file hasn't changed. May
* be used to reload configuration (for example to pickup additional System
* properties).
+ * @param initializationContext the logging initialization context
*/
- protected void reinitialize() {
+ protected void reinitialize(LoggingInitializationContext initializationContext) {
}
protected final ClassLoader getClassLoader() {
diff --git a/spring-boot/src/main/java/org/springframework/boot/logging/LoggingApplicationListener.java b/spring-boot/src/main/java/org/springframework/boot/logging/LoggingApplicationListener.java
index 8ef047903a7..73bc27a5adc 100644
--- a/spring-boot/src/main/java/org/springframework/boot/logging/LoggingApplicationListener.java
+++ b/spring-boot/src/main/java/org/springframework/boot/logging/LoggingApplicationListener.java
@@ -198,12 +198,14 @@ public class LoggingApplicationListener implements GenericApplicationListener {
private void initializeSystem(ConfigurableEnvironment environment,
LoggingSystem system) {
+ LoggingInitializationContext initializationContext = new LoggingInitializationContext(
+ environment);
LogFile logFile = LogFile.get(environment);
String logConfig = environment.getProperty(CONFIG_PROPERTY);
if (StringUtils.hasLength(logConfig)) {
try {
ResourceUtils.getURL(logConfig).openStream().close();
- system.initialize(logConfig, logFile);
+ system.initialize(initializationContext, logConfig, logFile);
}
catch (Exception ex) {
// NOTE: We can't use the logger here to report the problem
@@ -214,7 +216,7 @@ public class LoggingApplicationListener implements GenericApplicationListener {
}
}
else {
- system.initialize(null, logFile);
+ system.initialize(initializationContext, null, logFile);
}
}
diff --git a/spring-boot/src/main/java/org/springframework/boot/logging/LoggingInitializationContext.java b/spring-boot/src/main/java/org/springframework/boot/logging/LoggingInitializationContext.java
new file mode 100644
index 00000000000..586b5eee392
--- /dev/null
+++ b/spring-boot/src/main/java/org/springframework/boot/logging/LoggingInitializationContext.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.logging;
+
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.Environment;
+
+/**
+ * Context passed to the {@link LoggingSystem} during initialization.
+ *
+ * @author Phillip Webb
+ * @since 1.3.0
+ */
+public class LoggingInitializationContext {
+
+ private final ConfigurableEnvironment environment;
+
+ /**
+ * Create a new {@link LoggingInitializationContext} instance.
+ * @param environment the Spring environment.
+ */
+ public LoggingInitializationContext(ConfigurableEnvironment environment) {
+ this.environment = environment;
+ }
+
+ /**
+ * Return the Spring environment if available.
+ * @return the {@link Environment} or {@code null}
+ */
+ public Environment getEnvironment() {
+ return this.environment;
+ }
+
+}
diff --git a/spring-boot/src/main/java/org/springframework/boot/logging/LoggingSystem.java b/spring-boot/src/main/java/org/springframework/boot/logging/LoggingSystem.java
index 1210f151da9..5e6871ad251 100644
--- a/spring-boot/src/main/java/org/springframework/boot/logging/LoggingSystem.java
+++ b/spring-boot/src/main/java/org/springframework/boot/logging/LoggingSystem.java
@@ -53,19 +53,21 @@ public abstract class LoggingSystem {
/**
* Reset the logging system to be limit output. This method may be called before
- * {@link #initialize(String, LogFile)} to reduce logging noise until the system has
- * been fully Initialized.
+ * {@link #initialize(LoggingInitializationContext, String, LogFile)} to reduce
+ * logging noise until the system has been fully Initialized.
*/
public abstract void beforeInitialize();
/**
* Fully initialize the logging system.
+ * @param initializationContext the logging initialization context
* @param configLocation a log configuration location or {@code null} if default
* initialization is required
* @param logFile the log output file that should be written or {@code null} for
* console only output
*/
- public abstract void initialize(String configLocation, LogFile logFile);
+ public abstract void initialize(LoggingInitializationContext initializationContext,
+ String configLocation, LogFile logFile);
/**
* Clean up the logging system. The default implementation does nothing. Subclasses
diff --git a/spring-boot/src/main/java/org/springframework/boot/logging/java/JavaLoggingSystem.java b/spring-boot/src/main/java/org/springframework/boot/logging/java/JavaLoggingSystem.java
index 6bd3ba8e0d6..ff662ba5cb6 100644
--- a/spring-boot/src/main/java/org/springframework/boot/logging/java/JavaLoggingSystem.java
+++ b/spring-boot/src/main/java/org/springframework/boot/logging/java/JavaLoggingSystem.java
@@ -28,6 +28,7 @@ import java.util.logging.Logger;
import org.springframework.boot.logging.AbstractLoggingSystem;
import org.springframework.boot.logging.LogFile;
import org.springframework.boot.logging.LogLevel;
+import org.springframework.boot.logging.LoggingInitializationContext;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
@@ -81,6 +82,11 @@ public class JavaLoggingSystem extends AbstractLoggingSystem {
}
@Override
+ protected void loadConfiguration(LoggingInitializationContext initializationContext,
+ String location, LogFile logFile) {
+ loadConfiguration(location, logFile);
+ }
+
protected void loadConfiguration(String location, LogFile logFile) {
Assert.notNull(location, "Location must not be null");
try {
diff --git a/spring-boot/src/main/java/org/springframework/boot/logging/log4j/Log4JLoggingSystem.java b/spring-boot/src/main/java/org/springframework/boot/logging/log4j/Log4JLoggingSystem.java
index 2820fe96dd6..96af7c1a255 100644
--- a/spring-boot/src/main/java/org/springframework/boot/logging/log4j/Log4JLoggingSystem.java
+++ b/spring-boot/src/main/java/org/springframework/boot/logging/log4j/Log4JLoggingSystem.java
@@ -25,6 +25,7 @@ import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.boot.logging.LogFile;
import org.springframework.boot.logging.LogLevel;
+import org.springframework.boot.logging.LoggingInitializationContext;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.logging.Slf4JLoggingSystem;
import org.springframework.util.Assert;
@@ -79,6 +80,11 @@ public class Log4JLoggingSystem extends Slf4JLoggingSystem {
}
@Override
+ protected void loadConfiguration(LoggingInitializationContext initializationContext,
+ String location, LogFile logFile) {
+ loadConfiguration(location, logFile);
+ }
+
protected void loadConfiguration(String location, LogFile logFile) {
Assert.notNull(location, "Location must not be null");
if (logFile != null) {
@@ -94,7 +100,7 @@ public class Log4JLoggingSystem extends Slf4JLoggingSystem {
}
@Override
- protected void reinitialize() {
+ protected void reinitialize(LoggingInitializationContext initializationContext) {
loadConfiguration(getSelfInitializationConfig(), null);
}
diff --git a/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java b/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java
index 04a188bb883..57578be33a9 100644
--- a/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java
+++ b/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java
@@ -39,6 +39,7 @@ import org.apache.logging.log4j.core.filter.AbstractFilter;
import org.apache.logging.log4j.message.Message;
import org.springframework.boot.logging.LogFile;
import org.springframework.boot.logging.LogLevel;
+import org.springframework.boot.logging.LoggingInitializationContext;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.logging.Slf4JLoggingSystem;
import org.springframework.util.Assert;
@@ -128,9 +129,10 @@ public class Log4J2LoggingSystem extends Slf4JLoggingSystem {
}
@Override
- public void initialize(String configLocation, LogFile logFile) {
+ public void initialize(LoggingInitializationContext initializationContext,
+ String configLocation, LogFile logFile) {
getLoggerConfig(null).removeFilter(FILTER);
- super.initialize(configLocation, logFile);
+ super.initialize(initializationContext, configLocation, logFile);
}
@Override
@@ -144,6 +146,11 @@ public class Log4J2LoggingSystem extends Slf4JLoggingSystem {
}
@Override
+ protected void loadConfiguration(LoggingInitializationContext initializationContext,
+ String location, LogFile logFile) {
+ loadConfiguration(location, logFile);
+ }
+
protected void loadConfiguration(String location, LogFile logFile) {
Assert.notNull(location, "Location must not be null");
if (logFile != null) {
@@ -170,7 +177,7 @@ public class Log4J2LoggingSystem extends Slf4JLoggingSystem {
}
@Override
- protected void reinitialize() {
+ protected void reinitialize(LoggingInitializationContext initializationContext) {
getLoggerContext().reconfigure();
}
diff --git a/spring-boot/src/main/java/org/springframework/boot/logging/logback/LogbackLoggingSystem.java b/spring-boot/src/main/java/org/springframework/boot/logging/logback/LogbackLoggingSystem.java
index 52a10a8e4e2..c4ccc1e6601 100644
--- a/spring-boot/src/main/java/org/springframework/boot/logging/logback/LogbackLoggingSystem.java
+++ b/spring-boot/src/main/java/org/springframework/boot/logging/logback/LogbackLoggingSystem.java
@@ -30,6 +30,7 @@ import org.slf4j.Marker;
import org.slf4j.impl.StaticLoggerBinder;
import org.springframework.boot.logging.LogFile;
import org.springframework.boot.logging.LogLevel;
+import org.springframework.boot.logging.LoggingInitializationContext;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.logging.Slf4JLoggingSystem;
import org.springframework.util.Assert;
@@ -38,8 +39,10 @@ import org.springframework.util.StringUtils;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.classic.turbo.TurboFilter;
import ch.qos.logback.classic.util.ContextInitializer;
+import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.spi.FilterReply;
import ch.qos.logback.core.status.Status;
@@ -93,9 +96,10 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem {
}
@Override
- public void initialize(String configLocation, LogFile logFile) {
+ public void initialize(LoggingInitializationContext initializationContext,
+ String configLocation, LogFile logFile) {
getLogger(null).getLoggerContext().getTurboFilterList().remove(FILTER);
- super.initialize(configLocation, logFile);
+ super.initialize(initializationContext, configLocation, logFile);
}
@Override
@@ -108,23 +112,24 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem {
}
@Override
- protected void loadConfiguration(String location, LogFile logFile) {
+ protected void loadConfiguration(LoggingInitializationContext initializationContext,
+ String location, LogFile logFile) {
Assert.notNull(location, "Location must not be null");
if (logFile != null) {
logFile.applyToSystemProperties();
}
- LoggerContext context = getLoggerContext();
- context.stop();
- context.reset();
+ LoggerContext loggerContext = getLoggerContext();
+ loggerContext.stop();
+ loggerContext.reset();
try {
- URL url = ResourceUtils.getURL(location);
- new ContextInitializer(context).configureByResource(url);
+ configureByResourceUrl(initializationContext, loggerContext,
+ ResourceUtils.getURL(location));
}
catch (Exception ex) {
throw new IllegalStateException("Could not initialize Logback logging from "
+ location, ex);
}
- List statuses = context.getStatusManager().getCopyOfStatusList();
+ List statuses = loggerContext.getStatusManager().getCopyOfStatusList();
StringBuilder errors = new StringBuilder();
for (Status status : statuses) {
if (status.getLevel() == Status.ERROR) {
@@ -138,6 +143,20 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem {
}
}
+ private void configureByResourceUrl(
+ LoggingInitializationContext initializationContext,
+ LoggerContext loggerContext, URL url) throws JoranException {
+ if (url.toString().endsWith("xml")) {
+ JoranConfigurator configurator = new SpringBootJoranConfigurator(
+ initializationContext);
+ configurator.setContext(loggerContext);
+ configurator.doConfigure(url);
+ }
+ else {
+ new ContextInitializer(loggerContext).configureByResource(url);
+ }
+ }
+
@Override
public void cleanUp() {
super.cleanUp();
@@ -145,9 +164,9 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem {
}
@Override
- protected void reinitialize() {
+ protected void reinitialize(LoggingInitializationContext initializationContext) {
getLoggerContext().reset();
- loadConfiguration(getSelfInitializationConfig(), null);
+ loadConfiguration(initializationContext, getSelfInitializationConfig(), null);
}
private void configureJBossLoggingToUseSlf4j() {
diff --git a/spring-boot/src/main/java/org/springframework/boot/logging/logback/SpringBootJoranConfigurator.java b/spring-boot/src/main/java/org/springframework/boot/logging/logback/SpringBootJoranConfigurator.java
new file mode 100644
index 00000000000..6ef15c5b8ca
--- /dev/null
+++ b/spring-boot/src/main/java/org/springframework/boot/logging/logback/SpringBootJoranConfigurator.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.logging.logback;
+
+import org.springframework.boot.logging.LoggingInitializationContext;
+
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.core.joran.action.NOPAction;
+import ch.qos.logback.core.joran.spi.ElementSelector;
+import ch.qos.logback.core.joran.spi.RuleStore;
+
+/**
+ * Extended version of the Logback {@link JoranConfigurator} that adds additional Spring
+ * Boot rules.
+ *
+ * @author Phillip Webb
+ */
+class SpringBootJoranConfigurator extends JoranConfigurator {
+
+ private LoggingInitializationContext initializationContext;
+
+ public SpringBootJoranConfigurator(LoggingInitializationContext initializationContext) {
+ this.initializationContext = initializationContext;
+ }
+
+ @Override
+ public void addInstanceRules(RuleStore rs) {
+ super.addInstanceRules(rs);
+ rs.addRule(new ElementSelector("*/springProfile"), new SpringProfileAction(
+ this.initializationContext.getEnvironment()));
+ rs.addRule(new ElementSelector("*/springProfile/*"), new NOPAction());
+ }
+
+}
diff --git a/spring-boot/src/main/java/org/springframework/boot/logging/logback/SpringProfileAction.java b/spring-boot/src/main/java/org/springframework/boot/logging/logback/SpringProfileAction.java
new file mode 100644
index 00000000000..101c206630e
--- /dev/null
+++ b/spring-boot/src/main/java/org/springframework/boot/logging/logback/SpringProfileAction.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.logging.logback;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.core.env.Environment;
+import org.springframework.util.Assert;
+import org.xml.sax.Attributes;
+
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.event.InPlayListener;
+import ch.qos.logback.core.joran.event.SaxEvent;
+import ch.qos.logback.core.joran.spi.ActionException;
+import ch.qos.logback.core.joran.spi.InterpretationContext;
+import ch.qos.logback.core.joran.spi.Interpreter;
+import ch.qos.logback.core.util.OptionHelper;
+
+/**
+ * Lockback {@link Action} to support {@code } tags. Allows section of a
+ * logback configuration to only be enabled when a specific profile is active.
+ *
+ * @author Phillip Webb
+ */
+class SpringProfileAction extends Action implements InPlayListener {
+
+ private final Environment environment;
+
+ private int depth = 0;
+
+ private boolean acceptsProfile;
+
+ private List events;
+
+ public SpringProfileAction(Environment environment) {
+ this.environment = environment;
+ }
+
+ @Override
+ public void begin(InterpretationContext ic, String name, Attributes attributes)
+ throws ActionException {
+ this.depth++;
+ if (this.depth != 1) {
+ return;
+ }
+ ic.pushObject(this);
+ this.acceptsProfile = acceptsProfiles(ic, attributes);
+ this.events = new ArrayList();
+ ic.addInPlayListener(this);
+ }
+
+ private boolean acceptsProfiles(InterpretationContext ic, Attributes attributes) {
+ String profileName = attributes.getValue(NAME_ATTRIBUTE);
+ if (!OptionHelper.isEmpty(profileName)) {
+ OptionHelper.substVars(profileName, ic, this.context);
+ return this.environment != null
+ && this.environment.acceptsProfiles(profileName);
+ }
+ return false;
+ }
+
+ @Override
+ public void end(InterpretationContext ic, String name) throws ActionException {
+ this.depth--;
+ if (this.depth != 0) {
+ return;
+ }
+ ic.removeInPlayListener(this);
+ verifyAndPop(ic);
+ if (this.acceptsProfile) {
+ addEventsToPlayer(ic);
+ }
+ }
+
+ private void verifyAndPop(InterpretationContext ic) {
+ Object o = ic.peekObject();
+ Assert.state(o != null, "Unexpected null object on stack");
+ Assert.isInstanceOf(SpringProfileAction.class, o, "logback stack error");
+ Assert.state(o == this, "ProfileAction different than current one on stack");
+ ic.popObject();
+ }
+
+ private void addEventsToPlayer(InterpretationContext ic) {
+ Interpreter interpreter = ic.getJoranInterpreter();
+ this.events.remove(0);
+ this.events.remove(this.events.size() - 1);
+ interpreter.getEventPlayer().addEventsDynamically(this.events, 1);
+ }
+
+ @Override
+ public void inPlay(SaxEvent event) {
+ this.events.add(event);
+ }
+
+}
diff --git a/spring-boot/src/test/java/org/springframework/boot/logging/java/JavaLoggerSystemTests.java b/spring-boot/src/test/java/org/springframework/boot/logging/java/JavaLoggerSystemTests.java
index 280cc13b2fa..25923ac5bd9 100644
--- a/spring-boot/src/test/java/org/springframework/boot/logging/java/JavaLoggerSystemTests.java
+++ b/spring-boot/src/test/java/org/springframework/boot/logging/java/JavaLoggerSystemTests.java
@@ -81,7 +81,7 @@ public class JavaLoggerSystemTests extends AbstractLoggingSystemTests {
public void noFile() throws Exception {
this.loggingSystem.beforeInitialize();
this.logger.info("Hidden");
- this.loggingSystem.initialize(null, null);
+ this.loggingSystem.initialize(null, null, null);
this.logger.info("Hello world");
String output = this.output.toString().trim();
assertTrue("Wrong output:\n" + output, output.contains("Hello world"));
@@ -98,7 +98,7 @@ public class JavaLoggerSystemTests extends AbstractLoggingSystemTests {
}
this.loggingSystem.beforeInitialize();
this.logger.info("Hidden");
- this.loggingSystem.initialize(null, getLogFile(null, tmpDir()));
+ this.loggingSystem.initialize(null, null, getLogFile(null, tmpDir()));
this.logger.info("Hello world");
String output = this.output.toString().trim();
assertTrue("Wrong output:\n" + output, output.contains("Hello world"));
@@ -109,7 +109,7 @@ public class JavaLoggerSystemTests extends AbstractLoggingSystemTests {
@Test
public void testCustomFormatter() throws Exception {
this.loggingSystem.beforeInitialize();
- this.loggingSystem.initialize(null, null);
+ this.loggingSystem.initialize(null, null, null);
this.logger.info("Hello world");
String output = this.output.toString().trim();
assertTrue("Wrong output:\n" + output, output.contains("Hello world"));
@@ -121,6 +121,7 @@ public class JavaLoggerSystemTests extends AbstractLoggingSystemTests {
System.setProperty("PID", "1234");
this.loggingSystem.beforeInitialize();
this.loggingSystem.initialize(
+ null,
"classpath:"
+ ClassUtils.addResourcePathToPackagePath(getClass(),
"logging.properties"), null);
@@ -134,7 +135,8 @@ public class JavaLoggerSystemTests extends AbstractLoggingSystemTests {
@Test
public void testNonDefaultConfigLocation() throws Exception {
this.loggingSystem.beforeInitialize();
- this.loggingSystem.initialize("classpath:logging-nondefault.properties", null);
+ this.loggingSystem.initialize(null, "classpath:logging-nondefault.properties",
+ null);
this.logger.info("Hello world");
String output = this.output.toString().trim();
assertTrue("Wrong output:\n" + output, output.contains("INFO: Hello"));
@@ -143,13 +145,14 @@ public class JavaLoggerSystemTests extends AbstractLoggingSystemTests {
@Test(expected = IllegalStateException.class)
public void testNonexistentConfigLocation() throws Exception {
this.loggingSystem.beforeInitialize();
- this.loggingSystem.initialize("classpath:logging-nonexistent.properties", null);
+ this.loggingSystem.initialize(null, "classpath:logging-nonexistent.properties",
+ null);
}
@Test
public void setLevel() throws Exception {
this.loggingSystem.beforeInitialize();
- this.loggingSystem.initialize(null, null);
+ this.loggingSystem.initialize(null, null, null);
this.logger.debug("Hello");
this.loggingSystem.setLogLevel("org.springframework.boot", LogLevel.DEBUG);
this.logger.debug("Hello");
diff --git a/spring-boot/src/test/java/org/springframework/boot/logging/log4j/Log4JLoggingSystemTests.java b/spring-boot/src/test/java/org/springframework/boot/logging/log4j/Log4JLoggingSystemTests.java
index af39dca37dd..e0ad064f8d6 100644
--- a/spring-boot/src/test/java/org/springframework/boot/logging/log4j/Log4JLoggingSystemTests.java
+++ b/spring-boot/src/test/java/org/springframework/boot/logging/log4j/Log4JLoggingSystemTests.java
@@ -68,7 +68,7 @@ public class Log4JLoggingSystemTests extends AbstractLoggingSystemTests {
public void noFile() throws Exception {
this.loggingSystem.beforeInitialize();
this.logger.info("Hidden");
- this.loggingSystem.initialize(null, null);
+ this.loggingSystem.initialize(null, null, null);
this.logger.info("Hello world");
String output = this.output.toString().trim();
assertTrue("Wrong output:\n" + output, output.contains("Hello world"));
@@ -80,7 +80,7 @@ public class Log4JLoggingSystemTests extends AbstractLoggingSystemTests {
public void withFile() throws Exception {
this.loggingSystem.beforeInitialize();
this.logger.info("Hidden");
- this.loggingSystem.initialize(null, getLogFile(null, tmpDir()));
+ this.loggingSystem.initialize(null, null, getLogFile(null, tmpDir()));
this.logger.info("Hello world");
String output = this.output.toString().trim();
assertTrue("Wrong output:\n" + output, output.contains("Hello world"));
@@ -91,7 +91,7 @@ public class Log4JLoggingSystemTests extends AbstractLoggingSystemTests {
@Test
public void testNonDefaultConfigLocation() throws Exception {
this.loggingSystem.beforeInitialize();
- this.loggingSystem.initialize("classpath:log4j-nondefault.properties",
+ this.loggingSystem.initialize(null, "classpath:log4j-nondefault.properties",
getLogFile(null, tmpDir()));
this.logger.info("Hello world");
String output = this.output.toString().trim();
@@ -103,13 +103,13 @@ public class Log4JLoggingSystemTests extends AbstractLoggingSystemTests {
@Test(expected = IllegalStateException.class)
public void testNonexistentConfigLocation() throws Exception {
this.loggingSystem.beforeInitialize();
- this.loggingSystem.initialize("classpath:log4j-nonexistent.xml", null);
+ this.loggingSystem.initialize(null, "classpath:log4j-nonexistent.xml", null);
}
@Test
public void setLevel() throws Exception {
this.loggingSystem.beforeInitialize();
- this.loggingSystem.initialize(null, null);
+ this.loggingSystem.initialize(null, null, null);
this.logger.debug("Hello");
this.loggingSystem.setLogLevel("org.springframework.boot", LogLevel.DEBUG);
this.logger.debug("Hello");
@@ -121,7 +121,7 @@ public class Log4JLoggingSystemTests extends AbstractLoggingSystemTests {
@Ignore("Fails on Bamboo")
public void loggingThatUsesJulIsCaptured() {
this.loggingSystem.beforeInitialize();
- this.loggingSystem.initialize(null, null);
+ this.loggingSystem.initialize(null, null, null);
java.util.logging.Logger julLogger = java.util.logging.Logger
.getLogger(getClass().getName());
julLogger.severe("Hello world");
diff --git a/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystemTests.java b/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystemTests.java
index 1b51e70ad28..025031331aa 100644
--- a/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystemTests.java
+++ b/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystemTests.java
@@ -71,7 +71,7 @@ public class Log4J2LoggingSystemTests extends AbstractLoggingSystemTests {
public void noFile() throws Exception {
this.loggingSystem.beforeInitialize();
this.logger.info("Hidden");
- this.loggingSystem.initialize(null, null);
+ this.loggingSystem.initialize(null, null, null);
this.logger.info("Hello world");
String output = this.output.toString().trim();
assertTrue("Wrong output:\n" + output, output.contains("Hello world"));
@@ -85,7 +85,7 @@ public class Log4J2LoggingSystemTests extends AbstractLoggingSystemTests {
public void withFile() throws Exception {
this.loggingSystem.beforeInitialize();
this.logger.info("Hidden");
- this.loggingSystem.initialize(null, getLogFile(null, tmpDir()));
+ this.loggingSystem.initialize(null, null, getLogFile(null, tmpDir()));
this.logger.info("Hello world");
String output = this.output.toString().trim();
assertTrue("Wrong output:\n" + output, output.contains("Hello world"));
@@ -98,7 +98,7 @@ public class Log4J2LoggingSystemTests extends AbstractLoggingSystemTests {
@Test
public void testNonDefaultConfigLocation() throws Exception {
this.loggingSystem.beforeInitialize();
- this.loggingSystem.initialize("classpath:log4j2-nondefault.xml",
+ this.loggingSystem.initialize(null, "classpath:log4j2-nondefault.xml",
getLogFile(tmpDir() + "/tmp.log", null));
this.logger.info("Hello world");
String output = this.output.toString().trim();
@@ -116,13 +116,13 @@ public class Log4J2LoggingSystemTests extends AbstractLoggingSystemTests {
@Test(expected = IllegalStateException.class)
public void testNonexistentConfigLocation() throws Exception {
this.loggingSystem.beforeInitialize();
- this.loggingSystem.initialize("classpath:log4j2-nonexistent.xml", null);
+ this.loggingSystem.initialize(null, "classpath:log4j2-nonexistent.xml", null);
}
@Test
public void setLevel() throws Exception {
this.loggingSystem.beforeInitialize();
- this.loggingSystem.initialize(null, null);
+ this.loggingSystem.initialize(null, null, null);
this.logger.debug("Hello");
this.loggingSystem.setLogLevel("org.springframework.boot", LogLevel.DEBUG);
this.logger.debug("Hello");
@@ -134,7 +134,7 @@ public class Log4J2LoggingSystemTests extends AbstractLoggingSystemTests {
@Ignore("Fails on Bamboo")
public void loggingThatUsesJulIsCaptured() {
this.loggingSystem.beforeInitialize();
- this.loggingSystem.initialize(null, null);
+ this.loggingSystem.initialize(null, null, null);
java.util.logging.Logger julLogger = java.util.logging.Logger
.getLogger(getClass().getName());
julLogger.severe("Hello world");
diff --git a/spring-boot/src/test/java/org/springframework/boot/logging/logback/LogbackLoggingSystemTests.java b/spring-boot/src/test/java/org/springframework/boot/logging/logback/LogbackLoggingSystemTests.java
index 37f0344b7fe..6fe9c1fe863 100644
--- a/spring-boot/src/test/java/org/springframework/boot/logging/logback/LogbackLoggingSystemTests.java
+++ b/spring-boot/src/test/java/org/springframework/boot/logging/logback/LogbackLoggingSystemTests.java
@@ -31,7 +31,9 @@ import org.slf4j.bridge.SLF4JBridgeHandler;
import org.slf4j.impl.StaticLoggerBinder;
import org.springframework.boot.logging.AbstractLoggingSystemTests;
import org.springframework.boot.logging.LogLevel;
+import org.springframework.boot.logging.LoggingInitializationContext;
import org.springframework.boot.test.OutputCapture;
+import org.springframework.mock.env.MockEnvironment;
import org.springframework.util.StringUtils;
import ch.qos.logback.classic.Logger;
@@ -61,9 +63,13 @@ public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
private Log logger;
+ private LoggingInitializationContext initializationContext;
+
@Before
public void setup() {
this.logger = new SLF4JLogFactory().getInstance(getClass().getName());
+ this.initializationContext = new LoggingInitializationContext(
+ new MockEnvironment());
}
@Override
@@ -76,7 +82,7 @@ public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
public void noFile() throws Exception {
this.loggingSystem.beforeInitialize();
this.logger.info("Hidden");
- this.loggingSystem.initialize(null, null);
+ this.loggingSystem.initialize(this.initializationContext, null, null);
this.logger.info("Hello world");
String output = this.output.toString().trim();
assertTrue("Wrong output:\n" + output, output.contains("Hello world"));
@@ -88,7 +94,8 @@ public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
public void withFile() throws Exception {
this.loggingSystem.beforeInitialize();
this.logger.info("Hidden");
- this.loggingSystem.initialize(null, getLogFile(null, tmpDir()));
+ this.loggingSystem.initialize(this.initializationContext, null,
+ getLogFile(null, tmpDir()));
this.logger.info("Hello world");
String output = this.output.toString().trim();
assertTrue("Wrong output:\n" + output, output.contains("Hello world"));
@@ -108,7 +115,8 @@ public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
@Test
public void testNonDefaultConfigLocation() throws Exception {
this.loggingSystem.beforeInitialize();
- this.loggingSystem.initialize("classpath:logback-nondefault.xml",
+ this.loggingSystem.initialize(this.initializationContext,
+ "classpath:logback-nondefault.xml",
getLogFile(tmpDir() + "/tmp.log", null));
this.logger.info("Hello world");
String output = this.output.toString().trim();
@@ -121,13 +129,14 @@ public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
@Test(expected = IllegalStateException.class)
public void testNonexistentConfigLocation() throws Exception {
this.loggingSystem.beforeInitialize();
- this.loggingSystem.initialize("classpath:logback-nonexistent.xml", null);
+ this.loggingSystem.initialize(this.initializationContext,
+ "classpath:logback-nonexistent.xml", null);
}
@Test
public void setLevel() throws Exception {
this.loggingSystem.beforeInitialize();
- this.loggingSystem.initialize(null, null);
+ this.loggingSystem.initialize(this.initializationContext, null, null);
this.logger.debug("Hello");
this.loggingSystem.setLogLevel("org.springframework.boot", LogLevel.DEBUG);
this.logger.debug("Hello");
@@ -138,7 +147,7 @@ public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
@Test
public void loggingThatUsesJulIsCaptured() {
this.loggingSystem.beforeInitialize();
- this.loggingSystem.initialize(null, null);
+ this.loggingSystem.initialize(this.initializationContext, null, null);
java.util.logging.Logger julLogger = java.util.logging.Logger
.getLogger(getClass().getName());
julLogger.info("Hello world");
diff --git a/spring-boot/src/test/java/org/springframework/boot/logging/logback/SpringBootJoranConfiguratorTests.java b/spring-boot/src/test/java/org/springframework/boot/logging/logback/SpringBootJoranConfiguratorTests.java
new file mode 100644
index 00000000000..25869f44e93
--- /dev/null
+++ b/spring-boot/src/test/java/org/springframework/boot/logging/logback/SpringBootJoranConfiguratorTests.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2012-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.logging.logback;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.impl.StaticLoggerBinder;
+import org.springframework.boot.logging.LoggingInitializationContext;
+import org.springframework.boot.test.OutputCapture;
+import org.springframework.mock.env.MockEnvironment;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.core.joran.spi.JoranException;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.not;
+
+/**
+ * Tests for {@link SpringBootJoranConfigurator}.
+ *
+ * @author Phillip Webb
+ */
+public class SpringBootJoranConfiguratorTests {
+
+ @Rule
+ public OutputCapture out = new OutputCapture();
+
+ private MockEnvironment environment;
+
+ private LoggingInitializationContext initializationContext;
+
+ private JoranConfigurator configurator;
+
+ private LoggerContext context;
+
+ private Logger logger;
+
+ @Before
+ public void setup() {
+ this.environment = new MockEnvironment();
+ this.initializationContext = new LoggingInitializationContext(this.environment);
+ this.configurator = new SpringBootJoranConfigurator(this.initializationContext);
+ StaticLoggerBinder binder = StaticLoggerBinder.getSingleton();
+ this.context = (LoggerContext) binder.getLoggerFactory();
+ this.logger = this.context.getLogger(getClass());
+ }
+
+ @After
+ public void reset() {
+ this.context.reset();
+ }
+
+ @Test
+ public void profileActive() throws Exception {
+ this.environment.setActiveProfiles("production");
+ initialize("production-profile.xml");
+ this.logger.trace("Hello");
+ this.out.expect(containsString("Hello"));
+ }
+
+ @Test
+ public void profileNotActive() throws Exception {
+ initialize("production-profile.xml");
+ this.logger.trace("Hello");
+ this.out.expect(not(containsString("Hello")));
+ }
+
+ @Test
+ public void profileNestedActiveActive() throws Exception {
+ doTestNestedProfile(true, "outer", "inner");
+ }
+
+ @Test
+ public void profileNestedActiveNotActive() throws Exception {
+ doTestNestedProfile(false, "outer");
+ }
+
+ @Test
+ public void profileNestedNotActiveActive() throws Exception {
+ doTestNestedProfile(false, "inner");
+ }
+
+ @Test
+ public void profileNestedNotActiveNotActive() throws Exception {
+ doTestNestedProfile(false);
+ }
+
+ private void doTestNestedProfile(boolean expected, String... profiles)
+ throws JoranException {
+ this.environment.setActiveProfiles(profiles);
+ initialize("nested.xml");
+ this.logger.trace("Hello");
+ if (expected) {
+ this.out.expect(containsString("Hello"));
+ }
+ else {
+ this.out.expect(not(containsString("Hello")));
+ }
+
+ }
+
+ private void initialize(String config) throws JoranException {
+ this.configurator.setContext(this.context);
+ this.configurator.doConfigure(getClass().getResourceAsStream(config));
+ }
+
+}
diff --git a/spring-boot/src/test/resources/org/springframework/boot/logging/logback/nested.xml b/spring-boot/src/test/resources/org/springframework/boot/logging/logback/nested.xml
new file mode 100644
index 00000000000..9ad8b045680
--- /dev/null
+++ b/spring-boot/src/test/resources/org/springframework/boot/logging/logback/nested.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/spring-boot/src/test/resources/org/springframework/boot/logging/logback/production-profile.xml b/spring-boot/src/test/resources/org/springframework/boot/logging/logback/production-profile.xml
new file mode 100644
index 00000000000..8b263afd5dd
--- /dev/null
+++ b/spring-boot/src/test/resources/org/springframework/boot/logging/logback/production-profile.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+