diff --git a/spring-boot-actuator/pom.xml b/spring-boot-actuator/pom.xml
index b2df4ffca0b..f81e2485e34 100644
--- a/spring-boot-actuator/pom.xml
+++ b/spring-boot-actuator/pom.xml
@@ -127,6 +127,16 @@
spring-data-solr
true
+
+ org.springframework.integration
+ spring-integration-jmx
+ true
+
+
+ org.springframework.integration
+ spring-integration-core
+ true
+
org.elasticsearch
elasticsearch
diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ActuatorMetricRepository.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ActuatorMetricReader.java
similarity index 96%
rename from spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ActuatorMetricRepository.java
rename to spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ActuatorMetricReader.java
index d18bcf68a51..1618aef333c 100644
--- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ActuatorMetricRepository.java
+++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ActuatorMetricReader.java
@@ -37,6 +37,6 @@ import org.springframework.beans.factory.annotation.Qualifier;
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
-public @interface ActuatorMetricRepository {
+public @interface ActuatorMetricReader {
}
diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ActuatorMetricWriter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ActuatorMetricWriter.java
new file mode 100644
index 00000000000..61b3d26ddc2
--- /dev/null
+++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ActuatorMetricWriter.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2012-2015 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;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+
+/**
+ * Qualifier annotation for a metric repository that is used by the actuator (to
+ * distinguish it from others that might be installed by the user).
+ *
+ * @author Dave Syer
+ */
+@Qualifier
+@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE,
+ ElementType.ANNOTATION_TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+public @interface ActuatorMetricWriter {
+
+}
diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricExportAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricExportAutoConfiguration.java
index 7c6672d7ef0..20b6db54252 100644
--- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricExportAutoConfiguration.java
+++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricExportAutoConfiguration.java
@@ -18,6 +18,7 @@ package org.springframework.boot.actuate.autoconfigure;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
@@ -48,11 +49,11 @@ public class MetricExportAutoConfiguration {
private MetricExportProperties metrics;
@Autowired(required = false)
- @ActuatorMetricRepository
- private MetricWriter actuatorMetricRepository;
+ @ActuatorMetricWriter
+ private List actuatorMetrics = Collections.emptyList();
@Autowired(required = false)
- @ActuatorMetricRepository
+ @ActuatorMetricReader
private MetricReader reader;
@Bean
@@ -61,12 +62,9 @@ public class MetricExportAutoConfiguration {
Map writers = new HashMap();
if (this.reader != null) {
writers.putAll(this.writers);
- if (this.actuatorMetricRepository != null
- && writers.containsValue(this.actuatorMetricRepository)) {
- for (String name : this.writers.keySet()) {
- if (writers.get(name).equals(this.actuatorMetricRepository)) {
- writers.remove(name);
- }
+ for (String name : this.writers.keySet()) {
+ if (this.actuatorMetrics.contains(writers.get(name))) {
+ writers.remove(name);
}
}
MetricExporters exporters = new MetricExporters(this.reader, writers,
@@ -80,5 +78,4 @@ public class MetricExportAutoConfiguration {
}
};
}
-
}
diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricRepositoryAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricRepositoryAutoConfiguration.java
index 1d1e8d148aa..c68f13482f8 100644
--- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricRepositoryAutoConfiguration.java
+++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricRepositoryAutoConfiguration.java
@@ -90,7 +90,7 @@ public class MetricRepositoryAutoConfiguration {
static class LegacyMetricServicesConfiguration {
@Autowired
- @ActuatorMetricRepository
+ @ActuatorMetricReader
private MetricWriter writer;
@Bean
@@ -125,7 +125,7 @@ public class MetricRepositoryAutoConfiguration {
}
@Bean
- @ActuatorMetricRepository
+ @ActuatorMetricReader
@ConditionalOnMissingBean
public BufferMetricReader actuatorMetricReader(CounterBuffers counters,
GaugeBuffers gauges) {
@@ -151,7 +151,7 @@ public class MetricRepositoryAutoConfiguration {
static class LegacyMetricRepositoryConfiguration {
@Bean
- @ActuatorMetricRepository
+ @ActuatorMetricReader
public InMemoryMetricRepository actuatorMetricRepository() {
return new InMemoryMetricRepository();
}
diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfiguration.java
index 4580e197c58..b3c0b8a3ba1 100644
--- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfiguration.java
+++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfiguration.java
@@ -16,6 +16,9 @@
package org.springframework.boot.actuate.autoconfigure;
+import java.util.Collections;
+import java.util.List;
+
import javax.servlet.Servlet;
import javax.sql.DataSource;
@@ -29,8 +32,9 @@ import org.springframework.boot.actuate.endpoint.PublicMetrics;
import org.springframework.boot.actuate.endpoint.RichGaugeReaderPublicMetrics;
import org.springframework.boot.actuate.endpoint.SystemPublicMetrics;
import org.springframework.boot.actuate.endpoint.TomcatPublicMetrics;
+import org.springframework.boot.actuate.metrics.integration.SpringIntegrationMetricReader;
+import org.springframework.boot.actuate.metrics.reader.CompositeMetricReader;
import org.springframework.boot.actuate.metrics.reader.MetricReader;
-import org.springframework.boot.actuate.metrics.repository.InMemoryMetricRepository;
import org.springframework.boot.actuate.metrics.rich.RichGaugeReader;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
@@ -38,12 +42,17 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnJava;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnJava.JavaVersion;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadataProvider;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.integration.monitor.IntegrationMBeanExporter;
+import org.springframework.lang.UsesJava7;
/**
* {@link EnableAutoConfiguration Auto-configuration} for {@link PublicMetrics}.
@@ -56,12 +65,13 @@ import org.springframework.context.annotation.Configuration;
@Configuration
@AutoConfigureBefore(EndpointAutoConfiguration.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, CacheAutoConfiguration.class,
- MetricRepositoryAutoConfiguration.class, CacheStatisticsAutoConfiguration.class })
+ MetricRepositoryAutoConfiguration.class, CacheStatisticsAutoConfiguration.class,
+ IntegrationAutoConfiguration.class })
public class PublicMetricsAutoConfiguration {
@Autowired(required = false)
- @ActuatorMetricRepository
- private MetricReader metricReader = new InMemoryMetricRepository();
+ @ActuatorMetricReader
+ private List metricReaders = Collections.emptyList();
@Bean
public SystemPublicMetrics systemPublicMetrics() {
@@ -70,7 +80,7 @@ public class PublicMetricsAutoConfiguration {
@Bean
public MetricReaderPublicMetrics metricReaderPublicMetrics() {
- return new MetricReaderPublicMetrics(this.metricReader);
+ return new MetricReaderPublicMetrics(new CompositeMetricReader(this.metricReaders.toArray(new MetricReader[0])));
}
@Bean
@@ -120,4 +130,21 @@ public class PublicMetricsAutoConfiguration {
}
+ @Configuration
+ @ConditionalOnClass(IntegrationMBeanExporter.class)
+ @ConditionalOnBean(IntegrationMBeanExporter.class)
+ @ConditionalOnJava(JavaVersion.SEVEN)
+ @UsesJava7
+ static class IntegrationMetricsConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ public MetricReaderPublicMetrics springIntegrationPublicMetrics(
+ IntegrationMBeanExporter exporter) {
+ return new MetricReaderPublicMetrics(new SpringIntegrationMetricReader(
+ exporter));
+ }
+
+ }
+
}
diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReader.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReader.java
new file mode 100644
index 00000000000..407e89c6b59
--- /dev/null
+++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReader.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2015 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.integration;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.springframework.boot.actuate.metrics.Metric;
+import org.springframework.boot.actuate.metrics.reader.MetricReader;
+import org.springframework.integration.monitor.IntegrationMBeanExporter;
+import org.springframework.integration.support.management.Statistics;
+import org.springframework.lang.UsesJava7;
+
+/**
+ * A {@link MetricReader} for Spring Integration metrics (as provided by spring-integration-jmx).
+ *
+ * @author Dave Syer
+ *
+ */
+@UsesJava7
+public class SpringIntegrationMetricReader implements MetricReader {
+
+ private final IntegrationMBeanExporter exporter;
+
+ public SpringIntegrationMetricReader(IntegrationMBeanExporter exporter) {
+ this.exporter = exporter;
+ }
+
+ @Override
+ public Metric> findOne(String metricName) {
+ return null;
+ }
+
+ @Override
+ public Iterable> findAll() {
+ List> metrics = new ArrayList>();
+ for (String name : exporter.getChannelNames()) {
+ metrics.addAll(getStatistics("integration.channel." + name + ".errorRate", exporter.getChannelErrorRate(name)));
+ metrics.addAll(getStatistics("integration.channel." + name + ".sendRate", exporter.getChannelSendRate(name)));
+ metrics.add(new Metric("integration.channel." + name + ".receiveCount", exporter.getChannelReceiveCountLong(name)));
+ }
+ for (String name : exporter.getHandlerNames()) {
+ metrics.addAll(getStatistics("integration.handler." + name + ".duration", exporter.getHandlerDuration(name)));
+ }
+ metrics.add(new Metric("integration.activeHandlerCount", exporter.getActiveHandlerCountLong()));
+ metrics.add(new Metric("integration.handlerCount", exporter.getHandlerCount()));
+ metrics.add(new Metric("integration.channelCount", exporter.getChannelCount()));
+ metrics.add(new Metric("integration.queuedMessageCount", exporter.getQueuedMessageCount()));
+ return metrics;
+ }
+
+ private Collection extends Metric>> getStatistics(String name, Statistics statistic) {
+ List> metrics = new ArrayList>();
+ metrics.add(new Metric(name + ".mean", statistic.getMean()));
+ metrics.add(new Metric(name + ".max", statistic.getMax()));
+ metrics.add(new Metric(name + ".min", statistic.getMin()));
+ metrics.add(new Metric(name + ".stdev", statistic.getStandardDeviation()));
+ metrics.add(new Metric(name + ".count", statistic.getCountLong()));
+ return metrics;
+ }
+
+ @Override
+ public long count() {
+ return exporter.getChannelCount()*11 + exporter.getHandlerCount()*5 + 4;
+ }
+
+}
diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderTests.java
new file mode 100644
index 00000000000..b14c5468f72
--- /dev/null
+++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderTests.java
@@ -0,0 +1,43 @@
+package org.springframework.boot.actuate.metrics.integration;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.actuate.metrics.integration.SpringIntegrationMetricReaderTests.TestConfiguration;
+import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration;
+import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
+import org.springframework.boot.test.IntegrationTest;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.integration.monitor.IntegrationMBeanExporter;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(classes=TestConfiguration.class)
+@IntegrationTest("spring.jmx.enabled=true")
+@DirtiesContext
+public class SpringIntegrationMetricReaderTests {
+
+ @Autowired
+ private SpringIntegrationMetricReader reader;
+
+ @Test
+ public void test() {
+ assertTrue(reader.count()>0);
+ }
+
+ @Configuration
+ @Import({JmxAutoConfiguration.class, IntegrationAutoConfiguration.class})
+ protected static class TestConfiguration {
+ @Bean
+ public SpringIntegrationMetricReader reader(IntegrationMBeanExporter exporter) {
+ return new SpringIntegrationMetricReader(exporter);
+ }
+ }
+
+}