Remove default JUL handler to prevent duplicate console logging

By default, JUL configures a single root handler. That handler is a
ConsoleHandler. Previously, we removed all root handlers from JUL but
this is problematic in environments where other handlers are
registered with JUL and those handlers need to be retained.
0679d436 attempted to fix the problem by leaving the root handlers in
place and only adding and removing the bridge handler. This resulted
in log output from Tomcat (and anything else that uses JUL) being
duplicated.

This commit makes another attempt at tackling the problem. It attempts
to detect JUL's default configuration (a single root handler that's a
ConsoleHandler) and only removes the handler if it appears to be from
the default configuration. For environments where default JUL
configuration is being used, this will prevent duplicate logging and
for environments where custom JUL configuration is being used, this
will prevent that configuration from being undone.

Closes gh-8933
pull/11834/head
Andy Wilkinson 7 years ago
parent c2a2999799
commit 844782b20b

@ -16,6 +16,11 @@
package org.springframework.boot.logging; package org.springframework.boot.logging;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import org.slf4j.bridge.SLF4JBridgeHandler; import org.slf4j.bridge.SLF4JBridgeHandler;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -74,6 +79,7 @@ public abstract class Slf4JLoggingSystem extends AbstractLoggingSystem {
private void removeJdkLoggingBridgeHandler() { private void removeJdkLoggingBridgeHandler() {
try { try {
if (isBridgeHandlerAvailable()) { if (isBridgeHandlerAvailable()) {
removeDefaultRootHandler();
SLF4JBridgeHandler.uninstall(); SLF4JBridgeHandler.uninstall();
} }
} }
@ -82,4 +88,17 @@ public abstract class Slf4JLoggingSystem extends AbstractLoggingSystem {
} }
} }
private void removeDefaultRootHandler() {
try {
Logger rootLogger = LogManager.getLogManager().getLogger("");
Handler[] handlers = rootLogger.getHandlers();
if (handlers.length == 1 && handlers[0] instanceof ConsoleHandler) {
rootLogger.removeHandler(handlers[0]);
}
}
catch (Throwable ex) {
// Ignore and continue
}
}
} }

Loading…
Cancel
Save