From 58c8c4d56a1f2205e03a58a70edc490cea833945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Thu, 2 Nov 2017 14:10:14 +0100 Subject: [PATCH] Add auto-configuration for RabbitMQ metrics See gh-10887 --- .../metrics/MetricsAutoConfiguration.java | 20 +++++++ .../MetricsAutoConfigurationTests.java | 23 ++++++++ .../actuate/metrics/amqp/RabbitMetrics.java | 53 +++++++++++++++++++ .../actuate/metrics/amqp/package-info.java | 20 +++++++ .../autoconfigure/amqp/RabbitProperties.java | 16 +++++- .../spring-boot-dependencies/pom.xml | 2 +- 6 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/amqp/RabbitMetrics.java create mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/amqp/package-info.java 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 ec7742ba0c..0bf3e513e5 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 @@ -19,12 +19,15 @@ package org.springframework.boot.actuate.autoconfigure.metrics; import java.util.Collection; import java.util.Collections; +import com.rabbitmq.client.Channel; import io.micrometer.core.annotation.Timed; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.binder.MeterBinder; import io.micrometer.core.instrument.composite.CompositeMeterRegistry; +import org.springframework.amqp.rabbit.connection.AbstractConnectionFactory; +import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint; import org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsConfiguration; @@ -43,13 +46,16 @@ import org.springframework.boot.actuate.autoconfigure.metrics.reactive.server.We import org.springframework.boot.actuate.autoconfigure.metrics.web.client.RestTemplateMetricsConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.web.servlet.WebMvcMetricsConfiguration; import org.springframework.boot.actuate.metrics.MetricsEndpoint; +import org.springframework.boot.actuate.metrics.amqp.RabbitMetrics; import org.springframework.boot.actuate.metrics.integration.SpringIntegrationMetrics; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration; +import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 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.SearchStrategy; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; @@ -66,6 +72,7 @@ import org.springframework.integration.support.management.IntegrationManagementC * @since 2.0.0 * @author Jon Schneider * @author Stephane Nicoll + * @author Arnaud Cogoluègnes */ @Configuration @ConditionalOnClass(Timed.class) @@ -132,6 +139,19 @@ public class MetricsAutoConfiguration { } + @Configuration + @ConditionalOnClass({ RabbitTemplate.class, Channel.class }) + @ConditionalOnBean(AbstractConnectionFactory.class) + @ConditionalOnProperty(prefix = "spring.rabbitmq", name = "metrics", matchIfMissing = true) + static class MetricsRabbitConfiguration { + + @Bean + public RabbitMetrics rabbitMetrics(AbstractConnectionFactory connectionFactory) { + return new RabbitMetrics(connectionFactory.getRabbitConnectionFactory()); + } + + } + @Configuration static class MeterRegistryConfigurationSupport { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationTests.java index 30b7341e0c..900c080d73 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationTests.java @@ -25,6 +25,7 @@ import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -37,6 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link MetricsAutoConfiguration}. * * @author Stephane Nicoll + * @author Arnaud Cogoluègnes */ public class MetricsAutoConfigurationTests { @@ -107,6 +109,27 @@ public class MetricsAutoConfigurationTests { }); } + @Test + public void rabbitmqNativeConnectionFactoryIsInstrumented() { + this.contextRunner + .withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class)) + .run((context) -> { + MeterRegistry registry = context.getBean(MeterRegistry.class); + assertThat(registry.find("rabbitmq.connections").meter()).isPresent(); + }); + } + + @Test + public void rabbitmqNativeConnectionFactoryInstrumentationCanBeDisabled() { + this.contextRunner + .withConfiguration(AutoConfigurations.of(RabbitAutoConfiguration.class)) + .withPropertyValues("spring.rabbitmq.metrics=false") + .run((context) -> { + MeterRegistry registry = context.getBean(MeterRegistry.class); + assertThat(registry.find("rabbitmq.connections").meter()).isNotPresent(); + }); + } + @Configuration static class RegistryConfiguration { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/amqp/RabbitMetrics.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/amqp/RabbitMetrics.java new file mode 100644 index 0000000000..7a964a1138 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/amqp/RabbitMetrics.java @@ -0,0 +1,53 @@ +/* + * 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.metrics.amqp; + +import java.util.Collections; + +import com.rabbitmq.client.ConnectionFactory; +import com.rabbitmq.client.impl.MicrometerMetricsCollector; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.binder.MeterBinder; + +/** + * A {@link MeterBinder} for RabbitMQ Java Client metrics. + * + * @author Arnaud Cogoluègnes + * @since 2.0.0 + */ +public class RabbitMetrics implements MeterBinder { + + private final Iterable tags; + + private final ConnectionFactory connectionFactory; + + public RabbitMetrics(ConnectionFactory connectionFactory) { + this(connectionFactory, Collections.emptyList()); + } + + public RabbitMetrics(ConnectionFactory connectionFactory, Iterable tags) { + this.connectionFactory = connectionFactory; + this.tags = tags; + } + + @Override + public void bindTo(MeterRegistry registry) { + this.connectionFactory.setMetricsCollector(new MicrometerMetricsCollector(registry, "rabbitmq", this.tags)); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/amqp/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/amqp/package-info.java new file mode 100644 index 0000000000..8c56a721d7 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/amqp/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Actuator support for RabbitMQ Java Client metrics. + */ +package org.springframework.boot.actuate.metrics.amqp; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java index ab9fd4d1e7..3fbf85437a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * 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. @@ -37,6 +37,7 @@ import org.springframework.util.StringUtils; * @author Andy Wilkinson * @author Josh Thornhill * @author Gary Russell + * @author Arnaud Cogoluègnes */ @ConfigurationProperties(prefix = "spring.rabbitmq") public class RabbitProperties { @@ -112,6 +113,11 @@ public class RabbitProperties { private List
parsedAddresses; + /** + * Enable metrics. + */ + private boolean metrics = true; + public String getHost() { return this.host; } @@ -307,6 +313,14 @@ public class RabbitProperties { return this.template; } + public boolean isMetrics() { + return this.metrics; + } + + public void setMetrics(boolean metrics) { + this.metrics = metrics; + } + public static class Ssl { /** diff --git a/spring-boot-project/spring-boot-dependencies/pom.xml b/spring-boot-project/spring-boot-dependencies/pom.xml index f212b227ba..56c2fd30d1 100644 --- a/spring-boot-project/spring-boot-dependencies/pom.xml +++ b/spring-boot-project/spring-boot-dependencies/pom.xml @@ -126,7 +126,7 @@ 42.1.4 2.3.0 4.1.4 - 5.1.1 + 5.1.2 Bismuth-BUILD-SNAPSHOT 3.0.6 1.0.2