Honor logback.debug property and write Logback statuses to console

Closes gh-16876
pull/17391/head
Andy Wilkinson 6 years ago
parent 60358da43a
commit d5d96dff96

@ -0,0 +1,72 @@
/*
* 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.logback;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.pattern.Converter;
import ch.qos.logback.core.spi.LifeCycle;
import ch.qos.logback.core.status.InfoStatus;
import ch.qos.logback.core.status.Status;
/**
* Custom {@link LogbackConfigurator} used to add {@link Status Statuses} when Logback
* debugging is enabled.
*
* @author Andy Wilkinson
*/
class DebugLogbackConfigurator extends LogbackConfigurator {
DebugLogbackConfigurator(LoggerContext context) {
super(context);
}
@Override
@SuppressWarnings("rawtypes")
public void conversionRule(String conversionWord, Class<? extends Converter> converterClass) {
info("Adding conversion rule of type '" + converterClass.getName() + "' for word '" + conversionWord);
super.conversionRule(conversionWord, converterClass);
}
@Override
public void appender(String name, Appender<?> appender) {
info("Adding appender '" + appender + "' named '" + name + "'");
super.appender(name, appender);
}
@Override
public void logger(String name, Level level, boolean additive, Appender<ILoggingEvent> appender) {
info("Configuring logger '" + name + "' with level '" + level + "'. Additive: " + additive);
if (appender != null) {
info("Adding appender '" + appender + "' to logger '" + name + "'");
}
super.logger(name, level, additive, appender);
}
@Override
public void start(LifeCycle lifeCycle) {
info("Starting '" + lifeCycle + "'");
super.start(lifeCycle);
}
private void info(String message) {
getContext().getStatusManager().add(new InfoStatus(message, this));
}
}

@ -28,7 +28,6 @@ import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.pattern.Converter; import ch.qos.logback.core.pattern.Converter;
import ch.qos.logback.core.spi.ContextAware; import ch.qos.logback.core.spi.ContextAware;
import ch.qos.logback.core.spi.LifeCycle; import ch.qos.logback.core.spi.LifeCycle;
import ch.qos.logback.core.spi.PropertyContainer;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -47,7 +46,7 @@ class LogbackConfigurator {
this.context = context; this.context = context;
} }
public PropertyContainer getContext() { public LoggerContext getContext() {
return this.context; return this.context;
} }

@ -33,7 +33,9 @@ import ch.qos.logback.classic.turbo.TurboFilter;
import ch.qos.logback.classic.util.ContextInitializer; import ch.qos.logback.classic.util.ContextInitializer;
import ch.qos.logback.core.joran.spi.JoranException; import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.spi.FilterReply; import ch.qos.logback.core.spi.FilterReply;
import ch.qos.logback.core.status.OnConsoleStatusListener;
import ch.qos.logback.core.status.Status; import ch.qos.logback.core.status.Status;
import ch.qos.logback.core.util.StatusListenerConfigHelper;
import org.slf4j.ILoggerFactory; import org.slf4j.ILoggerFactory;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.Marker; import org.slf4j.Marker;
@ -125,7 +127,12 @@ public class LogbackLoggingSystem extends Slf4JLoggingSystem {
protected void loadDefaults(LoggingInitializationContext initializationContext, LogFile logFile) { protected void loadDefaults(LoggingInitializationContext initializationContext, LogFile logFile) {
LoggerContext context = getLoggerContext(); LoggerContext context = getLoggerContext();
stopAndReset(context); stopAndReset(context);
LogbackConfigurator configurator = new LogbackConfigurator(context); boolean debug = Boolean.getBoolean("logback.debug");
if (debug) {
StatusListenerConfigHelper.addOnConsoleListenerInstance(context, new OnConsoleStatusListener());
}
LogbackConfigurator configurator = debug ? new DebugLogbackConfigurator(context)
: new LogbackConfigurator(context);
Environment environment = initializationContext.getEnvironment(); Environment environment = initializationContext.getEnvironment();
context.putProperty(LoggingSystemProperties.LOG_LEVEL_PATTERN, context.putProperty(LoggingSystemProperties.LOG_LEVEL_PATTERN,
environment.resolvePlaceholders("${logging.pattern.level:${LOG_LEVEL_PATTERN:%5p}}")); environment.resolvePlaceholders("${logging.pattern.level:${LOG_LEVEL_PATTERN:%5p}}"));

@ -460,6 +460,35 @@ public class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
.containsPattern("\\d{4}-\\d{2}\\-\\d{2}T\\d{2}:\\d{2}:\\d{2}"); .containsPattern("\\d{4}-\\d{2}\\-\\d{2}T\\d{2}:\\d{2}:\\d{2}");
} }
@Test
public void noDebugOutputIsProducedByDefault() {
System.clearProperty("logback.debug");
this.loggingSystem.beforeInitialize();
File file = new File(tmpDir(), "logback-test.log");
LogFile logFile = getLogFile(file.getPath(), null);
this.loggingSystem.initialize(this.initializationContext, null, logFile);
String output = this.output.toString().trim();
System.out.println(output);
assertThat(output).doesNotContain("LevelChangePropagator").doesNotContain("SizeAndTimeBasedFNATP");
}
@Test
public void logbackDebugPropertyIsHonored() {
System.setProperty("logback.debug", "true");
try {
this.loggingSystem.beforeInitialize();
File file = new File(tmpDir(), "logback-test.log");
LogFile logFile = getLogFile(file.getPath(), null);
this.loggingSystem.initialize(this.initializationContext, null, logFile);
String output = this.output.toString().trim();
assertThat(output).contains("LevelChangePropagator").contains("SizeAndTimeBasedFNATP")
.contains("DebugLogbackConfigurator");
}
finally {
System.clearProperty("logback.debug");
}
}
private static Logger getRootLogger() { private static Logger getRootLogger() {
ILoggerFactory factory = StaticLoggerBinder.getSingleton().getLoggerFactory(); ILoggerFactory factory = StaticLoggerBinder.getSingleton().getLoggerFactory();
LoggerContext context = (LoggerContext) factory; LoggerContext context = (LoggerContext) factory;

Loading…
Cancel
Save