mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-15 01:07:30 +08:00
Upgrade to Logback 1.4 and SLF4J 2.0
Closes gh-12649
This commit is contained in:
parent
05d2f3cc8e
commit
0bfa9cd704
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -24,7 +24,7 @@ import io.micrometer.core.instrument.MeterRegistry;
|
|||||||
import io.micrometer.core.instrument.binder.MeterBinder;
|
import io.micrometer.core.instrument.binder.MeterBinder;
|
||||||
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
|
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.slf4j.impl.StaticLoggerBinder;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||||
import org.springframework.boot.actuate.autoconfigure.metrics.export.atlas.AtlasMetricsExportAutoConfiguration;
|
import org.springframework.boot.actuate.autoconfigure.metrics.export.atlas.AtlasMetricsExportAutoConfiguration;
|
||||||
@ -76,8 +76,7 @@ class MeterRegistryConfigurerIntegrationTests {
|
|||||||
void counterIsIncrementedOncePerEventWithoutCompositeMeterRegistry() {
|
void counterIsIncrementedOncePerEventWithoutCompositeMeterRegistry() {
|
||||||
new ApplicationContextRunner().with(MetricsRun.limitedTo(JmxMetricsExportAutoConfiguration.class))
|
new ApplicationContextRunner().with(MetricsRun.limitedTo(JmxMetricsExportAutoConfiguration.class))
|
||||||
.withConfiguration(AutoConfigurations.of(LogbackMetricsAutoConfiguration.class)).run((context) -> {
|
.withConfiguration(AutoConfigurations.of(LogbackMetricsAutoConfiguration.class)).run((context) -> {
|
||||||
Logger logger = ((LoggerContext) StaticLoggerBinder.getSingleton().getLoggerFactory())
|
Logger logger = ((LoggerContext) LoggerFactory.getILoggerFactory()).getLogger("test-logger");
|
||||||
.getLogger("test-logger");
|
|
||||||
logger.error("Error.");
|
logger.error("Error.");
|
||||||
Map<String, MeterRegistry> registriesByName = context.getBeansOfType(MeterRegistry.class);
|
Map<String, MeterRegistry> registriesByName = context.getBeansOfType(MeterRegistry.class);
|
||||||
assertThat(registriesByName).hasSize(1);
|
assertThat(registriesByName).hasSize(1);
|
||||||
@ -92,8 +91,7 @@ class MeterRegistryConfigurerIntegrationTests {
|
|||||||
.with(MetricsRun.limitedTo(JmxMetricsExportAutoConfiguration.class,
|
.with(MetricsRun.limitedTo(JmxMetricsExportAutoConfiguration.class,
|
||||||
PrometheusMetricsExportAutoConfiguration.class))
|
PrometheusMetricsExportAutoConfiguration.class))
|
||||||
.withConfiguration(AutoConfigurations.of(LogbackMetricsAutoConfiguration.class)).run((context) -> {
|
.withConfiguration(AutoConfigurations.of(LogbackMetricsAutoConfiguration.class)).run((context) -> {
|
||||||
Logger logger = ((LoggerContext) StaticLoggerBinder.getSingleton().getLoggerFactory())
|
Logger logger = ((LoggerContext) LoggerFactory.getILoggerFactory()).getLogger("test-logger");
|
||||||
.getLogger("test-logger");
|
|
||||||
logger.error("Error.");
|
logger.error("Error.");
|
||||||
Map<String, MeterRegistry> registriesByName = context.getBeansOfType(MeterRegistry.class);
|
Map<String, MeterRegistry> registriesByName = context.getBeansOfType(MeterRegistry.class);
|
||||||
assertThat(registriesByName).hasSize(3);
|
assertThat(registriesByName).hasSize(3);
|
||||||
|
@ -23,7 +23,7 @@ import ch.qos.logback.classic.Logger;
|
|||||||
import ch.qos.logback.classic.LoggerContext;
|
import ch.qos.logback.classic.LoggerContext;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.slf4j.impl.StaticLoggerBinder;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport;
|
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport;
|
||||||
@ -147,8 +147,8 @@ class ConditionEvaluationReportLoggingListenerTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void withDebugLogging(Runnable runnable) {
|
private void withDebugLogging(Runnable runnable) {
|
||||||
LoggerContext context = (LoggerContext) StaticLoggerBinder.getSingleton().getLoggerFactory();
|
Logger logger = ((LoggerContext) LoggerFactory.getILoggerFactory())
|
||||||
Logger logger = context.getLogger(ConditionEvaluationReportLoggingListener.class);
|
.getLogger(ConditionEvaluationReportLoggingListener.class);
|
||||||
Level currentLevel = logger.getLevel();
|
Level currentLevel = logger.getLevel();
|
||||||
logger.setLevel(Level.DEBUG);
|
logger.setLevel(Level.DEBUG);
|
||||||
try {
|
try {
|
||||||
|
@ -863,7 +863,7 @@ bom {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
library("Logback", "1.2.11") {
|
library("Logback", "1.4.1") {
|
||||||
group("ch.qos.logback") {
|
group("ch.qos.logback") {
|
||||||
modules = [
|
modules = [
|
||||||
"logback-access",
|
"logback-access",
|
||||||
@ -1366,7 +1366,7 @@ bom {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
library("SLF4J", "1.7.36") {
|
library("SLF4J", "2.0.2") {
|
||||||
group("org.slf4j") {
|
group("org.slf4j") {
|
||||||
modules = [
|
modules = [
|
||||||
"jcl-over-slf4j",
|
"jcl-over-slf4j",
|
||||||
@ -1375,9 +1375,11 @@ bom {
|
|||||||
"slf4j-api",
|
"slf4j-api",
|
||||||
"slf4j-ext",
|
"slf4j-ext",
|
||||||
"slf4j-jcl",
|
"slf4j-jcl",
|
||||||
|
"slf4j-jdk-platform-logging",
|
||||||
"slf4j-jdk14",
|
"slf4j-jdk14",
|
||||||
"slf4j-log4j12",
|
"slf4j-log4j12",
|
||||||
"slf4j-nop",
|
"slf4j-nop",
|
||||||
|
"slf4j-reload4j",
|
||||||
"slf4j-simple"
|
"slf4j-simple"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ plugins {
|
|||||||
description = "Starter for using Log4j2 for logging. An alternative to spring-boot-starter-logging"
|
description = "Starter for using Log4j2 for logging. An alternative to spring-boot-starter-logging"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api("org.apache.logging.log4j:log4j-slf4j-impl")
|
api("org.apache.logging.log4j:log4j-slf4j2-impl")
|
||||||
api("org.apache.logging.log4j:log4j-core")
|
api("org.apache.logging.log4j:log4j-core")
|
||||||
api("org.apache.logging.log4j:log4j-jul")
|
api("org.apache.logging.log4j:log4j-jul")
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ package org.springframework.boot.loader.tools;
|
|||||||
import ch.qos.logback.classic.Level;
|
import ch.qos.logback.classic.Level;
|
||||||
import org.slf4j.ILoggerFactory;
|
import org.slf4j.ILoggerFactory;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.impl.StaticLoggerBinder;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ import org.springframework.util.ClassUtils;
|
|||||||
public abstract class LogbackInitializer {
|
public abstract class LogbackInitializer {
|
||||||
|
|
||||||
public static void initialize() {
|
public static void initialize() {
|
||||||
if (ClassUtils.isPresent("org.slf4j.impl.StaticLoggerBinder", null)
|
if (ClassUtils.isPresent("org.slf4j.LoggerFactory", null)
|
||||||
&& ClassUtils.isPresent("ch.qos.logback.classic.Logger", null)) {
|
&& ClassUtils.isPresent("ch.qos.logback.classic.Logger", null)) {
|
||||||
new Initializer().setRootLogLevel();
|
new Initializer().setRootLogLevel();
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ public abstract class LogbackInitializer {
|
|||||||
private static class Initializer {
|
private static class Initializer {
|
||||||
|
|
||||||
void setRootLogLevel() {
|
void setRootLogLevel() {
|
||||||
ILoggerFactory factory = StaticLoggerBinder.getSingleton().getLoggerFactory();
|
ILoggerFactory factory = LoggerFactory.getILoggerFactory();
|
||||||
Logger logger = factory.getLogger(Logger.ROOT_LOGGER_NAME);
|
Logger logger = factory.getLogger(Logger.ROOT_LOGGER_NAME);
|
||||||
((ch.qos.logback.classic.Logger) logger).setLevel(Level.INFO);
|
((ch.qos.logback.classic.Logger) logger).setLevel(Level.INFO);
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import ch.qos.logback.core.Appender;
|
|||||||
import ch.qos.logback.core.ConsoleAppender;
|
import ch.qos.logback.core.ConsoleAppender;
|
||||||
import ch.qos.logback.core.rolling.RollingFileAppender;
|
import ch.qos.logback.core.rolling.RollingFileAppender;
|
||||||
import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy;
|
import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy;
|
||||||
|
import ch.qos.logback.core.spi.ScanException;
|
||||||
import ch.qos.logback.core.util.FileSize;
|
import ch.qos.logback.core.util.FileSize;
|
||||||
import ch.qos.logback.core.util.OptionHelper;
|
import ch.qos.logback.core.util.OptionHelper;
|
||||||
|
|
||||||
@ -146,7 +147,12 @@ class DefaultLogbackConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String resolve(LogbackConfigurator config, String val) {
|
private String resolve(LogbackConfigurator config, String val) {
|
||||||
return OptionHelper.substVars(val, config.getContext());
|
try {
|
||||||
|
return OptionHelper.substVars(val, config.getContext());
|
||||||
|
}
|
||||||
|
catch (ScanException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,9 +39,9 @@ import ch.qos.logback.core.status.Status;
|
|||||||
import ch.qos.logback.core.util.StatusListenerConfigHelper;
|
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.LoggerFactory;
|
||||||
import org.slf4j.Marker;
|
import org.slf4j.Marker;
|
||||||
import org.slf4j.bridge.SLF4JBridgeHandler;
|
import org.slf4j.bridge.SLF4JBridgeHandler;
|
||||||
import org.slf4j.impl.StaticLoggerBinder;
|
|
||||||
|
|
||||||
import org.springframework.boot.logging.AbstractLoggingSystem;
|
import org.springframework.boot.logging.AbstractLoggingSystem;
|
||||||
import org.springframework.boot.logging.LogFile;
|
import org.springframework.boot.logging.LogFile;
|
||||||
@ -348,7 +348,7 @@ public class LogbackLoggingSystem extends AbstractLoggingSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private LoggerContext getLoggerContext() {
|
private LoggerContext getLoggerContext() {
|
||||||
ILoggerFactory factory = StaticLoggerBinder.getSingleton().getLoggerFactory();
|
ILoggerFactory factory = LoggerFactory.getILoggerFactory();
|
||||||
Assert.isInstanceOf(LoggerContext.class, factory,
|
Assert.isInstanceOf(LoggerContext.class, factory,
|
||||||
() -> String.format(
|
() -> String.format(
|
||||||
"LoggerFactory is not a Logback LoggerContext but Logback is on "
|
"LoggerFactory is not a Logback LoggerContext but Logback is on "
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2019 the original author or authors.
|
* Copyright 2012-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -17,18 +17,18 @@
|
|||||||
package org.springframework.boot.logging.logback;
|
package org.springframework.boot.logging.logback;
|
||||||
|
|
||||||
import ch.qos.logback.classic.joran.JoranConfigurator;
|
import ch.qos.logback.classic.joran.JoranConfigurator;
|
||||||
import ch.qos.logback.core.joran.action.NOPAction;
|
|
||||||
import ch.qos.logback.core.joran.spi.ElementSelector;
|
import ch.qos.logback.core.joran.spi.ElementSelector;
|
||||||
import ch.qos.logback.core.joran.spi.RuleStore;
|
import ch.qos.logback.core.joran.spi.RuleStore;
|
||||||
|
import ch.qos.logback.core.model.processor.DefaultProcessor;
|
||||||
|
|
||||||
import org.springframework.boot.logging.LoggingInitializationContext;
|
import org.springframework.boot.logging.LoggingInitializationContext;
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extended version of the Logback {@link JoranConfigurator} that adds additional Spring
|
* Extended version of the Logback {@link JoranConfigurator} that adds additional Spring
|
||||||
* Boot rules.
|
* Boot rules.
|
||||||
*
|
*
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
|
* @author Andy Wilkinson
|
||||||
*/
|
*/
|
||||||
class SpringBootJoranConfigurator extends JoranConfigurator {
|
class SpringBootJoranConfigurator extends JoranConfigurator {
|
||||||
|
|
||||||
@ -39,12 +39,22 @@ class SpringBootJoranConfigurator extends JoranConfigurator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addInstanceRules(RuleStore rs) {
|
protected void addModelHandlerAssociations(DefaultProcessor defaultProcessor) {
|
||||||
super.addInstanceRules(rs);
|
super.addModelHandlerAssociations(defaultProcessor);
|
||||||
Environment environment = this.initializationContext.getEnvironment();
|
defaultProcessor.addHandler(SpringPropertyModel.class,
|
||||||
rs.addRule(new ElementSelector("configuration/springProperty"), new SpringPropertyAction(environment));
|
(handlerContext, handlerMic) -> new SpringPropertyModelHandler(this.context,
|
||||||
rs.addRule(new ElementSelector("*/springProfile"), new SpringProfileAction(environment));
|
this.initializationContext.getEnvironment()));
|
||||||
rs.addRule(new ElementSelector("*/springProfile/*"), new NOPAction());
|
defaultProcessor.addHandler(SpringProfileModel.class,
|
||||||
|
(handlerContext, handlerMic) -> new SpringProfileModelHandler(this.context,
|
||||||
|
this.initializationContext.getEnvironment()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addElementSelectorAndActionAssociations(RuleStore ruleStore) {
|
||||||
|
super.addElementSelectorAndActionAssociations(ruleStore);
|
||||||
|
ruleStore.addRule(new ElementSelector("configuration/springProperty"), SpringPropertyAction::new);
|
||||||
|
ruleStore.addRule(new ElementSelector("*/springProfile"), SpringProfileAction::new);
|
||||||
|
ruleStore.addTransparentPathPart("springProfile");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2019 the original author or authors.
|
* Copyright 2012-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -16,102 +16,29 @@
|
|||||||
|
|
||||||
package org.springframework.boot.logging.logback;
|
package org.springframework.boot.logging.logback;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import ch.qos.logback.core.joran.action.BaseModelAction;
|
||||||
import java.util.List;
|
import ch.qos.logback.core.joran.spi.SaxEventInterpretationContext;
|
||||||
|
import ch.qos.logback.core.model.Model;
|
||||||
import ch.qos.logback.core.joran.action.Action;
|
|
||||||
import ch.qos.logback.core.joran.event.InPlayListener;
|
|
||||||
import ch.qos.logback.core.joran.event.SaxEvent;
|
|
||||||
import ch.qos.logback.core.joran.spi.ActionException;
|
|
||||||
import ch.qos.logback.core.joran.spi.InterpretationContext;
|
|
||||||
import ch.qos.logback.core.joran.spi.Interpreter;
|
|
||||||
import ch.qos.logback.core.util.OptionHelper;
|
|
||||||
import org.xml.sax.Attributes;
|
import org.xml.sax.Attributes;
|
||||||
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.core.env.Profiles;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logback {@link Action} to support {@code <springProfile>} tags. Allows section of a
|
* Logback {@link BaseModelAction} for {@code <springProperty>} tags. Allows a section of
|
||||||
* logback configuration to only be enabled when a specific profile is active.
|
* a Logback configuration to only be enabled when a specific profile is active.
|
||||||
*
|
*
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @author Eddú Meléndez
|
* @author Eddú Meléndez
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @see SpringProfileModel
|
||||||
|
* @see SpringProfileModelHandler
|
||||||
*/
|
*/
|
||||||
class SpringProfileAction extends Action implements InPlayListener {
|
class SpringProfileAction extends BaseModelAction {
|
||||||
|
|
||||||
private final Environment environment;
|
|
||||||
|
|
||||||
private int depth = 0;
|
|
||||||
|
|
||||||
private boolean acceptsProfile;
|
|
||||||
|
|
||||||
private List<SaxEvent> events;
|
|
||||||
|
|
||||||
SpringProfileAction(Environment environment) {
|
|
||||||
this.environment = environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void begin(InterpretationContext ic, String name, Attributes attributes) throws ActionException {
|
protected Model buildCurrentModel(SaxEventInterpretationContext interpretationContext, String name,
|
||||||
this.depth++;
|
Attributes attributes) {
|
||||||
if (this.depth != 1) {
|
SpringProfileModel model = new SpringProfileModel();
|
||||||
return;
|
model.setName(attributes.getValue(NAME_ATTRIBUTE));
|
||||||
}
|
return model;
|
||||||
ic.pushObject(this);
|
|
||||||
this.acceptsProfile = acceptsProfiles(ic, attributes);
|
|
||||||
this.events = new ArrayList<>();
|
|
||||||
ic.addInPlayListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean acceptsProfiles(InterpretationContext ic, Attributes attributes) {
|
|
||||||
if (this.environment == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String[] profileNames = StringUtils
|
|
||||||
.trimArrayElements(StringUtils.commaDelimitedListToStringArray(attributes.getValue(NAME_ATTRIBUTE)));
|
|
||||||
if (profileNames.length == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < profileNames.length; i++) {
|
|
||||||
profileNames[i] = OptionHelper.substVars(profileNames[i], ic, this.context);
|
|
||||||
}
|
|
||||||
return this.environment.acceptsProfiles(Profiles.of(profileNames));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void end(InterpretationContext ic, String name) throws ActionException {
|
|
||||||
this.depth--;
|
|
||||||
if (this.depth != 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ic.removeInPlayListener(this);
|
|
||||||
verifyAndPop(ic);
|
|
||||||
if (this.acceptsProfile) {
|
|
||||||
addEventsToPlayer(ic);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyAndPop(InterpretationContext ic) {
|
|
||||||
Object o = ic.peekObject();
|
|
||||||
Assert.state(o != null, "Unexpected null object on stack");
|
|
||||||
Assert.isInstanceOf(SpringProfileAction.class, o, "logback stack error");
|
|
||||||
Assert.state(o == this, "ProfileAction different than current one on stack");
|
|
||||||
ic.popObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addEventsToPlayer(InterpretationContext ic) {
|
|
||||||
Interpreter interpreter = ic.getJoranInterpreter();
|
|
||||||
this.events.remove(0);
|
|
||||||
this.events.remove(this.events.size() - 1);
|
|
||||||
interpreter.getEventPlayer().addEventsDynamically(this.events, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void inPlay(SaxEvent event) {
|
|
||||||
this.events.add(event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
* 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.core.model.NamedModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logback {@link NamedModel model} to support {@code <springProfile>} tags.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @see SpringProfileAction
|
||||||
|
* @see SpringProfileModelHandler
|
||||||
|
*/
|
||||||
|
class SpringProfileModel extends NamedModel {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
* 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.core.Context;
|
||||||
|
import ch.qos.logback.core.model.Model;
|
||||||
|
import ch.qos.logback.core.model.processor.ModelHandlerBase;
|
||||||
|
import ch.qos.logback.core.model.processor.ModelHandlerException;
|
||||||
|
import ch.qos.logback.core.model.processor.ModelInterpretationContext;
|
||||||
|
import ch.qos.logback.core.spi.ScanException;
|
||||||
|
import ch.qos.logback.core.util.OptionHelper;
|
||||||
|
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.core.env.Profiles;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logback {@link ModelHandlerBase model handler} to support {@code <springProfile>} tags.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @author Eddú Meléndez
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @see SpringProfileModel
|
||||||
|
* @see SpringProfileAction
|
||||||
|
*/
|
||||||
|
class SpringProfileModelHandler extends ModelHandlerBase {
|
||||||
|
|
||||||
|
private final Environment environment;
|
||||||
|
|
||||||
|
SpringProfileModelHandler(Context context, Environment environment) {
|
||||||
|
super(context);
|
||||||
|
this.environment = environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(ModelInterpretationContext intercon, Model model) throws ModelHandlerException {
|
||||||
|
SpringProfileModel profileModel = (SpringProfileModel) model;
|
||||||
|
if (!acceptsProfiles(intercon, profileModel)) {
|
||||||
|
model.markAsSkipped();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean acceptsProfiles(ModelInterpretationContext ic, SpringProfileModel model) {
|
||||||
|
if (this.environment == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String[] profileNames = StringUtils
|
||||||
|
.trimArrayElements(StringUtils.commaDelimitedListToStringArray(model.getName()));
|
||||||
|
if (profileNames.length == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < profileNames.length; i++) {
|
||||||
|
try {
|
||||||
|
profileNames[i] = OptionHelper.substVars(profileNames[i], ic, this.context);
|
||||||
|
}
|
||||||
|
catch (ScanException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.environment.acceptsProfiles(Profiles.of(profileNames));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2019 the original author or authors.
|
* Copyright 2012-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -16,58 +16,37 @@
|
|||||||
|
|
||||||
package org.springframework.boot.logging.logback;
|
package org.springframework.boot.logging.logback;
|
||||||
|
|
||||||
import ch.qos.logback.core.joran.action.Action;
|
import ch.qos.logback.core.joran.action.BaseModelAction;
|
||||||
import ch.qos.logback.core.joran.action.ActionUtil;
|
import ch.qos.logback.core.joran.spi.SaxEventInterpretationContext;
|
||||||
import ch.qos.logback.core.joran.action.ActionUtil.Scope;
|
import ch.qos.logback.core.model.Model;
|
||||||
import ch.qos.logback.core.joran.spi.ActionException;
|
|
||||||
import ch.qos.logback.core.joran.spi.InterpretationContext;
|
|
||||||
import ch.qos.logback.core.util.OptionHelper;
|
|
||||||
import org.xml.sax.Attributes;
|
import org.xml.sax.Attributes;
|
||||||
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logback {@link Action} to support {@code <springProperty>} tags. Allows logback
|
* Logback {@link BaseModelAction} for {@code <springProperty>} tags. Allows Logback
|
||||||
* properties to be sourced from the Spring environment.
|
* properties to be sourced from the Spring environment.
|
||||||
*
|
*
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @author Eddú Meléndez
|
* @author Eddú Meléndez
|
||||||
* @author Madhura Bhave
|
* @author Madhura Bhave
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @see SpringPropertyModel
|
||||||
|
* @see SpringPropertyModelHandler
|
||||||
*/
|
*/
|
||||||
class SpringPropertyAction extends Action {
|
class SpringPropertyAction extends BaseModelAction {
|
||||||
|
|
||||||
private static final String SOURCE_ATTRIBUTE = "source";
|
private static final String SOURCE_ATTRIBUTE = "source";
|
||||||
|
|
||||||
private static final String DEFAULT_VALUE_ATTRIBUTE = "defaultValue";
|
private static final String DEFAULT_VALUE_ATTRIBUTE = "defaultValue";
|
||||||
|
|
||||||
private final Environment environment;
|
|
||||||
|
|
||||||
SpringPropertyAction(Environment environment) {
|
|
||||||
this.environment = environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void begin(InterpretationContext context, String elementName, Attributes attributes) throws ActionException {
|
protected Model buildCurrentModel(SaxEventInterpretationContext interpretationContext, String name,
|
||||||
String name = attributes.getValue(NAME_ATTRIBUTE);
|
Attributes attributes) {
|
||||||
String source = attributes.getValue(SOURCE_ATTRIBUTE);
|
SpringPropertyModel model = new SpringPropertyModel();
|
||||||
Scope scope = ActionUtil.stringToScope(attributes.getValue(SCOPE_ATTRIBUTE));
|
model.setName(attributes.getValue(NAME_ATTRIBUTE));
|
||||||
String defaultValue = attributes.getValue(DEFAULT_VALUE_ATTRIBUTE);
|
model.setSource(attributes.getValue(SOURCE_ATTRIBUTE));
|
||||||
if (OptionHelper.isEmpty(name) || OptionHelper.isEmpty(source)) {
|
model.setScope(attributes.getValue(SCOPE_ATTRIBUTE));
|
||||||
addError("The \"name\" and \"source\" attributes of <springProperty> must be set");
|
model.setDefaultValue(attributes.getValue(DEFAULT_VALUE_ATTRIBUTE));
|
||||||
}
|
return model;
|
||||||
ActionUtil.setProperty(context, name, getValue(source, defaultValue), scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getValue(String source, String defaultValue) {
|
|
||||||
if (this.environment == null) {
|
|
||||||
addWarn("No Spring Environment available to resolve " + source);
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
return this.environment.getProperty(source, defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void end(InterpretationContext context, String name) throws ActionException {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
* 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.core.model.NamedModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logback {@link NamedModel model} to support {@code <springProperty>} tags. Allows
|
||||||
|
* Logback properties to be sourced from the Spring environment.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @see SpringPropertyAction
|
||||||
|
* @see SpringPropertyModelHandler
|
||||||
|
*/
|
||||||
|
class SpringPropertyModel extends NamedModel {
|
||||||
|
|
||||||
|
private String scope;
|
||||||
|
|
||||||
|
private String defaultValue;
|
||||||
|
|
||||||
|
private String source;
|
||||||
|
|
||||||
|
String getScope() {
|
||||||
|
return this.scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setScope(String scope) {
|
||||||
|
this.scope = scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getDefaultValue() {
|
||||||
|
return this.defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDefaultValue(String defaultValue) {
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getSource() {
|
||||||
|
return this.source;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSource(String source) {
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* 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.core.Context;
|
||||||
|
import ch.qos.logback.core.joran.action.ActionUtil;
|
||||||
|
import ch.qos.logback.core.joran.action.ActionUtil.Scope;
|
||||||
|
import ch.qos.logback.core.model.Model;
|
||||||
|
import ch.qos.logback.core.model.ModelUtil;
|
||||||
|
import ch.qos.logback.core.model.processor.ModelHandlerBase;
|
||||||
|
import ch.qos.logback.core.model.processor.ModelHandlerException;
|
||||||
|
import ch.qos.logback.core.model.processor.ModelInterpretationContext;
|
||||||
|
import ch.qos.logback.core.util.OptionHelper;
|
||||||
|
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logback {@link ModelHandlerBase model handler} to support {@code <springProperty>}
|
||||||
|
* tags. Allows Logback properties to be sourced from the Spring environment.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @author Eddú Meléndez
|
||||||
|
* @author Madhura Bhave
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @see SpringPropertyAction
|
||||||
|
* @see SpringPropertyModel
|
||||||
|
*/
|
||||||
|
class SpringPropertyModelHandler extends ModelHandlerBase {
|
||||||
|
|
||||||
|
private final Environment environment;
|
||||||
|
|
||||||
|
SpringPropertyModelHandler(Context context, Environment environment) {
|
||||||
|
super(context);
|
||||||
|
this.environment = environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(ModelInterpretationContext intercon, Model model) throws ModelHandlerException {
|
||||||
|
SpringPropertyModel propertyModel = (SpringPropertyModel) model;
|
||||||
|
Scope scope = ActionUtil.stringToScope(propertyModel.getScope());
|
||||||
|
String defaultValue = propertyModel.getDefaultValue();
|
||||||
|
String source = propertyModel.getSource();
|
||||||
|
if (OptionHelper.isNullOrEmpty(propertyModel.getName()) || OptionHelper.isNullOrEmpty(source)) {
|
||||||
|
addError("The \"name\" and \"source\" attributes of <springProperty> must be set");
|
||||||
|
}
|
||||||
|
ModelUtil.setProperty(intercon, propertyModel.getName(), getValue(source, defaultValue), scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getValue(String source, String defaultValue) {
|
||||||
|
if (this.environment == null) {
|
||||||
|
addWarn("No Spring Environment available to resolve " + source);
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
return this.environment.getProperty(source, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -41,8 +41,8 @@ import org.junit.jupiter.api.BeforeEach;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.junit.jupiter.api.io.TempDir;
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.slf4j.bridge.SLF4JBridgeHandler;
|
import org.slf4j.bridge.SLF4JBridgeHandler;
|
||||||
import org.slf4j.impl.StaticLoggerBinder;
|
|
||||||
|
|
||||||
import org.springframework.boot.DefaultBootstrapContext;
|
import org.springframework.boot.DefaultBootstrapContext;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
@ -101,7 +101,7 @@ class LoggingApplicationListenerTests {
|
|||||||
|
|
||||||
private final LoggingApplicationListener listener = new LoggingApplicationListener();
|
private final LoggingApplicationListener listener = new LoggingApplicationListener();
|
||||||
|
|
||||||
private final LoggerContext loggerContext = (LoggerContext) StaticLoggerBinder.getSingleton().getLoggerFactory();
|
private final LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
|
||||||
|
|
||||||
private final ch.qos.logback.classic.Logger logger = this.loggerContext.getLogger(getClass());
|
private final ch.qos.logback.classic.Logger logger = this.loggerContext.getLogger(getClass());
|
||||||
|
|
||||||
|
@ -43,8 +43,8 @@ import org.junit.jupiter.api.BeforeEach;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.slf4j.ILoggerFactory;
|
import org.slf4j.ILoggerFactory;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.slf4j.bridge.SLF4JBridgeHandler;
|
import org.slf4j.bridge.SLF4JBridgeHandler;
|
||||||
import org.slf4j.impl.StaticLoggerBinder;
|
|
||||||
|
|
||||||
import org.springframework.boot.convert.ApplicationConversionService;
|
import org.springframework.boot.convert.ApplicationConversionService;
|
||||||
import org.springframework.boot.logging.AbstractLoggingSystemTests;
|
import org.springframework.boot.logging.AbstractLoggingSystemTests;
|
||||||
@ -103,7 +103,7 @@ class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
|||||||
System.getProperties().remove(LoggingSystemProperties.FILE_LOG_CHARSET);
|
System.getProperties().remove(LoggingSystemProperties.FILE_LOG_CHARSET);
|
||||||
this.systemPropertyNames = new HashSet<>(System.getProperties().keySet());
|
this.systemPropertyNames = new HashSet<>(System.getProperties().keySet());
|
||||||
this.loggingSystem.cleanUp();
|
this.loggingSystem.cleanUp();
|
||||||
this.logger = ((LoggerContext) StaticLoggerBinder.getSingleton().getLoggerFactory()).getLogger(getClass());
|
this.logger = ((LoggerContext) LoggerFactory.getILoggerFactory()).getLogger(getClass());
|
||||||
this.environment = new MockEnvironment();
|
this.environment = new MockEnvironment();
|
||||||
ConversionService conversionService = ApplicationConversionService.getSharedInstance();
|
ConversionService conversionService = ApplicationConversionService.getSharedInstance();
|
||||||
this.environment.setConversionService((ConfigurableConversionService) conversionService);
|
this.environment.setConversionService((ConfigurableConversionService) conversionService);
|
||||||
@ -114,7 +114,7 @@ class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
|||||||
void cleanUp() {
|
void cleanUp() {
|
||||||
System.getProperties().keySet().retainAll(this.systemPropertyNames);
|
System.getProperties().keySet().retainAll(this.systemPropertyNames);
|
||||||
this.loggingSystem.cleanUp();
|
this.loggingSystem.cleanUp();
|
||||||
((LoggerContext) StaticLoggerBinder.getSingleton().getLoggerFactory()).stop();
|
((LoggerContext) LoggerFactory.getILoggerFactory()).stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -243,7 +243,7 @@ class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
|||||||
void getLoggingConfigurationForALL() {
|
void getLoggingConfigurationForALL() {
|
||||||
this.loggingSystem.beforeInitialize();
|
this.loggingSystem.beforeInitialize();
|
||||||
initialize(this.initializationContext, null, null);
|
initialize(this.initializationContext, null, null);
|
||||||
Logger logger = (Logger) StaticLoggerBinder.getSingleton().getLoggerFactory().getLogger(getClass().getName());
|
Logger logger = (Logger) LoggerFactory.getILoggerFactory().getLogger(getClass().getName());
|
||||||
logger.setLevel(Level.ALL);
|
logger.setLevel(Level.ALL);
|
||||||
LoggerConfiguration configuration = this.loggingSystem.getLoggerConfiguration(getClass().getName());
|
LoggerConfiguration configuration = this.loggingSystem.getLoggerConfiguration(getClass().getName());
|
||||||
assertThat(configuration)
|
assertThat(configuration)
|
||||||
@ -255,7 +255,7 @@ class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
|||||||
this.loggingSystem.beforeInitialize();
|
this.loggingSystem.beforeInitialize();
|
||||||
initialize(this.initializationContext, null, null);
|
initialize(this.initializationContext, null, null);
|
||||||
this.loggingSystem.setLogLevel(getClass().getName(), LogLevel.TRACE);
|
this.loggingSystem.setLogLevel(getClass().getName(), LogLevel.TRACE);
|
||||||
Logger logger = (Logger) StaticLoggerBinder.getSingleton().getLoggerFactory().getLogger(getClass().getName());
|
Logger logger = (Logger) LoggerFactory.getILoggerFactory().getLogger(getClass().getName());
|
||||||
assertThat(logger.getLevel()).isEqualTo(Level.TRACE);
|
assertThat(logger.getLevel()).isEqualTo(Level.TRACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,9 +516,9 @@ class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
|||||||
this.environment.setProperty("logging.logback.rollingpolicy.max-history", "20");
|
this.environment.setProperty("logging.logback.rollingpolicy.max-history", "20");
|
||||||
this.loggingSystem.beforeInitialize();
|
this.loggingSystem.beforeInitialize();
|
||||||
initialize(this.initializationContext, null, null);
|
initialize(this.initializationContext, null, null);
|
||||||
LoggerContext loggerContext = (LoggerContext) StaticLoggerBinder.getSingleton().getLoggerFactory();
|
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
|
||||||
Map<String, String> properties = loggerContext.getCopyOfPropertyMap();
|
Map<String, String> properties = loggerContext.getCopyOfPropertyMap();
|
||||||
Set<String> expectedProperties = new HashSet<String>();
|
Set<String> expectedProperties = new HashSet<>();
|
||||||
ReflectionUtils.doWithFields(LogbackLoggingSystemProperties.class,
|
ReflectionUtils.doWithFields(LogbackLoggingSystemProperties.class,
|
||||||
(field) -> expectedProperties.add((String) field.get(null)), this::isPublicStaticFinal);
|
(field) -> expectedProperties.add((String) field.get(null)), this::isPublicStaticFinal);
|
||||||
expectedProperties.removeAll(Arrays.asList("LOG_FILE", "LOG_PATH"));
|
expectedProperties.removeAll(Arrays.asList("LOG_FILE", "LOG_PATH"));
|
||||||
@ -533,7 +533,7 @@ class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void initializationIsOnlyPerformedOnceUntilCleanedUp() {
|
void initializationIsOnlyPerformedOnceUntilCleanedUp() {
|
||||||
LoggerContext loggerContext = (LoggerContext) StaticLoggerBinder.getSingleton().getLoggerFactory();
|
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
|
||||||
LoggerContextListener listener = mock(LoggerContextListener.class);
|
LoggerContextListener listener = mock(LoggerContextListener.class);
|
||||||
loggerContext.addListener(listener);
|
loggerContext.addListener(listener);
|
||||||
this.loggingSystem.beforeInitialize();
|
this.loggingSystem.beforeInitialize();
|
||||||
@ -635,7 +635,7 @@ class LogbackLoggingSystemTests extends AbstractLoggingSystemTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Logger getRootLogger() {
|
private static Logger getRootLogger() {
|
||||||
ILoggerFactory factory = StaticLoggerBinder.getSingleton().getLoggerFactory();
|
ILoggerFactory factory = LoggerFactory.getILoggerFactory();
|
||||||
LoggerContext context = (LoggerContext) factory;
|
LoggerContext context = (LoggerContext) factory;
|
||||||
return context.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
|
return context.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2019 the original author or authors.
|
* Copyright 2012-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -26,7 +26,6 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.slf4j.impl.StaticLoggerBinder;
|
|
||||||
|
|
||||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
|
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
|
||||||
import org.springframework.boot.logging.LoggingInitializationContext;
|
import org.springframework.boot.logging.LoggingInitializationContext;
|
||||||
@ -65,8 +64,7 @@ class SpringBootJoranConfiguratorTests {
|
|||||||
this.environment = new MockEnvironment();
|
this.environment = new MockEnvironment();
|
||||||
this.initializationContext = new LoggingInitializationContext(this.environment);
|
this.initializationContext = new LoggingInitializationContext(this.environment);
|
||||||
this.configurator = new SpringBootJoranConfigurator(this.initializationContext);
|
this.configurator = new SpringBootJoranConfigurator(this.initializationContext);
|
||||||
StaticLoggerBinder binder = StaticLoggerBinder.getSingleton();
|
this.context = (LoggerContext) LoggerFactory.getILoggerFactory();
|
||||||
this.context = (LoggerContext) binder.getLoggerFactory();
|
|
||||||
this.logger = this.context.getLogger(getClass());
|
this.logger = this.context.getLogger(getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,38 +21,34 @@ import java.util.List;
|
|||||||
|
|
||||||
import ch.qos.logback.core.Context;
|
import ch.qos.logback.core.Context;
|
||||||
import ch.qos.logback.core.ContextBase;
|
import ch.qos.logback.core.ContextBase;
|
||||||
import ch.qos.logback.core.joran.action.Action;
|
|
||||||
import ch.qos.logback.core.joran.spi.ActionException;
|
import ch.qos.logback.core.joran.spi.ActionException;
|
||||||
import ch.qos.logback.core.joran.spi.InterpretationContext;
|
import ch.qos.logback.core.model.processor.ModelHandlerException;
|
||||||
|
import ch.qos.logback.core.model.processor.ModelInterpretationContext;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.xml.sax.Attributes;
|
|
||||||
|
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.core.env.Profiles;
|
import org.springframework.core.env.Profiles;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.BDDMockito.given;
|
|
||||||
import static org.mockito.BDDMockito.then;
|
import static org.mockito.BDDMockito.then;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link SpringProfileAction}.
|
* Tests for {@link SpringProfileModelHandler}.
|
||||||
*
|
*
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
*/
|
*/
|
||||||
class SpringProfileActionTests {
|
class SpringProfileModelHandlerTests {
|
||||||
|
|
||||||
private final Environment environment = mock(Environment.class);
|
private final Environment environment = mock(Environment.class);
|
||||||
|
|
||||||
private final SpringProfileAction action = new SpringProfileAction(this.environment);
|
|
||||||
|
|
||||||
private final Context context = new ContextBase();
|
private final Context context = new ContextBase();
|
||||||
|
|
||||||
private final InterpretationContext interpretationContext = new InterpretationContext(this.context, null);
|
private final SpringProfileModelHandler action = new SpringProfileModelHandler(this.context, this.environment);
|
||||||
|
|
||||||
private final Attributes attributes = mock(Attributes.class);
|
private final ModelInterpretationContext interpretationContext = new ModelInterpretationContext(this.context);
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
@ -60,9 +56,10 @@ class SpringProfileActionTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void environmentIsQueriedWithProfileFromNameAttribute() throws ActionException {
|
void environmentIsQueriedWithProfileFromModelName() throws ActionException, ModelHandlerException {
|
||||||
given(this.attributes.getValue(Action.NAME_ATTRIBUTE)).willReturn("dev");
|
SpringProfileModel model = new SpringProfileModel();
|
||||||
this.action.begin(this.interpretationContext, null, this.attributes);
|
model.setName("dev");
|
||||||
|
this.action.handle(this.interpretationContext, model);
|
||||||
ArgumentCaptor<Profiles> profiles = ArgumentCaptor.forClass(Profiles.class);
|
ArgumentCaptor<Profiles> profiles = ArgumentCaptor.forClass(Profiles.class);
|
||||||
then(this.environment).should().acceptsProfiles(profiles.capture());
|
then(this.environment).should().acceptsProfiles(profiles.capture());
|
||||||
List<String> profileNames = new ArrayList<>();
|
List<String> profileNames = new ArrayList<>();
|
||||||
@ -74,9 +71,10 @@ class SpringProfileActionTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void environmentIsQueriedWithMultipleProfilesFromCommaSeparatedNameAttribute() throws ActionException {
|
void environmentIsQueriedWithMultipleProfilesFromCommaSeparatedModelName() throws ModelHandlerException {
|
||||||
given(this.attributes.getValue(Action.NAME_ATTRIBUTE)).willReturn("dev,qa");
|
SpringProfileModel model = new SpringProfileModel();
|
||||||
this.action.begin(this.interpretationContext, null, this.attributes);
|
model.setName("dev,qa");
|
||||||
|
this.action.handle(this.interpretationContext, model);
|
||||||
ArgumentCaptor<Profiles> profiles = ArgumentCaptor.forClass(Profiles.class);
|
ArgumentCaptor<Profiles> profiles = ArgumentCaptor.forClass(Profiles.class);
|
||||||
then(this.environment).should().acceptsProfiles(profiles.capture());
|
then(this.environment).should().acceptsProfiles(profiles.capture());
|
||||||
List<String> profileNames = new ArrayList<>();
|
List<String> profileNames = new ArrayList<>();
|
||||||
@ -88,10 +86,11 @@ class SpringProfileActionTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void environmentIsQueriedWithResolvedValueWhenNameAttributeUsesAPlaceholder() throws ActionException {
|
void environmentIsQueriedWithResolvedValueWhenModelNameUsesAPlaceholder() throws ModelHandlerException {
|
||||||
given(this.attributes.getValue(Action.NAME_ATTRIBUTE)).willReturn("${profile}");
|
SpringProfileModel model = new SpringProfileModel();
|
||||||
|
model.setName("${profile}");
|
||||||
this.context.putProperty("profile", "dev");
|
this.context.putProperty("profile", "dev");
|
||||||
this.action.begin(this.interpretationContext, null, this.attributes);
|
this.action.handle(this.interpretationContext, model);
|
||||||
ArgumentCaptor<Profiles> profiles = ArgumentCaptor.forClass(Profiles.class);
|
ArgumentCaptor<Profiles> profiles = ArgumentCaptor.forClass(Profiles.class);
|
||||||
then(this.environment).should().acceptsProfiles(profiles.capture());
|
then(this.environment).should().acceptsProfiles(profiles.capture());
|
||||||
List<String> profileNames = new ArrayList<>();
|
List<String> profileNames = new ArrayList<>();
|
||||||
@ -104,11 +103,12 @@ class SpringProfileActionTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void environmentIsQueriedWithResolvedValuesFromCommaSeparatedNameNameAttributeWithPlaceholders()
|
void environmentIsQueriedWithResolvedValuesFromCommaSeparatedNameNameAttributeWithPlaceholders()
|
||||||
throws ActionException {
|
throws ModelHandlerException {
|
||||||
given(this.attributes.getValue(Action.NAME_ATTRIBUTE)).willReturn("${profile1},${profile2}");
|
SpringProfileModel model = new SpringProfileModel();
|
||||||
|
model.setName("${profile1},${profile2}");
|
||||||
this.context.putProperty("profile1", "dev");
|
this.context.putProperty("profile1", "dev");
|
||||||
this.context.putProperty("profile2", "qa");
|
this.context.putProperty("profile2", "qa");
|
||||||
this.action.begin(this.interpretationContext, null, this.attributes);
|
this.action.handle(this.interpretationContext, model);
|
||||||
ArgumentCaptor<Profiles> profiles = ArgumentCaptor.forClass(Profiles.class);
|
ArgumentCaptor<Profiles> profiles = ArgumentCaptor.forClass(Profiles.class);
|
||||||
then(this.environment).should().acceptsProfiles(profiles.capture());
|
then(this.environment).should().acceptsProfiles(profiles.capture());
|
||||||
List<String> profileNames = new ArrayList<>();
|
List<String> profileNames = new ArrayList<>();
|
@ -3,6 +3,12 @@
|
|||||||
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
|
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
|
||||||
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
|
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
|
||||||
<suppressions>
|
<suppressions>
|
||||||
|
<suppress files="ConditionEvaluationReportLoggingListenerTests\.java" checks="IllegalImport" />
|
||||||
|
<suppress files="LoggingApplicationListenerTests\.java" checks="IllegalImport" />
|
||||||
|
<suppress files="LogbackInitializer\.java" checks="IllegalImport" />
|
||||||
|
<suppress files="LogbackLoggingSystem\.java" checks="IllegalImport" />
|
||||||
|
<suppress files="LogbackLoggingSystemTests\.java" checks="IllegalImport" />
|
||||||
|
<suppress files="MeterRegistryConfigurerIntegrationTests\.java" checks="IllegalImport" />
|
||||||
<suppress files="SpringApplicationTests\.java" checks="FinalClass" />
|
<suppress files="SpringApplicationTests\.java" checks="FinalClass" />
|
||||||
<suppress files=".+Configuration\.java" checks="HideUtilityClassConstructor" />
|
<suppress files=".+Configuration\.java" checks="HideUtilityClassConstructor" />
|
||||||
<suppress files=".+Application\.java" checks="HideUtilityClassConstructor" />
|
<suppress files=".+Application\.java" checks="HideUtilityClassConstructor" />
|
||||||
|
Loading…
Reference in New Issue
Block a user