diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml index 2237d252c6c..bbcfc86385a 100644 --- a/spring-boot-dependencies/pom.xml +++ b/spring-boot-dependencies/pom.xml @@ -93,6 +93,7 @@ 4.11 3.0.8 1.2.17 + 2.0.2 1.1.2 1.9.5 2.12.3 @@ -287,6 +288,11 @@ spring-boot-starter-log4j 1.2.0.BUILD-SNAPSHOT + + org.springframework.boot + spring-boot-starter-log4j2 + 1.2.0.BUILD-SNAPSHOT + org.springframework.boot spring-boot-starter-logging @@ -562,6 +568,21 @@ log4j ${log4j.version} + + org.apache.logging.log4j + log4j-api + ${log4j2.version} + + + org.apache.logging.log4j + log4j-core + ${log4j2.version} + + + org.apache.logging.log4j + log4j-slf4j-impl + ${log4j2.version} + mysql mysql-connector-java diff --git a/spring-boot-docs/src/main/asciidoc/howto.adoc b/spring-boot-docs/src/main/asciidoc/howto.adoc index c597a2011af..b2bbc3e9f05 100644 --- a/spring-boot-docs/src/main/asciidoc/howto.adoc +++ b/spring-boot-docs/src/main/asciidoc/howto.adoc @@ -961,14 +961,15 @@ If Groovy is on the classpath you should be able to configure Logback with [[howto-configure-log4j-for-logging]] === Configure Log4j for logging -Spring Boot supports http://logging.apache.org/log4j[Log4j] for logging -configuration, but it has to be on the classpath. If you are using the starter poms for -assembling dependencies that means you have to exclude logback and then include log4j -instead. If you aren't using the starter poms then you need to provide `commons-logging` -(at least) in addition to Log4j. +Spring Boot also supports either http://logging.apache.org/log4j/1.2[Log4j] or +http://logging.apache.org/log4j/2.x[Log4j 2] for logging configuration, but only if one +of them is on the classpath. If you are using the starter poms for assembling +dependencies that means you have to exclude Logback and then include your chosen version +of Log4j instead. If you aren't using the starter poms then you need to provide +`commons-logging` (at least) in addition to your chosen version of Log4j. -The simplest path to using Log4j is probably through the starter poms, even though it -requires some jiggling with excludes, e.g. in Maven: +The simplest path is probably through the starter poms, even though it requires some +jiggling with excludes, .e.g. in Maven: [source,xml,indent=0,subs="verbatim,quotes,attributes"] ---- @@ -992,10 +993,13 @@ requires some jiggling with excludes, e.g. in Maven: ---- -NOTE: The use of the log4j starter gathers together the dependencies for common logging -requirements (e.g. including having Tomcat use `java.util.logging` but configure the -output using Log4j). See the Actuator Log4j Sample for more detail and to see it in -action. +To use Log4j 2, simply depend on `spring-boot-starter-log4j2` rather than +`spring-boot-starter-log4j` + +NOTE: The use of the one of the Log4j starters gathers together the dependencies for +common logging requirements (e.g. including having Tomcat use `java.util.logging` but +configure the output using Log4j or Log4j 2). See the Actuator Log4j or Log4j 2 +samples for more detail and to see it in action. diff --git a/spring-boot-samples/pom.xml b/spring-boot-samples/pom.xml index ac005c1d095..a7ec0496a63 100644 --- a/spring-boot-samples/pom.xml +++ b/spring-boot-samples/pom.xml @@ -22,6 +22,7 @@ spring-boot-sample-actuator spring-boot-sample-actuator-log4j + spring-boot-sample-actuator-log4j2 spring-boot-sample-actuator-noweb spring-boot-sample-actuator-ui spring-boot-sample-amqp diff --git a/spring-boot-samples/spring-boot-sample-actuator-log4j/pom.xml b/spring-boot-samples/spring-boot-sample-actuator-log4j/pom.xml index 64261d0d7d2..1db124f8d99 100644 --- a/spring-boot-samples/spring-boot-sample-actuator-log4j/pom.xml +++ b/spring-boot-samples/spring-boot-sample-actuator-log4j/pom.xml @@ -8,8 +8,8 @@ 1.2.0.BUILD-SNAPSHOT spring-boot-sample-actuator-log4j - Spring Boot Actuator Log4J Sample - Spring Boot Actuator Log4J Sample + Spring Boot Actuator Log4j Sample + Spring Boot Actuator Log4j Sample http://projects.spring.io/spring-boot/ Pivotal Software, Inc. diff --git a/spring-boot-samples/spring-boot-sample-actuator-log4j2/pom.xml b/spring-boot-samples/spring-boot-sample-actuator-log4j2/pom.xml new file mode 100644 index 00000000000..43b43161139 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator-log4j2/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-samples + 1.2.0.BUILD-SNAPSHOT + + spring-boot-sample-actuator-log4j2 + Spring Boot Actuator Log4j 2 Sample + Spring Boot Actuator Log4j 2 Sample + http://projects.spring.io/spring-boot/ + + Pivotal Software, Inc. + http://www.spring.io + + + ${basedir}/../.. + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-log4j2 + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-logging + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/java/sample/actuator/log4j2/HelloWorldService.java b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/java/sample/actuator/log4j2/HelloWorldService.java new file mode 100644 index 00000000000..fe8211ed48a --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/java/sample/actuator/log4j2/HelloWorldService.java @@ -0,0 +1,32 @@ +/* + * Copyright 2012-2013 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 sample.actuator.log4j2; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class HelloWorldService { + + @Autowired + private ServiceProperties configuration; + + public String getHelloMessage() { + return "Hello " + this.configuration.getName(); + } + +} diff --git a/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/java/sample/actuator/log4j2/SampleActuatorApplication.java b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/java/sample/actuator/log4j2/SampleActuatorApplication.java new file mode 100644 index 00000000000..5dd9d4569f7 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/java/sample/actuator/log4j2/SampleActuatorApplication.java @@ -0,0 +1,35 @@ +/* + * Copyright 2012-2013 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 sample.actuator.log4j2; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@EnableConfigurationProperties +@ComponentScan +public class SampleActuatorApplication { + + public static void main(String[] args) throws Exception { + SpringApplication.run(SampleActuatorApplication.class, args); + } + +} diff --git a/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/java/sample/actuator/log4j2/SampleController.java b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/java/sample/actuator/log4j2/SampleController.java new file mode 100644 index 00000000000..889931dc896 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/java/sample/actuator/log4j2/SampleController.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012-2013 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 sample.actuator.log4j2; + +import java.util.Collections; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +public class SampleController { + + @Autowired + private HelloWorldService helloWorldService; + + @RequestMapping("/") + @ResponseBody + public Map helloWorld() { + return Collections.singletonMap("message", + this.helloWorldService.getHelloMessage()); + } + + @RequestMapping("/foo") + @ResponseBody + public String foo() { + throw new IllegalArgumentException("Server error"); + } +} diff --git a/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/java/sample/actuator/log4j2/ServiceProperties.java b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/java/sample/actuator/log4j2/ServiceProperties.java new file mode 100644 index 00000000000..94945534a29 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/java/sample/actuator/log4j2/ServiceProperties.java @@ -0,0 +1,36 @@ +/* + * Copyright 2012-2014 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 sample.actuator.log4j2; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@ConfigurationProperties(prefix = "service", ignoreUnknownFields = false) +@Component +public class ServiceProperties { + + private String name = "World"; + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/resources/application.properties b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/resources/application.properties new file mode 100644 index 00000000000..0f0b2727261 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/resources/application.properties @@ -0,0 +1,17 @@ +logging.file: /tmp/logs/app.log +#server.port: 8080 +#management.port: 8080 +management.address: 127.0.0.1 +endpoints.shutdown.enabled: true +server.tomcat.basedir: target/tomcat +server.tomcat.access_log_pattern: %h %t "%r" %s %b +security.require_ssl: false +service.name: Daniel +shell.ssh.enabled: true +shell.ssh.port: 2222 +#shell.telnet.enabled: false +#shell.telnet.port: 1111 +shell.auth: spring +#shell.auth: key +#shell.auth.key.path: ${user.home}/test/id_rsa.pub.pem +#shell.auth: simple diff --git a/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/resources/log4j2.xml b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/resources/log4j2.xml new file mode 100644 index 00000000000..0f526e70797 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/main/resources/log4j2.xml @@ -0,0 +1,22 @@ + + + + ???? + [%d{yyyy-MM-dd HH:mm:ss.SSS}] log4j2%X{context} - ${sys:PID} %5p [%t] --- %c{1}: %m%n + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/test/java/sample/actuator/log4j2/SampleActuatorApplicationTests.java b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/test/java/sample/actuator/log4j2/SampleActuatorApplicationTests.java new file mode 100644 index 00000000000..ad5c29a82c7 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator-log4j2/src/test/java/sample/actuator/log4j2/SampleActuatorApplicationTests.java @@ -0,0 +1,61 @@ +/* + * Copyright 2012-2014 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 sample.actuator.log4j2; + +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.boot.test.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import static org.junit.Assert.assertEquals; + +/** + * Basic integration tests for service demo application. + * + * @author Dave Syer + */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = SampleActuatorApplication.class) +@WebAppConfiguration +@IntegrationTest("server.port=0") +@DirtiesContext +public class SampleActuatorApplicationTests { + + @Value("${local.server.port}") + private int port; + + @Test + public void testHome() throws Exception { + @SuppressWarnings("rawtypes") + ResponseEntity entity = new TestRestTemplate().getForEntity( + "http://localhost:" + port, Map.class); + assertEquals(HttpStatus.OK, entity.getStatusCode()); + @SuppressWarnings("unchecked") + Map body = entity.getBody(); + assertEquals("Hello Daniel", body.get("message")); + } + +} diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml index 8d965b2fa8a..41e08d41228 100644 --- a/spring-boot-starters/pom.xml +++ b/spring-boot-starters/pom.xml @@ -41,6 +41,7 @@ spring-boot-starter-jta-bitronix spring-boot-starter-logging spring-boot-starter-log4j + spring-boot-starter-log4j2 spring-boot-starter-mobile spring-boot-starter-actuator spring-boot-starter-parent diff --git a/spring-boot-starters/spring-boot-starter-log4j2/pom.xml b/spring-boot-starters/spring-boot-starter-log4j2/pom.xml new file mode 100644 index 00000000000..d1e59f0b864 --- /dev/null +++ b/spring-boot-starters/spring-boot-starter-log4j2/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starters + 1.2.0.BUILD-SNAPSHOT + + spring-boot-starter-log4j2 + Spring Boot Log4J2 Starter + Spring Boot Log4J2 Starter + http://projects.spring.io/spring-boot/ + + Pivotal Software, Inc. + http://www.spring.io + + + ${basedir}/../.. + + + + org.slf4j + jcl-over-slf4j + + + org.slf4j + jul-to-slf4j + + + org.apache.logging.log4j + log4j-slf4j-impl + + + org.apache.logging.log4j + log4j-api + + + org.apache.logging.log4j + log4j-core + + + diff --git a/spring-boot-starters/spring-boot-starter-log4j2/src/main/resources/META-INF/spring.provides b/spring-boot-starters/spring-boot-starter-log4j2/src/main/resources/META-INF/spring.provides new file mode 100644 index 00000000000..8b5bde70074 --- /dev/null +++ b/spring-boot-starters/spring-boot-starter-log4j2/src/main/resources/META-INF/spring.provides @@ -0,0 +1 @@ +provides: log4j2,log4j-slf4j-impl diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml index 7036d0cb55c..d51218d1f2a 100644 --- a/spring-boot/pom.xml +++ b/spring-boot/pom.xml @@ -74,6 +74,16 @@ log4j true + + org.apache.logging.log4j + log4j-api + true + + + org.apache.logging.log4j + log4j-core + true + org.apache.httpcomponents httpclient 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 469ec1dde38..cb3033ddca7 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 @@ -37,6 +37,8 @@ public abstract class LoggingSystem { systems.put("ch.qos.logback.core.Appender", pkg + ".logback.LogbackLoggingSystem"); systems.put("org.apache.log4j.PropertyConfigurator", pkg + ".log4j.Log4JLoggingSystem"); + systems.put("org.apache.logging.log4j.LogManager", pkg + + ".log4j2.Log4J2LoggingSystem"); systems.put("java.util.logging.LogManager", pkg + ".java.JavaLoggingSystem"); SYSTEMS = Collections.unmodifiableMap(systems); } 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 bd7a83bec6b..fb94a549836 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 @@ -33,7 +33,7 @@ import org.springframework.util.Log4jConfigurer; import org.springframework.util.StringUtils; /** - * {@link LoggingSystem} for for log4j. + * {@link LoggingSystem} for Log4j. * * @author Phillip Webb * @author Dave Syer diff --git a/spring-boot/src/main/java/org/springframework/boot/logging/log4j/package-info.java b/spring-boot/src/main/java/org/springframework/boot/logging/log4j/package-info.java index 90e1504f55b..8a32cb7f45a 100644 --- a/spring-boot/src/main/java/org/springframework/boot/logging/log4j/package-info.java +++ b/spring-boot/src/main/java/org/springframework/boot/logging/log4j/package-info.java @@ -15,7 +15,7 @@ */ /** - * Support for the Log4J logging library. + * Support for the Log4j logging library. */ package org.springframework.boot.logging.log4j; 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 new file mode 100644 index 00000000000..4ff3cc8277c --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java @@ -0,0 +1,74 @@ +package org.springframework.boot.logging.log4j2; + +import java.net.URL; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +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.springframework.boot.logging.AbstractLoggingSystem; +import org.springframework.boot.logging.LogLevel; +import org.springframework.boot.logging.LoggingSystem; +import org.springframework.util.Assert; +import org.springframework.util.ResourceUtils; +import org.springframework.util.SystemPropertyUtils; + +/** + * {@link LoggingSystem} for Log4j 2. + * + * @author Daniel Fullarton + * @since 1.2.0 + */ +public class Log4J2LoggingSystem extends AbstractLoggingSystem { + + private static final Map LEVELS; + static { + Map levels = new HashMap(); + levels.put(LogLevel.TRACE, Level.TRACE); + levels.put(LogLevel.DEBUG, Level.DEBUG); + levels.put(LogLevel.INFO, Level.INFO); + levels.put(LogLevel.WARN, Level.WARN); + levels.put(LogLevel.ERROR, Level.ERROR); + levels.put(LogLevel.FATAL, Level.ERROR); + levels.put(LogLevel.OFF, Level.OFF); + LEVELS = Collections.unmodifiableMap(levels); + } + + public Log4J2LoggingSystem(ClassLoader classLoader) { + super(classLoader, "log4j2.json", "log4j2.jsn", "log4j2.xml"); + } + + @Override + public void initialize(String configLocation) { + Assert.notNull(configLocation, "ConfigLocation must not be null"); + String resolvedLocation = SystemPropertyUtils.resolvePlaceholders(configLocation); + + try { + LoggerContext ctx = (LoggerContext) LogManager.getContext(false); + URL url = ResourceUtils.getURL(resolvedLocation); + ConfigurationSource configSource = new ConfigurationSource(url.openStream(), + url); + Configuration config = ConfigurationFactory.getInstance().getConfiguration( + configSource); + ctx.start(config); + + } + catch (Exception ex) { + throw new IllegalStateException("Could not initialize logging from " + + configLocation, ex); + } + + } + + @Override + public void setLogLevel(String loggerName, LogLevel level) { + LoggerContext ctx = (LoggerContext) LogManager.getContext(false); + ctx.getConfiguration().getLoggerConfig(loggerName).setLevel(LEVELS.get(level)); + ctx.updateLoggers(); + } +} diff --git a/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/package-info.java b/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/package-info.java new file mode 100644 index 00000000000..64115003e66 --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2012-2014 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. + */ + +/** + * Support for the Log4j 2 logging library. + */ +package org.springframework.boot.logging.log4j2; + diff --git a/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/basic-log4j2.xml b/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/basic-log4j2.xml new file mode 100644 index 00000000000..fdac8fe9584 --- /dev/null +++ b/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/basic-log4j2.xml @@ -0,0 +1,25 @@ + + + + ???? + [%d{yyyy-MM-dd HH:mm:ss.SSS}] boot%X{context} - ${sys:PID} %5p [%t] --- %c{1}: %m%n + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml b/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml new file mode 100644 index 00000000000..4b89e3fc384 --- /dev/null +++ b/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml @@ -0,0 +1,36 @@ + + + + ???? + /tmp + ${sys:LOG_PATH}/spring.log + [%d{yyyy-MM-dd HH:mm:ss.SSS}] boot%X{context} - ${sys:PID} %5p [%t] --- %c{1}: %m%n + + + + + + + + ${LOG_PATTERN} + + + + + + + + + + + + + + + + + + + + \ No newline at end of file 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 new file mode 100644 index 00000000000..81a78e3fcae --- /dev/null +++ b/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystemTests.java @@ -0,0 +1,93 @@ +/* + * Copyright 2012-2014 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.log4j2; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.springframework.boot.logging.LogLevel; +import org.springframework.boot.test.OutputCapture; +import org.springframework.util.StringUtils; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +/** + * Tests for {@link Log4J2LoggingSystem}. + * + * @author Daniel Fullarton + */ +public class Log4J2LoggingSystemTests { + + @Rule + public OutputCapture output = new OutputCapture(); + + private final Log4J2LoggingSystem loggingSystem = new Log4J2LoggingSystem(getClass() + .getClassLoader()); + + private Logger logger; + + @Before + public void setup() { + this.logger = LogManager.getLogger(getClass()); + } + + @After + public void clear() { + System.clearProperty("LOG_FILE"); + System.clearProperty("LOG_PATH"); + System.clearProperty("PID"); + } + + @Test + public void testNonDefaultConfigLocation() throws Exception { + this.loggingSystem.beforeInitialize(); + this.loggingSystem.initialize("classpath:log4j2-nondefault.xml"); + this.logger.info("Hello world"); + String output = this.output.toString().trim(); + assertTrue("Wrong output:\n" + output, output.contains("Hello world")); + assertTrue("Wrong output:\n" + output, output.contains("/tmp/spring.log")); + } + + @Test(expected = IllegalStateException.class) + public void testNonexistentConfigLocation() throws Exception { + this.loggingSystem.beforeInitialize(); + this.loggingSystem.initialize("classpath:log4j2-nonexistent.xml"); + } + + @Test(expected = IllegalArgumentException.class) + public void testNullConfigLocation() throws Exception { + this.loggingSystem.beforeInitialize(); + this.loggingSystem.initialize(null); + } + + @Test + public void setLevel() throws Exception { + this.loggingSystem.beforeInitialize(); + this.loggingSystem.initialize(); + this.logger.debug("Hello"); + this.loggingSystem.setLogLevel("org.springframework.boot", LogLevel.DEBUG); + this.logger.debug("Hello"); + assertThat(StringUtils.countOccurrencesOf(this.output.toString(), "Hello"), + equalTo(1)); + } + +} diff --git a/spring-boot/src/test/resources/log4j2-nondefault.xml b/spring-boot/src/test/resources/log4j2-nondefault.xml new file mode 100644 index 00000000000..53bf99dd3c9 --- /dev/null +++ b/spring-boot/src/test/resources/log4j2-nondefault.xml @@ -0,0 +1,19 @@ + + + + ???? + /tmp + ${sys:LOG_PATH}/spring.log + ${sys:LOG_FILE} %d{yyyy-MM-dd HH:mm:ss.SSS}] service%X{context} - ${sys:PID} %5p [%t] --- %c{1}: %m%n + + + + + + + + + + + + \ No newline at end of file