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 f9674a61e30..0978c0c3092 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 @@ -63,22 +63,21 @@ import com.codahale.metrics.MetricRegistry; * periodic basis) using an {@link Exporter}, most implementations of which have * optimizations for sending data to remote repositories. *

- * If Spring Messaging is on the classpath a {@link MessageChannel} called - * "metricsChannel" is also created (unless one already exists) and all metric update - * events are published additionally as messages on that channel. Additional analysis or - * actions can be taken by clients subscribing to that channel. + * If Spring Messaging is on the classpath and a {@link MessageChannel} called + * "metricsChannel" is also available, all metric update events are published additionally + * as messages on that channel. Additional analysis or actions can be taken by clients + * subscribing to that channel. *

- * In addition if Codahale's metrics library is on the classpath a {@link MetricRegistry} - * will be created and wired up to the counter and gauge services in addition to the basic - * repository. Users can create Codahale metrics by prefixing their metric names with the - * appropriate type (e.g. "histogram.*", "meter.*") and sending them to the standard - * GaugeService or CounterService. + * In addition if Dropwizard's metrics library is on the classpath a + * {@link MetricRegistry} will be created and the default counter and gauge services will + * switch to using it instead of the default repository. Users can create "special" + * Dropwizard metrics by prefixing their metric names with the appropriate type (e.g. + * "histogram.*", "meter.*". "timer.*") and sending them to the GaugeService + * or CounterService. *

* By default all metric updates go to all {@link MetricWriter} instances in the - * application context. To change this behaviour define your own metric writer bean called - * "primaryMetricWriter", mark it @Primary, and this one will receive all - * updates from the default counter and gauge services. Alternatively you can provide your - * own counter and gauge services and wire them to whichever writer you choose. + * application context via a {@link MetricCopyExporter} firing every 5 seconds (disable + * this by setting spring.metrics.export.enabled=false). * * @see GaugeService * @see CounterService diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricsDropwizardAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricsDropwizardAutoConfiguration.java index 7ba198ce4d6..14e29f2b44b 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricsDropwizardAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricsDropwizardAutoConfiguration.java @@ -20,8 +20,8 @@ import org.springframework.boot.actuate.endpoint.MetricReaderPublicMetrics; import org.springframework.boot.actuate.endpoint.PublicMetrics; import org.springframework.boot.actuate.metrics.CounterService; import org.springframework.boot.actuate.metrics.GaugeService; +import org.springframework.boot.actuate.metrics.dropwizard.DropwizardMetricServices; import org.springframework.boot.actuate.metrics.reader.MetricRegistryMetricReader; -import org.springframework.boot.actuate.metrics.writer.DropwizardMetricServices; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/MetricsMvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/MetricsMvcEndpoint.java index 5d1b4c054a7..ae54c50ca98 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/MetricsMvcEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/MetricsMvcEndpoint.java @@ -56,21 +56,21 @@ public class MetricsMvcEndpoint extends EndpointMvcAdapter { /** * {@link NamePatternFilter} for the Map source. */ - private class NamePatternMapFilter extends NamePatternFilter> { + private class NamePatternMapFilter extends NamePatternFilter> { - public NamePatternMapFilter(Map source) { + public NamePatternMapFilter(Map source) { super(source); } @Override - protected void getNames(Map source, NameCallback callback) { + protected void getNames(Map source, NameCallback callback) { for (String name : source.keySet()) { callback.addName(name); } } @Override - protected Object getValue(Map source, String name) { + protected Object getValue(Map source, String name) { Object value = source.get(name); if (value == null) { throw new NoSuchMetricException("No such metric: " + name); diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/DropwizardMetricServices.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/dropwizard/DropwizardMetricServices.java similarity index 97% rename from spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/DropwizardMetricServices.java rename to spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/dropwizard/DropwizardMetricServices.java index 0116268c4ea..d9491c714ee 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/DropwizardMetricServices.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/dropwizard/DropwizardMetricServices.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.writer; +package org.springframework.boot.actuate.metrics.dropwizard; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/dropwizard/package-info.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/dropwizard/package-info.java new file mode 100644 index 00000000000..bab7b17850a --- /dev/null +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/dropwizard/package-info.java @@ -0,0 +1,21 @@ +/* + * 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. + */ + +/** + * Metrics integration with Dropwizard Metrics. + */ +package org.springframework.boot.actuate.metrics.dropwizard; + diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/MetricCopyExporter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/MetricCopyExporter.java index 9d5fb729ff1..b218eef9f46 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/MetricCopyExporter.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/MetricCopyExporter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2013 the original author or authors. + * 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. @@ -17,10 +17,12 @@ package org.springframework.boot.actuate.metrics.export; import java.util.Collection; +import java.util.Iterator; import org.springframework.boot.actuate.metrics.Metric; import org.springframework.boot.actuate.metrics.reader.MetricReader; import org.springframework.boot.actuate.metrics.writer.MetricWriter; +import org.springframework.util.PatternMatchUtils; /** * {@link Exporter} that "exports" by copying metric data from a source @@ -34,10 +36,22 @@ public class MetricCopyExporter extends AbstractMetricExporter { private final MetricWriter writer; + private String[] includes = new String[0]; + + private String[] excludes = new String[0]; + public MetricCopyExporter(MetricReader reader, MetricWriter writer) { this(reader, writer, ""); } + public void setIncludes(String... includes) { + this.includes = includes; + } + + public void setExcludes(String... excludes) { + this.excludes = excludes; + } + public MetricCopyExporter(MetricReader reader, MetricWriter writer, String prefix) { super(prefix); this.reader = reader; @@ -46,7 +60,16 @@ public class MetricCopyExporter extends AbstractMetricExporter { @Override protected Iterable> next(String group) { - return this.reader.findAll(); + if (this.includes.length == 0 && this.excludes.length == 0) { + return this.reader.findAll(); + } + return new Iterable>() { + @Override + public Iterator> iterator() { + return new PatternMatchingIterator(MetricCopyExporter.this.reader + .findAll().iterator()); + } + }; } @Override @@ -56,4 +79,56 @@ public class MetricCopyExporter extends AbstractMetricExporter { } } + private class PatternMatchingIterator implements Iterator> { + + private Metric buffer = null; + private Iterator> iterator; + + public PatternMatchingIterator(Iterator> iterator) { + this.iterator = iterator; + } + + @Override + public boolean hasNext() { + if (this.buffer != null) { + return true; + } + this.buffer = findNext(); + return this.buffer != null; + } + + private Metric findNext() { + Metric metric = null; + boolean matched = false; + while (this.iterator.hasNext() && !matched) { + metric = this.iterator.next(); + if (MetricCopyExporter.this.includes.length == 0) { + matched = true; + } + else { + for (String pattern : MetricCopyExporter.this.includes) { + if (PatternMatchUtils.simpleMatch(pattern, metric.getName())) { + matched = true; + break; + } + } + } + for (String pattern : MetricCopyExporter.this.excludes) { + if (PatternMatchUtils.simpleMatch(pattern, metric.getName())) { + matched = false; + break; + } + } + } + return matched ? metric : null; + + } + + @Override + public Metric next() { + Metric metric = this.buffer; + this.buffer = null; + return metric; + } + }; } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/package-info.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/package-info.java index 714677991c0..0f34887c2a8 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/package-info.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/package-info.java @@ -15,7 +15,7 @@ */ /** - * Metrics integration with Dropwizard Metrics. + * Support for writing metrics */ package org.springframework.boot.actuate.metrics.writer; diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/MetricRepositoryAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/MetricRepositoryAutoConfigurationTests.java index 29959948cf9..7e366b4dbe9 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/MetricRepositoryAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/MetricRepositoryAutoConfigurationTests.java @@ -25,10 +25,10 @@ import org.springframework.boot.actuate.metrics.GaugeService; import org.springframework.boot.actuate.metrics.Metric; import org.springframework.boot.actuate.metrics.buffer.BufferCounterService; import org.springframework.boot.actuate.metrics.buffer.BufferGaugeService; +import org.springframework.boot.actuate.metrics.dropwizard.DropwizardMetricServices; import org.springframework.boot.actuate.metrics.export.MetricCopyExporter; import org.springframework.boot.actuate.metrics.reader.MetricReader; import org.springframework.boot.actuate.metrics.reader.PrefixMetricReader; -import org.springframework.boot.actuate.metrics.writer.DropwizardMetricServices; import org.springframework.boot.actuate.metrics.writer.MetricWriter; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration; diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/DropwizardCounterServiceSpeedTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/DropwizardCounterServiceSpeedTests.java index 9f2b697f432..5005d979069 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/DropwizardCounterServiceSpeedTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/DropwizardCounterServiceSpeedTests.java @@ -34,9 +34,9 @@ import org.junit.experimental.theories.Theory; import org.junit.runner.RunWith; import org.springframework.boot.actuate.metrics.CounterService; import org.springframework.boot.actuate.metrics.Metric; +import org.springframework.boot.actuate.metrics.dropwizard.DropwizardMetricServices; import org.springframework.boot.actuate.metrics.reader.MetricReader; import org.springframework.boot.actuate.metrics.reader.MetricRegistryMetricReader; -import org.springframework.boot.actuate.metrics.writer.DropwizardMetricServices; import org.springframework.lang.UsesJava8; import org.springframework.util.StopWatch; diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/writer/DropwizardMetricServicesTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/dropwizard/DropwizardMetricServicesTests.java similarity index 96% rename from spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/writer/DropwizardMetricServicesTests.java rename to spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/dropwizard/DropwizardMetricServicesTests.java index 068ebffc85b..13b499b4b72 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/writer/DropwizardMetricServicesTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/dropwizard/DropwizardMetricServicesTests.java @@ -14,12 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.actuate.metrics.writer; +package org.springframework.boot.actuate.metrics.dropwizard; import java.util.ArrayList; import java.util.List; import org.junit.Test; +import org.springframework.boot.actuate.metrics.dropwizard.DropwizardMetricServices; import com.codahale.metrics.Gauge; import com.codahale.metrics.MetricRegistry; diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/MetricCopyExporterTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/MetricCopyExporterTests.java index 9ad012f1451..e8b1e50d3f4 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/MetricCopyExporterTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/MetricCopyExporterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2013 the original author or authors. + * 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. @@ -41,6 +41,33 @@ public class MetricCopyExporterTests { assertEquals(1, this.writer.count()); } + @Test + public void exportIncludes() { + this.exporter.setIncludes("*"); + this.reader.set(new Metric("foo", 2.3)); + this.exporter.export(); + assertEquals(1, this.writer.count()); + } + + @Test + public void exportExcludesWithIncludes() { + this.exporter.setIncludes("*"); + this.exporter.setExcludes("foo"); + this.reader.set(new Metric("foo", 2.3)); + this.reader.set(new Metric("bar", 2.4)); + this.exporter.export(); + assertEquals(1, this.writer.count()); + } + + @Test + public void exportExcludesDefaultIncludes() { + this.exporter.setExcludes("foo"); + this.reader.set(new Metric("foo", 2.3)); + this.reader.set(new Metric("bar", 2.4)); + this.exporter.export(); + assertEquals(1, this.writer.count()); + } + @Test public void timestamp() { this.reader.set(new Metric("foo", 2.3));