diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/Slf4JLoggingSystem.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/Slf4JLoggingSystem.java deleted file mode 100644 index 31a3c7c81f..0000000000 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/Slf4JLoggingSystem.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2012-2019 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; - -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.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * Abstract base class for {@link LoggingSystem} implementations that utilize SLF4J. - * - * @author Andy Wilkinson - * @since 1.2.0 - */ -public abstract class Slf4JLoggingSystem extends AbstractLoggingSystem { - - private static final String BRIDGE_HANDLER = "org.slf4j.bridge.SLF4JBridgeHandler"; - - public Slf4JLoggingSystem(ClassLoader classLoader) { - super(classLoader); - } - - @Override - public void beforeInitialize() { - super.beforeInitialize(); - configureJdkLoggingBridgeHandler(); - } - - @Override - public void cleanUp() { - if (isBridgeHandlerAvailable()) { - removeJdkLoggingBridgeHandler(); - } - } - - @Override - protected void loadConfiguration(LoggingInitializationContext initializationContext, String location, - LogFile logFile) { - Assert.notNull(location, "Location must not be null"); - if (initializationContext != null) { - applySystemProperties(initializationContext.getEnvironment(), logFile); - } - } - - private void configureJdkLoggingBridgeHandler() { - try { - if (isBridgeJulIntoSlf4j()) { - removeJdkLoggingBridgeHandler(); - SLF4JBridgeHandler.install(); - } - } - catch (Throwable ex) { - // Ignore. No java.util.logging bridge is installed. - } - } - - /** - * Return whether bridging JUL into SLF4J or not. - * @return whether bridging JUL into SLF4J or not - * @since 2.0.4 - */ - protected final boolean isBridgeJulIntoSlf4j() { - return isBridgeHandlerAvailable() && isJulUsingASingleConsoleHandlerAtMost(); - } - - protected final boolean isBridgeHandlerAvailable() { - return ClassUtils.isPresent(BRIDGE_HANDLER, getClassLoader()); - } - - protected boolean isJulUsingASingleConsoleHandlerAtMost() { - Logger rootLogger = LogManager.getLogManager().getLogger(""); - Handler[] handlers = rootLogger.getHandlers(); - return handlers.length == 0 || (handlers.length == 1 && handlers[0] instanceof ConsoleHandler); - } - - private void removeJdkLoggingBridgeHandler() { - try { - removeDefaultRootHandler(); - SLF4JBridgeHandler.uninstall(); - } - catch (Throwable ex) { - // Ignore and continue - } - } - - protected 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 - } - } - -} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java index 22155fa271..7ac194c9d0 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.java @@ -25,6 +25,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.logging.ConsoleHandler; import java.util.logging.Handler; import java.util.stream.Collectors; @@ -49,13 +50,13 @@ import org.apache.logging.log4j.message.Message; import org.springframework.boot.context.properties.bind.BindResult; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.boot.logging.AbstractLoggingSystem; import org.springframework.boot.logging.LogFile; import org.springframework.boot.logging.LogLevel; import org.springframework.boot.logging.LoggerConfiguration; import org.springframework.boot.logging.LoggingInitializationContext; import org.springframework.boot.logging.LoggingSystem; import org.springframework.boot.logging.LoggingSystemFactory; -import org.springframework.boot.logging.Slf4JLoggingSystem; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.util.Assert; @@ -73,7 +74,7 @@ import org.springframework.util.StringUtils; * @author Ben Hale * @since 1.2.0 */ -public class Log4J2LoggingSystem extends Slf4JLoggingSystem { +public class Log4J2LoggingSystem extends AbstractLoggingSystem { private static final String FILE_PROTOCOL = "file"; @@ -169,12 +170,11 @@ public class Log4J2LoggingSystem extends Slf4JLoggingSystem { private boolean configureJdkLoggingBridgeHandler() { try { - if (isJulUsingASingleConsoleHandlerAtMost() && !isLog4jLogManagerInstalled()) { - if (isLog4jBridgeHandlerAvailable()) { - removeDefaultRootHandler(); - installLog4jBridgeHandler(); - return true; - } + if (isJulUsingASingleConsoleHandlerAtMost() && !isLog4jLogManagerInstalled() + && isLog4jBridgeHandlerAvailable()) { + removeDefaultRootHandler(); + Log4jBridgeHandler.install(false, null, true); + return true; } } catch (Throwable ex) { @@ -183,6 +183,12 @@ public class Log4J2LoggingSystem extends Slf4JLoggingSystem { return false; } + private boolean isJulUsingASingleConsoleHandlerAtMost() { + java.util.logging.Logger rootLogger = java.util.logging.LogManager.getLogManager().getLogger(""); + Handler[] handlers = rootLogger.getHandlers(); + return handlers.length == 0 || (handlers.length == 1 && handlers[0] instanceof ConsoleHandler); + } + private boolean isLog4jLogManagerInstalled() { final String logManagerClassName = java.util.logging.LogManager.getLogManager().getClass().getName(); return LOG4J_LOG_MANAGER.equals(logManagerClassName); @@ -192,11 +198,8 @@ public class Log4J2LoggingSystem extends Slf4JLoggingSystem { return ClassUtils.isPresent(LOG4J_BRIDGE_HANDLER, getClassLoader()); } - private void installLog4jBridgeHandler() { - Log4jBridgeHandler.install(false, null, true); - } - private void removeLog4jBridgeHandler() { + removeDefaultRootHandler(); java.util.logging.Logger rootLogger = java.util.logging.LogManager.getLogManager().getLogger(""); for (final Handler handler : rootLogger.getHandlers()) { if (handler instanceof Log4jBridgeHandler) { @@ -206,6 +209,19 @@ public class Log4J2LoggingSystem extends Slf4JLoggingSystem { } } + private void removeDefaultRootHandler() { + try { + java.util.logging.Logger rootLogger = java.util.logging.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 + } + } + @Override public void initialize(LoggingInitializationContext initializationContext, String configLocation, LogFile logFile) { LoggerContext loggerContext = getLoggerContext(); @@ -236,7 +252,9 @@ public class Log4J2LoggingSystem extends Slf4JLoggingSystem { @Override protected void loadConfiguration(LoggingInitializationContext initializationContext, String location, LogFile logFile) { - super.loadConfiguration(initializationContext, location, logFile); + if (initializationContext != null) { + applySystemProperties(initializationContext.getEnvironment(), logFile); + } loadConfiguration(location, logFile, getOverrides(initializationContext)); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/LogbackLoggingSystem.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/LogbackLoggingSystem.java index 6a73a973ac..0fde1b977c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/LogbackLoggingSystem.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/logging/logback/LogbackLoggingSystem.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 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. @@ -22,6 +22,7 @@ import java.security.ProtectionDomain; import java.util.ArrayList; import java.util.List; import java.util.Set; +import java.util.logging.ConsoleHandler; import java.util.logging.Handler; import java.util.logging.LogManager; @@ -42,6 +43,7 @@ import org.slf4j.Marker; import org.slf4j.bridge.SLF4JBridgeHandler; import org.slf4j.impl.StaticLoggerBinder; +import org.springframework.boot.logging.AbstractLoggingSystem; import org.springframework.boot.logging.LogFile; import org.springframework.boot.logging.LogLevel; import org.springframework.boot.logging.LoggerConfiguration; @@ -49,7 +51,6 @@ import org.springframework.boot.logging.LoggingInitializationContext; import org.springframework.boot.logging.LoggingSystem; import org.springframework.boot.logging.LoggingSystemFactory; import org.springframework.boot.logging.LoggingSystemProperties; -import org.springframework.boot.logging.Slf4JLoggingSystem; import org.springframework.core.Ordered; import org.springframework.core.SpringProperties; import org.springframework.core.annotation.Order; @@ -69,7 +70,9 @@ import org.springframework.util.StringUtils; * @author Ben Hale * @since 1.0.0 */ -public class LogbackLoggingSystem extends Slf4JLoggingSystem { +public class LogbackLoggingSystem extends AbstractLoggingSystem { + + private static final String BRIDGE_HANDLER = "org.slf4j.bridge.SLF4JBridgeHandler"; // Static final field to facilitate code removal by Graal private static final boolean XML_ENABLED = !SpringProperties.getFlag("spring.xml.ignore"); @@ -120,9 +123,59 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem { return; } super.beforeInitialize(); + configureJdkLoggingBridgeHandler(); loggerContext.getTurboFilterList().add(FILTER); } + private void configureJdkLoggingBridgeHandler() { + try { + if (isBridgeJulIntoSlf4j()) { + removeJdkLoggingBridgeHandler(); + SLF4JBridgeHandler.install(); + } + } + catch (Throwable ex) { + // Ignore. No java.util.logging bridge is installed. + } + } + + private boolean isBridgeJulIntoSlf4j() { + return isBridgeHandlerAvailable() && isJulUsingASingleConsoleHandlerAtMost(); + } + + private boolean isBridgeHandlerAvailable() { + return ClassUtils.isPresent(BRIDGE_HANDLER, getClassLoader()); + } + + private boolean isJulUsingASingleConsoleHandlerAtMost() { + java.util.logging.Logger rootLogger = LogManager.getLogManager().getLogger(""); + Handler[] handlers = rootLogger.getHandlers(); + return handlers.length == 0 || (handlers.length == 1 && handlers[0] instanceof ConsoleHandler); + } + + private void removeJdkLoggingBridgeHandler() { + try { + removeDefaultRootHandler(); + SLF4JBridgeHandler.uninstall(); + } + catch (Throwable ex) { + // Ignore and continue + } + } + + private void removeDefaultRootHandler() { + try { + java.util.logging.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 + } + } + @Override public void initialize(LoggingInitializationContext initializationContext, String configLocation, LogFile logFile) { LoggerContext loggerContext = getLoggerContext(); @@ -158,7 +211,9 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem { @Override protected void loadConfiguration(LoggingInitializationContext initializationContext, String location, LogFile logFile) { - super.loadConfiguration(initializationContext, location, logFile); + if (initializationContext != null) { + applySystemProperties(initializationContext.getEnvironment(), logFile); + } LoggerContext loggerContext = getLoggerContext(); stopAndReset(loggerContext); try { @@ -221,6 +276,9 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem { LoggerContext context = getLoggerContext(); markAsUninitialized(context); super.cleanUp(); + if (isBridgeHandlerAvailable()) { + removeJdkLoggingBridgeHandler(); + } context.getStatusManager().clear(); context.getTurboFilterList().remove(FILTER); }