diff --git a/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2-file.xml b/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2-file.xml
index 8379f0ffe21..c1110066d3a 100644
--- a/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2-file.xml
+++ b/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2-file.xml
@@ -4,8 +4,8 @@
%xwEx
%5p
yyyy-MM-dd HH:mm:ss.SSS
- %clr{%d{${LOG_DATEFORMAT_PATTERN}}}{faint} %clr{${LOG_LEVEL_PATTERN}} %clr{%pid}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}
- %d{${LOG_DATEFORMAT_PATTERN}} ${LOG_LEVEL_PATTERN} %pid --- [%t] %-40.40c{1.} : %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}
+ %clr{%d{${sys:LOG_DATEFORMAT_PATTERN}}}{faint} %clr{${sys:LOG_LEVEL_PATTERN}} %clr{%pid}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}
+ %d{${sys:LOG_DATEFORMAT_PATTERN}} ${sys:LOG_LEVEL_PATTERN} %pid --- [%t] %-40.40c{1.} : %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}
diff --git a/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml b/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml
index 9117facc5aa..0a0fdbd4cee 100644
--- a/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml
+++ b/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml
@@ -4,7 +4,7 @@
%xwEx
%5p
yyyy-MM-dd HH:mm:ss.SSS
- %clr{%d{${LOG_DATEFORMAT_PATTERN}}}{faint} %clr{${LOG_LEVEL_PATTERN}} %clr{%pid}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}
+ %clr{%d{${sys:LOG_DATEFORMAT_PATTERN}}}{faint} %clr{${sys:LOG_LEVEL_PATTERN}} %clr{%pid}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}
%d{${LOG_DATEFORMAT_PATTERN}} ${LOG_LEVEL_PATTERN} %pid --- [%t] %-40.40c{1.} : %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}
diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4j2FileXmlTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4j2FileXmlTests.java
new file mode 100644
index 00000000000..c2d2e53d23b
--- /dev/null
+++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4j2FileXmlTests.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2012-2020 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
+ *
+ * https://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.log4j2;
+
+import java.io.File;
+
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.layout.PatternLayout;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import org.springframework.boot.logging.LoggingSystemProperties;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@code log4j2-file.xml}.
+ *
+ * @author Andy Wilkinson
+ */
+class Log4j2FileXmlTests extends Log4j2XmlTests {
+
+ @BeforeEach
+ void configureLogFile(@TempDir File temp) {
+ System.setProperty(LoggingSystemProperties.LOG_FILE, new File(temp, "test.log").getAbsolutePath());
+ }
+
+ @AfterEach
+ void clearLogFile() {
+ System.clearProperty(LoggingSystemProperties.LOG_FILE);
+ }
+
+ @Test
+ void whenLogExceptionConversionWordIsNotConfiguredThenFileAppenderUsesDefault() {
+ assertThat(fileAppenderPattern()).contains("%xwEx");
+ }
+
+ @Test
+ void whenLogExceptionConversionWordIsSetThenFileAppenderUsesIt() {
+ withSystemProperty(LoggingSystemProperties.EXCEPTION_CONVERSION_WORD, "custom",
+ () -> assertThat(fileAppenderPattern()).contains("custom"));
+ }
+
+ @Test
+ void whenLogLevelPatternIsNotConfiguredThenFileAppenderUsesDefault() {
+ assertThat(fileAppenderPattern()).contains("%5p");
+ }
+
+ @Test
+ void whenLogLevelPatternIsSetThenFileAppenderUsesIt() {
+ withSystemProperty(LoggingSystemProperties.LOG_LEVEL_PATTERN, "custom",
+ () -> assertThat(fileAppenderPattern()).contains("custom"));
+ }
+
+ @Test
+ void whenLogLDateformatPatternIsNotConfiguredThenFileAppenderUsesDefault() {
+ assertThat(fileAppenderPattern()).contains("yyyy-MM-dd HH:mm:ss.SSS");
+ }
+
+ @Test
+ void whenLogDateformatPatternIsSetThenFileAppenderUsesIt() {
+ withSystemProperty(LoggingSystemProperties.LOG_DATEFORMAT_PATTERN, "custom",
+ () -> assertThat(fileAppenderPattern()).contains("custom"));
+ }
+
+ @Override
+ protected String getConfigFileName() {
+ return "log4j2-file.xml";
+ }
+
+ private String fileAppenderPattern() {
+ Configuration configuration = initializeConfiguration();
+ return ((PatternLayout) configuration.getAppender("File").getLayout()).getConversionPattern();
+ }
+
+}
diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4j2XmlTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4j2XmlTests.java
new file mode 100644
index 00000000000..ddbd7ec2fa1
--- /dev/null
+++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4j2XmlTests.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2012-2020 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
+ *
+ * https://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.log4j2;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.ConfigurationFactory;
+import org.apache.logging.log4j.core.config.ConfigurationSource;
+import org.apache.logging.log4j.core.layout.PatternLayout;
+import org.junit.jupiter.api.Test;
+
+import org.springframework.boot.logging.LoggingSystemProperties;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@code log4j2.xml}.
+ *
+ * @author Andy Wilkinson
+ */
+class Log4j2XmlTests {
+
+ @Test
+ void whenLogExceptionConversionWordIsNotConfiguredThenConsoleUsesDefault() {
+ assertThat(consolePattern()).contains("%xwEx");
+ }
+
+ @Test
+ void whenLogExceptionConversionWordIsSetThenConsoleUsesIt() {
+ withSystemProperty(LoggingSystemProperties.EXCEPTION_CONVERSION_WORD, "custom",
+ () -> assertThat(consolePattern()).contains("custom"));
+ }
+
+ @Test
+ void whenLogLevelPatternIsNotConfiguredThenConsoleUsesDefault() {
+ assertThat(consolePattern()).contains("%5p");
+ }
+
+ @Test
+ void whenLogLevelPatternIsSetThenConsoleUsesIt() {
+ withSystemProperty(LoggingSystemProperties.LOG_LEVEL_PATTERN, "custom",
+ () -> assertThat(consolePattern()).contains("custom"));
+ }
+
+ @Test
+ void whenLogLDateformatPatternIsNotConfiguredThenConsoleUsesDefault() {
+ assertThat(consolePattern()).contains("yyyy-MM-dd HH:mm:ss.SSS");
+ }
+
+ @Test
+ void whenLogDateformatPatternIsSetThenConsoleUsesIt() {
+ withSystemProperty(LoggingSystemProperties.LOG_DATEFORMAT_PATTERN, "custom",
+ () -> assertThat(consolePattern()).contains("custom"));
+ }
+
+ protected void withSystemProperty(String name, String value, Runnable action) {
+ String previous = System.setProperty(name, value);
+ action.run();
+ if (previous == null) {
+ System.clearProperty(name);
+ }
+ else {
+ System.setProperty(name, previous);
+ }
+ }
+
+ private String consolePattern() {
+ Configuration configuration = initializeConfiguration();
+ return ((PatternLayout) configuration.getAppender("Console").getLayout()).getConversionPattern();
+ }
+
+ protected Configuration initializeConfiguration() {
+ LoggerContext context = new LoggerContext("test");
+ Configuration configuration = ConfigurationFactory.getInstance().getConfiguration(context,
+ configurationSource());
+ configuration.initialize();
+ return configuration;
+ }
+
+ private ConfigurationSource configurationSource() {
+ try (InputStream in = getClass().getResourceAsStream(getConfigFileName())) {
+ return new ConfigurationSource(in);
+ }
+ catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ protected String getConfigFileName() {
+ return "log4j2.xml";
+ }
+
+}