Commit bead2394 authored by Stephane Nicoll's avatar Stephane Nicoll

Remove support for Log4j

Apache Log4j 1.x is EOL and has now been replaced by log4j 2. This commit
removes the deprecated support for Log4j 1.x

See gh-4905
parent 7b9cd20e
......@@ -110,7 +110,6 @@
<jstl.version>1.2</jstl.version>
<junit.version>4.12</junit.version>
<liquibase.version>3.4.2</liquibase.version>
<log4j.version>1.2.17</log4j.version>
<log4j2.version>2.4.1</log4j2.version>
<logback.version>1.1.3</logback.version>
<mariadb.version>1.2.3</mariadb.version>
......@@ -362,11 +361,6 @@
<artifactId>spring-boot-starter-undertow</artifactId>
<version>1.4.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.4.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
......@@ -854,11 +848,6 @@
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
......
......@@ -177,11 +177,6 @@
<artifactId>junit</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
......
......@@ -1313,12 +1313,11 @@ You also need to add `logging.file` to your `application.properties`:
[[howto-configure-log4j-for-logging]]
=== Configure Log4j for logging
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.
Spring Boot supports http://logging.apache.org/log4j/2.x[Log4j 2] for logging
configuration if it is on the classpath. If you are using the starter poms for
assembling dependencies that means you have to exclude Logback and then include log4j 2
instead. If you aren't using the starter poms then you need to provide `commons-logging`
(at least) in addition to Log4j 2.
The simplest path is probably through the starter poms, even though it requires some
jiggling with excludes, .e.g. in Maven:
......@@ -1341,17 +1340,14 @@ jiggling with excludes, .e.g. in Maven:
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
----
To use Log4j 2, simply depend on `spring-boot-starter-log4j2` rather than
`spring-boot-starter-log4j`.
NOTE: The use of one of the Log4j starters gathers together the dependencies for
common logging requirements (e.g. including having Tomcat use `java.util.logging` but
configuring the output using Log4j or Log4j 2). See the Actuator Log4j or Log4j 2
samples for more detail and to see it in action.
NOTE: The use of the Log4j starters gathers together the dependencies for common logging
requirements (e.g. including having Tomcat use `java.util.logging` but configuring the
output using Log4j 2). See the Actuator Log4j 2 samples for more detail and to see it in
action.
......
......@@ -983,9 +983,9 @@ Spring Boot uses http://commons.apache.org/logging[Commons Logging] for all inte
logging, but leaves the underlying log implementation open. Default configurations are
provided for
http://docs.oracle.com/javase/7/docs/api/java/util/logging/package-summary.html[Java Util Logging],
http://logging.apache.org/log4j/[Log4J], http://logging.apache.org/log4j/2.x/[Log4J2] and
http://logback.qos.ch/[Logback]. In each case loggers are pre-configured to use console
output with optional file output also available.
http://logging.apache.org/log4j/2.x/[Log4J2] andhttp://logback.qos.ch/[Logback]. In each
case loggers are pre-configured to use console output with optional file output also
available.
By default, If you use the '`Starter POMs`', Logback will be used for logging. Appropriate
Logback routing is also included to ensure that dependent libraries that use
......@@ -1182,9 +1182,6 @@ Depending on your logging system, the following files will be loaded:
|Logback
|`logback-spring.xml`, `logback-spring.groovy`, `logback.xml` or `logback.groovy`
|Log4j
|`log4j-spring.properties`, `log4j-spring.xml`, `log4j.properties` or `log4j.xml`
|Log4j2
|`log4j2-spring.xml` or `log4j2.xml`
......
......@@ -517,8 +517,8 @@ swap specific technical facets.
|`spring-boot-starter-jetty`
|Imports the Jetty HTTP engine (to be used as an alternative to Tomcat).
|`spring-boot-starter-log4j`
|Support the Log4J logging framework.
|`spring-boot-starter-log4j2`
|Support the Log4J 2 logging framework.
|`spring-boot-starter-logging`
|Import Spring Boot's default logging framework (Logback).
......
......@@ -42,6 +42,11 @@
<dependencies>
<!-- Additional Dependencies the consumers of spring-boot-dependencies
will generally not need -->
<dependency> <!-- deprecated but recent version required by 3rd party libs -->
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
......
......@@ -14,8 +14,8 @@
-- A web UI example with production features
* link:spring-boot-sample-actuator-noweb[spring-boot-sample-actuator-noweb]
-- A production features sample with no web application
* link:spring-boot-sample-actuator-log4j[spring-boot-sample-actuator-log4j]
-- A production features sample using log4j for logging (instead of logback)
* link:spring-boot-sample-actuator-log4j2[spring-boot-sample-actuator-log4j2]
-- A production features sample using log4j 2 for logging (instead of logback)
* link:spring-boot-sample-cache[spring-boot-sample-cache]
-- A web sample that uses Spring's cache abstraction
* link:spring-boot-sample-web-ui[spring-boot-sample-web-ui]
......
......@@ -24,7 +24,6 @@
<module>spring-boot-sample-ant</module>
<module>spring-boot-sample-activemq</module>
<module>spring-boot-sample-actuator</module>
<module>spring-boot-sample-actuator-log4j</module>
<module>spring-boot-sample-actuator-log4j2</module>
<module>spring-boot-sample-actuator-noweb</module>
<module>spring-boot-sample-actuator-ui</module>
......
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<!-- Your own application should inherit from spring-boot-starter-parent -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-samples</artifactId>
<version>1.4.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-actuator-log4j</artifactId>
<name>Spring Boot Actuator Log4j Sample</name>
<description>Spring Boot Actuator Log4j Sample</description>
<url>http://projects.spring.io/spring-boot/</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
/*
* 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.log4j;
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();
}
}
/*
* 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.log4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SampleActuatorLog4JApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleActuatorLog4JApplication.class, args);
}
}
/*
* 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.log4j;
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<String, String> helloWorld() {
return Collections.singletonMap("message",
this.helloWorldService.getHelloMessage());
}
@RequestMapping("/foo")
@ResponseBody
public String foo() {
throw new IllegalArgumentException("Server error");
}
}
/*
* 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.log4j;
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;
}
}
#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: Phil
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
log4j.rootCategory=INFO, CONSOLE
PID=????
LOG_PATTERN=[%d{yyyy-MM-dd HH:mm:ss.SSS}] log4j%X{context} - ${PID} %5p [%t] --- %c{1}: %m%n
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=${LOG_PATTERN}
log4j.category.org.hibernate.validator.internal.util.Version=WARN
log4j.category.org.apache.coyote.http11.Http11NioProtocol=WARN
log4j.category.org.apache.tomcat.util.net.NioSelectorPool=WARN
log4j.category.org.apache.catalina.startup.DigesterFactory=ERROR
/*
* 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.log4j;
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.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* Basic integration tests for service demo application.
*
* @author Dave Syer
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(SampleActuatorLog4JApplication.class)
@WebIntegrationTest(randomPort = true)
@DirtiesContext
public class SampleActuatorApplicationTests {
@Value("${local.server.port}")
private int port;
@Test
public void testHome() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = new TestRestTemplate()
.getForEntity("http://localhost:" + this.port, Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertEquals("Hello Phil", body.get("message"));
}
@Test
public void testHealth() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = new TestRestTemplate()
.getForEntity("http://localhost:" + this.port + "/health", Map.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
@SuppressWarnings("unchecked")
Map<String, Object> body = entity.getBody();
assertNotNull(body.get("diskSpace"));
}
}
log4j.rootCategory=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.category.org.springframework.web=DEBUG
......@@ -46,7 +46,6 @@
<module>spring-boot-starter-jta-atomikos</module>
<module>spring-boot-starter-jta-bitronix</module>
<module>spring-boot-starter-logging</module>
<module>spring-boot-starter-log4j</module>
<module>spring-boot-starter-log4j2</module>
<module>spring-boot-starter-mail</module>
<module>spring-boot-starter-mobile</module>
......
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starters</artifactId>
<version>1.4.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-starter-log4j</artifactId>
<name>Spring Boot Log4J Starter</name>
<description>Spring Boot Log4J Starter</description>
<url>http://projects.spring.io/spring-boot/</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
</dependencies>
</project>
......@@ -20,7 +20,7 @@
<goal>repackage</goal>
</goals>
<configuration>
<excludeGroupIds>log4j</excludeGroupIds>
<excludeGroupIds>org.apache.logging.log4j</excludeGroupIds>
</configuration>
</execution>
</executions>
......@@ -52,9 +52,9 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.4.1</version>
</dependency>
</dependencies>
</project>
......@@ -22,6 +22,6 @@ new Verify.JarArchiveVerification(f, Verify.SAMPLE_APP) {
@Override
protected void verifyZipEntries(Verify.ArchiveVerifier verifier) throws Exception {
super.verifyZipEntries(verifier)
verifier.assertHasNoEntryNameStartingWith("lib/log4j-1.2.17.jar")
verifier.assertHasNoEntryNameStartingWith("lib/log4j-api-2.4.1.jar")
}
}.verify();
......@@ -52,9 +52,9 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>@log4j.version@</version>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.4.1</version>
<scope>test</scope>
</dependency>
</dependencies>
......
......@@ -22,6 +22,6 @@ new Verify.JarArchiveVerification(f, Verify.SAMPLE_APP) {
@Override
protected void verifyZipEntries(Verify.ArchiveVerifier verifier) throws Exception {
super.verifyZipEntries(verifier)
verifier.assertHasNoEntryNameStartingWith("lib/log4j-1.2.17.jar")
verifier.assertHasNoEntryNameStartingWith("lib/log4j-api-2.4.1.jar")
}
}.verify();
......@@ -57,9 +57,9 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>@log4j.version@</version>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>@log4j2.version@</version>
</dependency>
</dependencies>
</project>
......@@ -23,8 +23,8 @@
<configuration>
<excludes>
<exclude>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclude>
</excludes>
<excludeGroupIds>javax.servlet</excludeGroupIds>
......@@ -36,9 +36,9 @@
</build>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>@log4j.version@</version>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>@log4j2.version@</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
......
......@@ -84,11 +84,6 @@
<artifactId>junit</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
......
......@@ -45,8 +45,6 @@ public abstract class LoggingSystem {
"org.springframework.boot.logging.logback.LogbackLoggingSystem");
systems.put("org.apache.logging.log4j.core.impl.Log4jContextFactory",
"org.springframework.boot.logging.log4j2.Log4J2LoggingSystem");
systems.put("org.apache.log4j.PropertyConfigurator",
"org.springframework.boot.logging.log4j.Log4JLoggingSystem");
systems.put("java.util.logging.LogManager",
"org.springframework.boot.logging.java.JavaLoggingSystem");
SYSTEMS = Collections.unmodifiableMap(systems);
......@@ -96,8 +94,7 @@ public abstract class LoggingSystem {
public abstract void setLogLevel(String loggerName, LogLevel level);
/**
* Detect and return the logging system in use. Supports Logback, Log4J, Log4J2 and
* Java Logging.
* Detect and return the logging system in use. Supports Logback and Java Logging.
* @param classLoader the classloader
* @return The logging system
*/
......
/*
* 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.log4j;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Level;
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;
import org.springframework.util.Log4jConfigurer;
import org.springframework.util.StringUtils;
/**
* {@link LoggingSystem} for <a href="http://logging.apache.org/log4j/1.2">Log4j</a>.
*
* @author Phillip Webb
* @author Dave Syer
* @author Andy Wilkinson
* @deprecated in Spring Boot 1.3 in favor of Apache Log4j 2 (following Apache's EOL
* declaration for log4j 1.x)
*/
@Deprecated
public class Log4JLoggingSystem extends Slf4JLoggingSystem {
private static final Map<LogLevel, Level> LEVELS;
static {
Map<LogLevel, Level> levels = new HashMap<LogLevel, Level>();
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.FATAL);
levels.put(LogLevel.OFF, Level.OFF);
LEVELS = Collections.unmodifiableMap(levels);
}
public Log4JLoggingSystem(ClassLoader classLoader) {
super(classLoader);
}
@Override
protected String[] getStandardConfigLocations() {
return new String[] { "log4j.xml", "log4j.properties" };
}
@Override
public void beforeInitialize() {
super.beforeInitialize();
LogManager.getRootLogger().setLevel(Level.FATAL);
}
@Override
protected void loadDefaults(LoggingInitializationContext initializationContext,
LogFile logFile) {
if (logFile != null) {
loadConfiguration(getPackagedConfigFile("log4j-file.properties"), logFile);
}
else {
loadConfiguration(getPackagedConfigFile("log4j.properties"), logFile);
}
}
@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) {
logFile.applyToSystemProperties();
}
try {
Log4jConfigurer.initLogging(location);
}
catch (Exception ex) {
throw new IllegalStateException(
"Could not initialize Log4J logging from " + location, ex);
}
}
@Override
protected void reinitialize(LoggingInitializationContext initializationContext) {
loadConfiguration(getSelfInitializationConfig(), null);
}
@Override
public void setLogLevel(String loggerName, LogLevel level) {
Logger logger = (StringUtils.hasLength(loggerName)
? LogManager.getLogger(loggerName) : LogManager.getRootLogger());
logger.setLevel(LEVELS.get(level));
}
@Override
public Runnable getShutdownHandler() {
return new ShutdownHandler();
}
private static final class ShutdownHandler implements Runnable {
@Override
public void run() {
LogManager.shutdown();
}
}
}
/*
* 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 logging library.
*/
package org.springframework.boot.logging.log4j;
log4j.rootCategory=INFO, CONSOLE, FILE
PID=????
LOG_PATH=${java.io.tmpdir}
LOG_FILE=${LOG_PATH}/spring.log
LOG_LEVEL_PATTERN=%5p
LOG_PATTERN=[%d{yyyy-MM-dd HH:mm:ss.SSS}] boot%X{context} - ${PID} ${LOG_LEVEL_PATTERN} [%t] --- %c{1}: %m%n
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=${LOG_PATTERN}
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File=${LOG_FILE}
log4j.appender.FILE.MaxFileSize=10MB
log4j.appender.FILE.layout = org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=${LOG_PATTERN}
log4j.category.org.apache.catalina.startup.DigesterFactory=ERROR
log4j.category.org.apache.catalina.util.LifecycleBase=ERROR
log4j.category.org.apache.coyote.http11.Http11NioProtocol=WARN
log4j.category.org.apache.sshd.common.util.SecurityUtils
log4j.category.org.apache.tomcat.util.net.NioSelectorPool=WARN
log4j.category.org.crsh.plugin=WARN
log4j.category.org.crsh.ssh=WARN
log4j.category.org.eclipse.jetty.util.component.AbstractLifeCycle=ERROR
log4j.category.org.hibernate.validator.internal.util.Version=WARN
log4j.category.org.springframework.boot.actuate.autoconfigure.CrshAutoConfiguration=WARN
log4j.category.org.springframework.boot.actuate.endpoint.jmx=WARN
log4j.category.org.thymeleaf=WARN
log4j.rootCategory=INFO, CONSOLE
PID=????
LOG_LEVEL_PATTERN=%5p
LOG_PATTERN=[%d{yyyy-MM-dd HH:mm:ss.SSS}] boot%X{context} - ${PID} ${LOG_LEVEL_PATTERN} [%t] --- %c{1}: %m%n
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=${LOG_PATTERN}
log4j.category.org.apache.catalina.startup.DigesterFactory=ERROR
log4j.category.org.apache.catalina.util.LifecycleBase=ERROR
log4j.category.org.apache.coyote.http11.Http11NioProtocol=WARN
log4j.category.org.apache.sshd.common.util.SecurityUtils
log4j.category.org.apache.tomcat.util.net.NioSelectorPool=WARN
log4j.category.org.crsh.plugin=WARN
log4j.category.org.crsh.ssh=WARN
log4j.category.org.eclipse.jetty.util.component.AbstractLifeCycle=ERROR
log4j.category.org.hibernate.validator.internal.util.Version=WARN
log4j.category.org.springframework.boot.actuate.autoconfigure.CrshAutoConfiguration=WARN
log4j.category.org.springframework.boot.actuate.endpoint.jmx=WARN
log4j.category.org.thymeleaf=WARN
/*
* 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.log4j;
import java.io.File;
import java.util.logging.Handler;
import java.util.logging.LogManager;
import org.apache.commons.logging.impl.Log4JLogger;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.bridge.SLF4JBridgeHandler;
import org.springframework.boot.logging.AbstractLoggingSystemTests;
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.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
* Tests for {@link Log4JLoggingSystem}.
*
* @author Phillip Webb
* @author Andy Wilkinson
*/
@SuppressWarnings("deprecation")
public class Log4JLoggingSystemTests extends AbstractLoggingSystemTests {
@Rule
public OutputCapture output = new OutputCapture();
private final Log4JLoggingSystem loggingSystem = new Log4JLoggingSystem(
getClass().getClassLoader());
private Log4JLogger logger;
@Before
public void setup() {
this.logger = new Log4JLogger(getClass().getName());
}
@Override
@After
public void clear() {
this.loggingSystem.cleanUp();
}
@Test
public void noFile() throws Exception {
this.loggingSystem.beforeInitialize();
this.logger.info("Hidden");
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"));
assertFalse("Output not hidden:\n" + output, output.contains("Hidden"));
assertFalse(new File(tmpDir() + "/spring.log").exists());
}
@Test
public void withFile() throws Exception {
this.loggingSystem.beforeInitialize();
this.logger.info("Hidden");
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"));
assertFalse("Output not hidden:\n" + output, output.contains("Hidden"));
assertTrue(new File(tmpDir() + "/spring.log").exists());
}
@Test
public void testNonDefaultConfigLocation() throws Exception {
this.loggingSystem.beforeInitialize();
this.loggingSystem.initialize(null, "classpath:log4j-nondefault.properties",
getLogFile(null, tmpDir()));
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(tmpDir() + "/spring.log"));
assertFalse(new File(tmpDir() + "/tmp.log").exists());
}
@Test(expected = IllegalStateException.class)
public void testNonexistentConfigLocation() throws Exception {
this.loggingSystem.beforeInitialize();
this.loggingSystem.initialize(null, "classpath:log4j-nonexistent.xml", null);
}
@Test
public void setLevel() throws Exception {
this.loggingSystem.beforeInitialize();
this.loggingSystem.initialize(null, null, null);
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));
}
@Test
@Ignore("Fails on Bamboo")
public void loggingThatUsesJulIsCaptured() {
this.loggingSystem.beforeInitialize();
this.loggingSystem.initialize(null, null, null);
java.util.logging.Logger julLogger = java.util.logging.Logger
.getLogger(getClass().getName());
julLogger.severe("Hello world");
String output = this.output.toString().trim();
assertTrue("Wrong output:\n" + output, output.contains("Hello world"));
}
@Test
public void bridgeHandlerLifecycle() {
assertFalse(bridgeHandlerInstalled());
this.loggingSystem.beforeInitialize();
assertTrue(bridgeHandlerInstalled());
this.loggingSystem.cleanUp();
assertFalse(bridgeHandlerInstalled());
}
private boolean bridgeHandlerInstalled() {
java.util.logging.Logger rootLogger = LogManager.getLogManager().getLogger("");
Handler[] handlers = rootLogger.getHandlers();
for (Handler handler : handlers) {
if (handler instanceof SLF4JBridgeHandler) {
return true;
}
}
return false;
}
}
log4j.reset=true
log4j.rootCategory=INFO, CONSOLE
PID=????
LOG_PATTERN=${LOG_FILE} %d{yyyy-MM-dd HH:mm:ss.SSS}] service%X{context} - ${PID} %5p [%t] --- %c{1}: %m%n
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=${LOG_PATTERN}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment