diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml
index 0ef5930a77c..ef0ecf425de 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml
@@ -37,6 +37,11 @@
spring-context
+
+ ch.qos.logback
+ logback-classic
+ true
+
com.fasterxml.jackson.dataformat
jackson-dataformat-xml
@@ -379,11 +384,6 @@
spring-boot-test-support
test
-
- ch.qos.logback
- logback-classic
- test
-
io.projectreactor
reactor-test
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java
index bfd9f8aae37..731b172e681 100644
--- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java
@@ -16,6 +16,7 @@
package org.springframework.boot.actuate.autoconfigure.metrics;
+import ch.qos.logback.classic.LoggerContext;
import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics;
@@ -26,17 +27,25 @@ import io.micrometer.core.instrument.binder.logging.LogbackMetrics;
import io.micrometer.core.instrument.binder.system.FileDescriptorMetrics;
import io.micrometer.core.instrument.binder.system.ProcessorMetrics;
import io.micrometer.core.instrument.binder.system.UptimeMetrics;
+import org.slf4j.ILoggerFactory;
+import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionMessage;
+import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
+import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Micrometer-based metrics.
@@ -103,7 +112,9 @@ public class MetricsAutoConfiguration {
static class MeterBindersConfiguration {
@Bean
- @ConditionalOnClass(name = "ch.qos.logback.classic.Logger")
+ @ConditionalOnClass(name = { "ch.qos.logback.classic.LoggerContext",
+ "org.slf4j.LoggerFactory" })
+ @Conditional(LogbackLoggingCondition.class)
@ConditionalOnMissingBean(LogbackMetrics.class)
@ConditionalOnProperty(value = "management.metrics.binders.logback.enabled", matchIfMissing = true)
public LogbackMetrics logbackMetrics() {
@@ -133,4 +144,23 @@ public class MetricsAutoConfiguration {
}
+ static class LogbackLoggingCondition extends SpringBootCondition {
+
+ @Override
+ public ConditionOutcome getMatchOutcome(ConditionContext context,
+ AnnotatedTypeMetadata metadata) {
+ ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
+ ConditionMessage.Builder message = ConditionMessage
+ .forCondition("LogbackLoggingCondition");
+ if (loggerFactory instanceof LoggerContext) {
+ return ConditionOutcome.match(
+ message.because("ILoggerFactory is a Logback LoggerContext"));
+ }
+ return ConditionOutcome
+ .noMatch(message.because("ILoggerFactory is an instance of "
+ + loggerFactory.getClass().getCanonicalName()));
+ }
+
+ }
+
}
diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationWithLog4j2AndLogbackTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationWithLog4j2AndLogbackTests.java
new file mode 100644
index 00000000000..a56fe1cbe29
--- /dev/null
+++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationWithLog4j2AndLogbackTests.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012-2018 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
+ *
+ * http://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.actuate.autoconfigure.metrics;
+
+import io.micrometer.core.instrument.binder.logging.LogbackMetrics;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport;
+import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportMessage;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.boot.testsupport.runner.classpath.ClassPathOverrides;
+import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link MetricsAutoConfiguration} when both Log4j2 and Logback are on the
+ * classpath.
+ *
+ * @author Andy Wilkinson
+ */
+@RunWith(ModifiedClassPathRunner.class)
+@ClassPathOverrides({ "org.apache.logging.log4j:log4j-core:2.9.0",
+ "org.apache.logging.log4j:log4j-slf4j-impl:2.9.0" })
+public class MetricsAutoConfigurationWithLog4j2AndLogbackTests {
+
+ private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class));
+
+ @Test
+ public void doesNotConfigureLogbackMetrics() {
+ this.contextRunner.run((context) -> {
+ System.out.println(
+ new ConditionEvaluationReportMessage(ConditionEvaluationReport
+ .get((ConfigurableListableBeanFactory) context
+ .getAutowireCapableBeanFactory())));
+ assertThat(context).doesNotHaveBean(LogbackMetrics.class);
+ });
+ }
+
+}