When Logback's in use, route JBoss Logging straight into SLF4J

Prior to this change, when using spring-boot-starter-logging, JBoss
Logging would route like this:

JBoss Logging -> Log4j2 API -> SLF4J -> Logback

This is inefficient as there's no need for it to go via the Log4j2
API.

This commit updates the Logback logging system to configure a system
property that controls JBoss's routing. With this change in place,
JBoss Logging will route like this:

JBoss Logging -> SLF4J -> Logback

Closes gh-33155
This commit is contained in:
Andy Wilkinson 2022-11-14 18:03:29 +00:00
parent 9e1c4f775e
commit b5bdee24c2
2 changed files with 33 additions and 0 deletions

View File

@ -20,6 +20,7 @@ import java.nio.charset.Charset;
import java.util.function.BiConsumer;
import ch.qos.logback.core.util.FileSize;
import org.flywaydb.core.internal.util.ClassUtils;
import org.springframework.boot.logging.LogFile;
import org.springframework.boot.logging.LoggingSystemProperties;
@ -37,6 +38,9 @@ import org.springframework.util.unit.DataSize;
*/
public class LogbackLoggingSystemProperties extends LoggingSystemProperties {
private static final boolean JBOSS_LOGGING_PRESENT = ClassUtils.isPresent("org.jboss.logging.Logger",
LogbackLoggingSystemProperties.class.getClassLoader());
/**
* The name of the System property that contains the rolled-over log file name
* pattern.
@ -85,6 +89,17 @@ public class LogbackLoggingSystemProperties extends LoggingSystemProperties {
@Override
protected void apply(LogFile logFile, PropertyResolver resolver) {
super.apply(logFile, resolver);
applyJBossLoggingProperties();
applyRollingPolicyProperties(resolver);
}
private void applyJBossLoggingProperties() {
if (JBOSS_LOGGING_PRESENT) {
setSystemProperty("org.jboss.logging.provider", "slf4j");
}
}
private void applyRollingPolicyProperties(PropertyResolver resolver) {
applyRollingPolicy(resolver, ROLLINGPOLICY_FILE_NAME_PATTERN, "logging.logback.rollingpolicy.file-name-pattern",
"logging.pattern.rolling-file-name");
applyRollingPolicy(resolver, ROLLINGPOLICY_CLEAN_HISTORY_ON_START,

View File

@ -55,6 +55,7 @@ import org.springframework.boot.logging.LoggerConfiguration;
import org.springframework.boot.logging.LoggingInitializationContext;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.logging.LoggingSystemProperties;
import org.springframework.boot.testsupport.classpath.ClassPathOverrides;
import org.springframework.boot.testsupport.system.CapturedOutput;
import org.springframework.boot.testsupport.system.OutputCaptureExtension;
import org.springframework.core.convert.ConversionService;
@ -118,6 +119,22 @@ class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
((LoggerContext) LoggerFactory.getILoggerFactory()).stop();
}
@Test
@ClassPathOverrides("org.jboss.logging:jboss-logging:3.5.0.Final")
void jbossLoggingRoutesThroughLog4j2ByDefault() {
org.jboss.logging.Logger jbossLogger = org.jboss.logging.Logger.getLogger(getClass());
assertThat(jbossLogger.getClass().getName()).isEqualTo("org.jboss.logging.Log4j2Logger");
}
@Test
@ClassPathOverrides("org.jboss.logging:jboss-logging:3.5.0.Final")
void jbossLoggingRoutesThroughSlf4jWhenLoggingSystemIsInitialized() {
this.loggingSystem.beforeInitialize();
initialize(this.initializationContext, null, null);
assertThat(org.jboss.logging.Logger.getLogger(getClass()).getClass().getName())
.isEqualTo("org.jboss.logging.Slf4jLocationAwareLogger");
}
@Test
void noFile(CapturedOutput output) {
this.loggingSystem.beforeInitialize();
@ -523,6 +540,7 @@ class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
ReflectionUtils.doWithFields(LogbackLoggingSystemProperties.class,
(field) -> expectedProperties.add((String) field.get(null)), this::isPublicStaticFinal);
expectedProperties.removeAll(Arrays.asList("LOG_FILE", "LOG_PATH"));
expectedProperties.add("org.jboss.logging.provider");
assertThat(properties).containsOnlyKeys(expectedProperties);
assertThat(properties).containsEntry("CONSOLE_LOG_CHARSET", Charset.defaultCharset().name());
}