Commit c3479727 authored by Andy Wilkinson's avatar Andy Wilkinson

Install SLF4JBridgeHandler when Log4J2LoggingSystem is initialized

Previously, Log4J2LoggingSystem did not install SLF4JBridgeHandler.
SLF4JBridgeHandler is used to route logging calls made using
java.util.logging into SLF4J. This resulted in entries being written
to System.err instead.

This commit updates Log4J2LoggingSystem to register the bridge handler
thereby ensuring the logging that originates into java.util.logging is
routed into SLF4J. This change has been made by extracting a new
abstract superclass that performs the registration. This super class is
extended by all SLF4J-based LoggingSystem implementations.

Fixes gh-1737
parent 6b1f76ad
/*
* 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;
import org.slf4j.bridge.SLF4JBridgeHandler;
import org.springframework.util.ClassUtils;
/**
* Abstract base class for {@link LoggingSystem} implementations that utilise SLF4J.
*
* @author Andy Wilkinson
* @since 1.2.0
*/
public abstract class Slf4JLoggingSystem extends AbstractLoggingSystem {
public Slf4JLoggingSystem(ClassLoader classLoader, String... paths) {
super(classLoader, paths);
}
@Override
public void beforeInitialize() {
super.beforeInitialize();
try {
if (ClassUtils.isPresent("org.slf4j.bridge.SLF4JBridgeHandler",
getClassLoader())) {
try {
SLF4JBridgeHandler.removeHandlersForRootLogger();
}
catch (NoSuchMethodError ex) {
// Method missing in older versions of SLF4J like in JBoss AS 7.1
SLF4JBridgeHandler.uninstall();
}
SLF4JBridgeHandler.install();
}
}
catch (Throwable ex) {
// Ignore. No java.util.logging bridge is installed.
}
}
}
...@@ -23,12 +23,10 @@ import java.util.Map; ...@@ -23,12 +23,10 @@ import java.util.Map;
import org.apache.log4j.Level; import org.apache.log4j.Level;
import org.apache.log4j.LogManager; import org.apache.log4j.LogManager;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.slf4j.bridge.SLF4JBridgeHandler;
import org.springframework.boot.logging.AbstractLoggingSystem;
import org.springframework.boot.logging.LogLevel; import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggingSystem; import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.logging.Slf4JLoggingSystem;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.Log4jConfigurer; import org.springframework.util.Log4jConfigurer;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
...@@ -38,7 +36,7 @@ import org.springframework.util.StringUtils; ...@@ -38,7 +36,7 @@ import org.springframework.util.StringUtils;
* @author Phillip Webb * @author Phillip Webb
* @author Dave Syer * @author Dave Syer
*/ */
public class Log4JLoggingSystem extends AbstractLoggingSystem { public class Log4JLoggingSystem extends Slf4JLoggingSystem {
private static final Map<LogLevel, Level> LEVELS; private static final Map<LogLevel, Level> LEVELS;
static { static {
...@@ -57,15 +55,6 @@ public class Log4JLoggingSystem extends AbstractLoggingSystem { ...@@ -57,15 +55,6 @@ public class Log4JLoggingSystem extends AbstractLoggingSystem {
super(classLoader, "log4j.xml", "log4j.properties"); super(classLoader, "log4j.xml", "log4j.properties");
} }
@Override
public void beforeInitialize() {
super.beforeInitialize();
if (ClassUtils.isPresent("org.slf4j.bridge.SLF4JBridgeHandler", getClassLoader())) {
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
}
}
@Override @Override
public void initialize(String configLocation) { public void initialize(String configLocation) {
Assert.notNull(configLocation, "ConfigLocation must not be null"); Assert.notNull(configLocation, "ConfigLocation must not be null");
......
...@@ -27,9 +27,9 @@ import org.apache.logging.log4j.core.LoggerContext; ...@@ -27,9 +27,9 @@ import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationFactory; import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.config.ConfigurationSource; 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.LogLevel;
import org.springframework.boot.logging.LoggingSystem; import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.logging.Slf4JLoggingSystem;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ResourceUtils; import org.springframework.util.ResourceUtils;
import org.springframework.util.SystemPropertyUtils; import org.springframework.util.SystemPropertyUtils;
...@@ -38,9 +38,10 @@ import org.springframework.util.SystemPropertyUtils; ...@@ -38,9 +38,10 @@ import org.springframework.util.SystemPropertyUtils;
* {@link LoggingSystem} for <a href="http://logging.apache.org/log4j/2.x/">Log4j 2</a>. * {@link LoggingSystem} for <a href="http://logging.apache.org/log4j/2.x/">Log4j 2</a>.
* *
* @author Daniel Fullarton * @author Daniel Fullarton
* @author Andy Wilkinson
* @since 1.2.0 * @since 1.2.0
*/ */
public class Log4J2LoggingSystem extends AbstractLoggingSystem { public class Log4J2LoggingSystem extends Slf4JLoggingSystem {
private static final Map<LogLevel, Level> LEVELS; private static final Map<LogLevel, Level> LEVELS;
static { static {
......
...@@ -23,13 +23,11 @@ import java.util.Map; ...@@ -23,13 +23,11 @@ import java.util.Map;
import org.slf4j.ILoggerFactory; import org.slf4j.ILoggerFactory;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.bridge.SLF4JBridgeHandler;
import org.slf4j.impl.StaticLoggerBinder; import org.slf4j.impl.StaticLoggerBinder;
import org.springframework.boot.logging.AbstractLoggingSystem;
import org.springframework.boot.logging.LogLevel; import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggingSystem; import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.logging.Slf4JLoggingSystem;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ResourceUtils; import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.util.SystemPropertyUtils; import org.springframework.util.SystemPropertyUtils;
...@@ -43,8 +41,9 @@ import ch.qos.logback.classic.util.ContextInitializer; ...@@ -43,8 +41,9 @@ import ch.qos.logback.classic.util.ContextInitializer;
* *
* @author Phillip Webb * @author Phillip Webb
* @author Dave Syer * @author Dave Syer
* @author Andy Wilkinson
*/ */
public class LogbackLoggingSystem extends AbstractLoggingSystem { public class LogbackLoggingSystem extends Slf4JLoggingSystem {
private static final Map<LogLevel, Level> LEVELS; private static final Map<LogLevel, Level> LEVELS;
static { static {
...@@ -64,27 +63,6 @@ public class LogbackLoggingSystem extends AbstractLoggingSystem { ...@@ -64,27 +63,6 @@ public class LogbackLoggingSystem extends AbstractLoggingSystem {
"logback.xml"); "logback.xml");
} }
@Override
public void beforeInitialize() {
super.beforeInitialize();
try {
if (ClassUtils.isPresent("org.slf4j.bridge.SLF4JBridgeHandler",
getClassLoader())) {
try {
SLF4JBridgeHandler.removeHandlersForRootLogger();
}
catch (NoSuchMethodError ex) {
// Method missing in older versions of SLF4J like in JBoss AS 7.1
SLF4JBridgeHandler.uninstall();
}
SLF4JBridgeHandler.install();
}
}
catch (Throwable ex) {
// Ignore. No java.util.logging bridge is installed.
}
}
@Override @Override
public void initialize(String configLocation) { public void initialize(String configLocation) {
Assert.notNull(configLocation, "ConfigLocation must not be null"); Assert.notNull(configLocation, "ConfigLocation must not be null");
......
...@@ -89,4 +89,15 @@ public class Log4JLoggingSystemTests { ...@@ -89,4 +89,15 @@ public class Log4JLoggingSystemTests {
equalTo(1)); equalTo(1));
} }
@Test
public void loggingThatUsesJulIsCaptured() {
this.loggingSystem.beforeInitialize();
this.loggingSystem.initialize();
java.util.logging.Logger julLogger = java.util.logging.Logger
.getLogger(getClass().getName());
julLogger.info("Hello world");
String output = this.output.toString().trim();
assertTrue("Wrong output:\n" + output, output.contains("Hello world"));
}
} }
...@@ -90,4 +90,15 @@ public class Log4J2LoggingSystemTests { ...@@ -90,4 +90,15 @@ public class Log4J2LoggingSystemTests {
equalTo(1)); equalTo(1));
} }
@Test
public void loggingThatUsesJulIsCaptured() {
this.loggingSystem.beforeInitialize();
this.loggingSystem.initialize();
java.util.logging.Logger julLogger = java.util.logging.Logger
.getLogger(getClass().getName());
julLogger.info("Hello world");
String output = this.output.toString().trim();
assertTrue("Wrong output:\n" + output, output.contains("Hello world"));
}
} }
...@@ -119,4 +119,15 @@ public class LogbackLoggingSystemTests { ...@@ -119,4 +119,15 @@ public class LogbackLoggingSystemTests {
equalTo(1)); equalTo(1));
} }
@Test
public void loggingThatUsesJulIsCaptured() {
this.loggingSystem.beforeInitialize();
this.loggingSystem.initialize();
java.util.logging.Logger julLogger = java.util.logging.Logger
.getLogger(getClass().getName());
julLogger.info("Hello world");
String output = this.output.toString().trim();
assertTrue("Wrong output:\n" + output, output.contains("Hello world"));
}
} }
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