diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ExportMetricReader.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ExportMetricReader.java index 6ddca1b12f..ca7f9d8f61 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ExportMetricReader.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ExportMetricReader.java @@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Qualifier; * others that might be installed by the user for other purposes). * * @author Dave Syer + * @since 1.3.0 */ @Qualifier @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ExportMetricWriter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ExportMetricWriter.java index 0f1ee64d0b..2762475e86 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ExportMetricWriter.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ExportMetricWriter.java @@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Qualifier; * the {@link ExportMetricReader} readers. * * @author Dave Syer + * @since 1.3.0 */ @Qualifier @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, 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 a6249fdf06..4737e3543c 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 @@ -29,6 +29,7 @@ import org.springframework.boot.actuate.metrics.export.MetricExporters; import org.springframework.boot.actuate.metrics.reader.CompositeMetricReader; import org.springframework.boot.actuate.metrics.reader.MetricReader; import org.springframework.boot.actuate.metrics.writer.MetricWriter; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -37,9 +38,13 @@ import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.config.ScheduledTaskRegistrar; +import org.springframework.util.CollectionUtils; /** + * {@link EnableAutoConfiguration Auto-configuration} for metrics export. + * * @author Dave Syer + * @since 1.3.0 */ @Configuration @EnableScheduling @@ -47,22 +52,39 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar; @EnableConfigurationProperties public class MetricExportAutoConfiguration { - @Autowired(required = false) - @ExportMetricWriter - private Map writers = Collections.emptyMap(); - @Autowired - private MetricExportProperties metrics; + private MetricExportProperties properties; + + @Autowired(required = false) + private MetricsEndpointMetricReader endpointReader; @Autowired(required = false) @ExportMetricReader private List readers; @Autowired(required = false) - private MetricsEndpointMetricReader endpointReader; + @ExportMetricWriter + private Map writers = Collections.emptyMap(); + + @Bean + @ConditionalOnMissingBean(name = "metricWritersMetricExporter") + public SchedulingConfigurer metricWritersMetricExporter() { + Map writers = new HashMap(); + MetricReader reader = this.endpointReader; + if (reader == null && !CollectionUtils.isEmpty(this.readers)) { + reader = new CompositeMetricReader( + this.readers.toArray(new MetricReader[this.readers.size()])); + } + if (reader != null) { + writers.putAll(this.writers); + return new MetricExporters(reader, writers, this.properties); + } + return new NoOpSchedulingConfigurer(); + } @Configuration protected static class MetricExportPropertiesConfiguration { + @Value("spring.metrics.${random.value:0000}.${spring.application.name:application}") private String prefix = "spring.metrics"; @@ -70,36 +92,18 @@ public class MetricExportAutoConfiguration { @ConditionalOnMissingBean public MetricExportProperties metricExportProperties() { MetricExportProperties export = new MetricExportProperties(); - export.getRedis().setPrefix(prefix); + export.getRedis().setPrefix(this.prefix); return export; } + } - @Bean - @ConditionalOnMissingBean(name = "metricWritersMetricExporter") - public SchedulingConfigurer metricWritersMetricExporter() { + private static class NoOpSchedulingConfigurer implements SchedulingConfigurer { - Map writers = new HashMap(); - - MetricReader reader = this.endpointReader; - if (reader == null && this.readers != null && !this.readers.isEmpty()) { - reader = new CompositeMetricReader( - this.readers.toArray(new MetricReader[this.readers.size()])); + @Override + public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { } - if (reader != null) { - writers.putAll(this.writers); - MetricExporters exporters = new MetricExporters(reader, writers, this.metrics); - return exporters; - } - - return new SchedulingConfigurer() { - - @Override - public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { - } - }; - } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricsChannelAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricsChannelAutoConfiguration.java index 154451a4e7..fd44d6b104 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricsChannelAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricsChannelAutoConfiguration.java @@ -32,6 +32,7 @@ import org.springframework.messaging.MessageChannel; * {@link MessageChannel}. * * @author Dave Syer + * @since 1.3.0 */ @Configuration @ConditionalOnClass(MessageChannel.class) @@ -46,4 +47,4 @@ public class MetricsChannelAutoConfiguration { return new MessageChannelMetricWriter(channel); } -} \ No newline at end of file +} 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 14e29f2b44..af8bc5b08e 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 @@ -35,6 +35,7 @@ import com.codahale.metrics.MetricRegistry; * {@link EnableAutoConfiguration Auto-configuration} for Dropwizard-based metrics. * * @author Dave Syer + * @since 1.3.0 */ @Configuration @ConditionalOnClass(MetricRegistry.class) @@ -60,4 +61,4 @@ public class MetricsDropwizardAutoConfiguration { return new MetricReaderPublicMetrics(reader); } -} \ No newline at end of file +} 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 eb9d1b0574..9c550cf725 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 @@ -80,7 +80,8 @@ public class PublicMetricsAutoConfiguration { @Bean public MetricReaderPublicMetrics metricReaderPublicMetrics() { - return new MetricReaderPublicMetrics(new CompositeMetricReader(this.metricReaders.toArray(new MetricReader[0]))); + return new MetricReaderPublicMetrics(new CompositeMetricReader( + this.metricReaders.toArray(new MetricReader[0]))); } @Bean diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/MetricsEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/MetricsEndpoint.java index 673c3a7be6..9e434402da 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/MetricsEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/MetricsEndpoint.java @@ -77,7 +77,7 @@ public class MetricsEndpoint extends AbstractEndpoint> { result.put(metric.getName(), metric.getValue()); } } - catch (Exception e) { + catch (Exception ex) { // Could not evaluate metrics } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/MetricsEndpointMetricReader.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/MetricsEndpointMetricReader.java index be756a7ee9..3944748bce 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/MetricsEndpointMetricReader.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/MetricsEndpointMetricReader.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.boot.actuate.endpoint; import java.util.ArrayList; @@ -25,12 +26,12 @@ import org.springframework.boot.actuate.metrics.Metric; import org.springframework.boot.actuate.metrics.reader.MetricReader; /** - * A {@link MetricReader} that pulls all current values out of the {@link MetricsEndpoint} - * . No timestamp information is available, so there is no way to check if the values are + * {@link MetricReader} that pulls all current values out of the {@link MetricsEndpoint}. + * No timestamp information is available, so there is no way to check if the values are * recent, and they all come out with the default (current time). - * - * @author Dave Syer * + * @author Dave Syer + * @since 1.3.0 */ public class MetricsEndpointMetricReader implements MetricReader { @@ -43,7 +44,7 @@ public class MetricsEndpointMetricReader implements MetricReader { @Override public Metric findOne(String metricName) { Metric metric = null; - Object value = endpoint.invoke().get(metricName); + Object value = this.endpoint.invoke().get(metricName); if (value != null) { metric = new Metric(metricName, (Number) value); } @@ -53,7 +54,7 @@ public class MetricsEndpointMetricReader implements MetricReader { @Override public Iterable> findAll() { List> metrics = new ArrayList>(); - Map values = endpoint.invoke(); + Map values = this.endpoint.invoke(); Date timestamp = new Date(); for (Entry entry : values.entrySet()) { String name = entry.getKey(); @@ -65,7 +66,7 @@ public class MetricsEndpointMetricReader implements MetricReader { @Override public long count() { - return endpoint.invoke().size(); + return this.endpoint.invoke().size(); } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/aggregate/AggregateMetricReader.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/aggregate/AggregateMetricReader.java index 2c8513503e..cb6b7a3f58 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/aggregate/AggregateMetricReader.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/aggregate/AggregateMetricReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 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. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.boot.actuate.metrics.aggregate; import java.util.HashSet; @@ -35,7 +36,7 @@ import org.springframework.util.StringUtils; * value. * * @author Dave Syer - * + * @since 1.3.0 */ public class AggregateMetricReader implements MetricReader { @@ -52,7 +53,6 @@ public class AggregateMetricReader implements MetricReader { /** * The number of period-separated keys to remove from the start of the input metric * names before aggregating. - * * @param truncate length of source metric prefixes */ public void setTruncateKeyLength(int truncate) { @@ -62,7 +62,6 @@ public class AggregateMetricReader implements MetricReader { /** * Prefix to apply to all output metrics. A period will be appended if no present in * the provided value. - * * @param prefix the prefix to use default "aggregator.") */ public void setPrefix(String prefix) { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/BufferCounterService.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/BufferCounterService.java index 34b4862b32..0b11d0ac19 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/BufferCounterService.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/BufferCounterService.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. @@ -25,6 +25,7 @@ import org.springframework.lang.UsesJava8; * Fast implementation of {@link CounterService} using {@link CounterBuffers}. * * @author Dave Syer + * @since 1.3.0 */ @UsesJava8 public class BufferCounterService implements CounterService { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/BufferGaugeService.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/BufferGaugeService.java index 3ef6d697ac..91a5d82883 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/BufferGaugeService.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/BufferGaugeService.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. @@ -25,6 +25,7 @@ import org.springframework.lang.UsesJava8; * Fast implementation of {@link GaugeService} using {@link GaugeBuffers}. * * @author Dave Syer + * @since 1.3.0 */ @UsesJava8 public class BufferGaugeService implements GaugeService { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/BufferMetricReader.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/BufferMetricReader.java index b3856bd15e..d59aee945f 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/BufferMetricReader.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/BufferMetricReader.java @@ -33,6 +33,7 @@ import org.springframework.lang.UsesJava8; * {@link GaugeBuffers}. * * @author Dave Syer + * @since 1.3.0 */ @UsesJava8 public class BufferMetricReader implements MetricReader, PrefixMetricReader { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/CounterBuffers.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/CounterBuffers.java index 96878be4c3..c46a687459 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/CounterBuffers.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/CounterBuffers.java @@ -28,6 +28,7 @@ import org.springframework.lang.UsesJava8; * Fast writes to in-memory metrics store using {@link LongBuffer}. * * @author Dave Syer + * @since 1.3.0 */ @UsesJava8 public class CounterBuffers { @@ -113,4 +114,5 @@ public class CounterBuffers { } consumer.accept(adder); } + } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/DoubleBuffer.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/DoubleBuffer.java index ec2d139abf..43389b85cf 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/DoubleBuffer.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/DoubleBuffer.java @@ -20,6 +20,7 @@ package org.springframework.boot.actuate.metrics.buffer; * Mutable buffer containing a double value and a timestamp. * * @author Dave Syer + * @since 1.3.0 */ public class DoubleBuffer { @@ -47,4 +48,5 @@ public class DoubleBuffer { public long getTimestamp() { return this.timestamp; } -} \ No newline at end of file + +} diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/GaugeBuffers.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/GaugeBuffers.java index 80cb065d91..a381a11e8a 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/GaugeBuffers.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/GaugeBuffers.java @@ -28,6 +28,7 @@ import org.springframework.lang.UsesJava8; * Fast writes to in-memory metrics store using {@link DoubleBuffer}. * * @author Dave Syer + * @since 1.3.0 */ @UsesJava8 public class GaugeBuffers { @@ -94,4 +95,5 @@ public class GaugeBuffers { } consumer.accept(value); } + } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/LongBuffer.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/LongBuffer.java index 08c2e97ef0..8d658a0554 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/LongBuffer.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/buffer/LongBuffer.java @@ -24,6 +24,7 @@ import org.springframework.lang.UsesJava8; * Mutable buffer containing a long adder (Java 8) and a timestamp. * * @author Dave Syer + * @since 1.3.0 */ @UsesJava8 public class LongBuffer { @@ -56,4 +57,5 @@ public class LongBuffer { public void add(long delta) { this.adder.add(delta); } -} \ No newline at end of file + +} diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/AbstractMetricExporter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/AbstractMetricExporter.java index ebabd48425..69b7cf76cb 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/AbstractMetricExporter.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/AbstractMetricExporter.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. @@ -33,26 +33,27 @@ import org.springframework.util.StringUtils; * export). * * @author Dave Syer + * @since 1.3.0 */ public abstract class AbstractMetricExporter implements Exporter { private static final Log logger = LogFactory.getLog(AbstractMetricExporter.class); - private volatile AtomicBoolean processing = new AtomicBoolean(false); + private final String prefix; private Date earliestTimestamp = new Date(); private boolean ignoreTimestamps = false; - private final String prefix; + private boolean sendLatest = true; + + private volatile AtomicBoolean processing = new AtomicBoolean(false); private Date latestTimestamp = new Date(0L); - private boolean sendLatest = true; - public AbstractMetricExporter(String prefix) { - this.prefix = !StringUtils.hasText(prefix) ? "" : (prefix.endsWith(".") ? prefix - : prefix + "."); + this.prefix = (!StringUtils.hasText(prefix) ? "" : (prefix.endsWith(".") ? prefix + : prefix + ".")); } /** @@ -73,7 +74,6 @@ public abstract class AbstractMetricExporter implements Exporter { /** * Send only the data that changed since the last export. - * * @param sendLatest the flag to set */ public void setSendLatest(boolean sendLatest) { @@ -82,47 +82,63 @@ public abstract class AbstractMetricExporter implements Exporter { @Override public void export() { - if (!this.processing.compareAndSet(false, true)) { - // skip a tick - return; - } - long latestTimestamp = 0; - try { - latestTimestamp = System.currentTimeMillis(); - for (String group : groups()) { - Collection> values = new ArrayList>(); - for (Metric metric : next(group)) { - Metric value = new Metric(this.prefix + metric.getName(), - metric.getValue(), metric.getTimestamp()); - Date timestamp = metric.getTimestamp(); - if (!this.ignoreTimestamps && this.earliestTimestamp.after(timestamp)) { - continue; - } - if (!this.ignoreTimestamps && this.sendLatest - && this.latestTimestamp.after(timestamp)) { - continue; - } - values.add(value); - } - if (!values.isEmpty()) { - write(group, values); - } - } - } - catch (Exception e) { - logger.warn("Could not write to MetricWriter: " + e.getClass() + ": " - + e.getMessage()); - } - finally { + if (this.processing.compareAndSet(false, true)) { + long latestTimestamp = System.currentTimeMillis(); try { + exportGroups(); + } + catch (Exception ex) { + logger.warn("Could not write to MetricWriter: " + ex.getClass() + ": " + + ex.getMessage()); + } + finally { this.latestTimestamp = new Date(latestTimestamp); - flush(); + flushQuietly(); + this.processing.set(false); } - catch (Exception e) { - logger.warn("Could not flush MetricWriter: " + e.getClass() + ": " - + e.getMessage()); + } + } + + private void exportGroups() { + for (String group : groups()) { + Collection> values = new ArrayList>(); + for (Metric metric : next(group)) { + Date timestamp = metric.getTimestamp(); + if (canExportTimestamp(timestamp)) { + values.add(getPrefixedMetric(metric)); + } } - this.processing.set(false); + if (!values.isEmpty()) { + write(group, values); + } + } + } + + private Metric getPrefixedMetric(Metric metric) { + String name = this.prefix + metric.getName(); + return new Metric(name, metric.getValue(), metric.getTimestamp()); + } + + private boolean canExportTimestamp(Date timestamp) { + if (this.ignoreTimestamps) { + return true; + } + if (this.earliestTimestamp.after(timestamp)) { + return false; + } + if (this.sendLatest && this.latestTimestamp.after(timestamp)) { + return false; + } + return true; + } + + private void flushQuietly() { + try { + flush(); + } + catch (Exception ex) { + logger.warn("Could not flush MetricWriter: " + ex.getClass() + ": " + + ex.getMessage()); } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/Exporter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/Exporter.java index d0c92a8b49..6664b8e3c6 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/Exporter.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/Exporter.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. @@ -25,6 +25,7 @@ package org.springframework.boot.actuate.metrics.export; * it using a {@code @Scheduled} annotation in a Spring ApplicationContext. * * @author Dave Syer + * @since 1.3.0 */ public interface Exporter { 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 69dbbe706d..246630c741 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 @@ -16,23 +16,33 @@ package org.springframework.boot.actuate.metrics.export; +import java.io.Flushable; +import java.lang.reflect.Method; import java.util.Collection; import java.util.Iterator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.boot.actuate.metrics.Metric; import org.springframework.boot.actuate.metrics.reader.MetricReader; +import org.springframework.boot.actuate.metrics.writer.CompositeMetricWriter; import org.springframework.boot.actuate.metrics.writer.MetricWriter; -import org.springframework.boot.actuate.metrics.writer.WriterUtils; +import org.springframework.util.ClassUtils; +import org.springframework.util.ObjectUtils; import org.springframework.util.PatternMatchUtils; +import org.springframework.util.ReflectionUtils; /** * {@link Exporter} that "exports" by copying metric data from a source * {@link MetricReader} to a destination {@link MetricWriter}. * * @author Dave Syer + * @since 1.3.0 */ public class MetricCopyExporter extends AbstractMetricExporter { + private static final Log logger = LogFactory.getLog(MetricCopyExporter.class); + private final MetricReader reader; private final MetricWriter writer; @@ -41,41 +51,53 @@ public class MetricCopyExporter extends AbstractMetricExporter { private String[] excludes = new String[0]; + /** + * Create a new {@link MetricCopyExporter} instance. + * @param reader the metric reader + * @param writer the metric writer + */ public MetricCopyExporter(MetricReader reader, MetricWriter writer) { this(reader, writer, ""); } - public void setIncludes(String... includes) { - if (includes != null) { - this.includes = includes; - } - } - - public void setExcludes(String... excludes) { - if (excludes != null) { - this.excludes = excludes; - } - } - + /** + * Create a new {@link MetricCopyExporter} instance. + * @param reader the metric reader + * @param writer the metric writer + * @param prefix the name prefix + */ public MetricCopyExporter(MetricReader reader, MetricWriter writer, String prefix) { super(prefix); this.reader = reader; this.writer = writer; } + /** + * Set the include patterns used to filter metrics. + * @param includes the include patterns + */ + public void setIncludes(String... includes) { + if (includes != null) { + this.includes = includes; + } + } + + /** + * Set the exclude patterns used to filter metrics. + * @param excludes the exclude patterns + */ + public void setExcludes(String... excludes) { + if (excludes != null) { + this.excludes = excludes; + } + } + @Override protected Iterable> next(String group) { - if ((this.includes == null || this.includes.length == 0) - && (this.excludes == null || this.excludes.length == 0)) { + if (ObjectUtils.isEmpty(this.includes) && ObjectUtils.isEmpty(this.excludes)) { return this.reader.findAll(); } - return new Iterable>() { - @Override - public Iterator> iterator() { - return new PatternMatchingIterator(MetricCopyExporter.this.reader - .findAll().iterator()); - } - }; + return new PatternMatchingIterable(MetricCopyExporter.this.reader); } @Override @@ -87,12 +109,52 @@ public class MetricCopyExporter extends AbstractMetricExporter { @Override public void flush() { - WriterUtils.flush(this.writer); + flush(this.writer); + } + + private void flush(MetricWriter writer) { + if (writer instanceof CompositeMetricWriter) { + for (MetricWriter child : (CompositeMetricWriter) writer) { + flush(child); + } + } + try { + if (ClassUtils.isPresent("java.io.Flushable", null)) { + if (writer instanceof Flushable) { + ((Flushable) writer).flush(); + return; + } + } + Method method = ReflectionUtils.findMethod(writer.getClass(), "flush"); + if (method != null) { + ReflectionUtils.invokeMethod(method, writer); + } + } + catch (Exception ex) { + logger.warn("Could not flush MetricWriter: " + ex.getClass() + ": " + + ex.getMessage()); + } + } + + private class PatternMatchingIterable implements Iterable> { + + private final MetricReader reader; + + public PatternMatchingIterable(MetricReader reader) { + this.reader = reader; + } + + @Override + public Iterator> iterator() { + return new PatternMatchingIterator(this.reader.findAll().iterator()); + } + } private class PatternMatchingIterator implements Iterator> { private Metric buffer = null; + private Iterator> iterator; public PatternMatchingIterator(Iterator> iterator) { @@ -109,33 +171,24 @@ public class MetricCopyExporter extends AbstractMetricExporter { } private Metric findNext() { - Metric metric = null; - boolean matched = false; - while (this.iterator.hasNext() && !matched) { - metric = this.iterator.next(); - if (MetricCopyExporter.this.includes == null - || MetricCopyExporter.this.includes.length == 0) { - matched = true; - } - else { - for (String pattern : MetricCopyExporter.this.includes) { - if (PatternMatchUtils.simpleMatch(pattern, metric.getName())) { - matched = true; - break; - } - } - } - if (MetricCopyExporter.this.excludes != null) { - for (String pattern : MetricCopyExporter.this.excludes) { - if (PatternMatchUtils.simpleMatch(pattern, metric.getName())) { - matched = false; - break; - } - } + while (this.iterator.hasNext()) { + Metric metric = this.iterator.next(); + if (isMatch(metric)) { + return metric; } } - return matched ? metric : null; + return null; + } + private boolean isMatch(Metric metric) { + String[] includes = MetricCopyExporter.this.includes; + String[] excludes = MetricCopyExporter.this.excludes; + String name = metric.getName(); + if (ObjectUtils.isEmpty(includes) + || PatternMatchUtils.simpleMatch(includes, name)) { + return !PatternMatchUtils.simpleMatch(excludes, name); + } + return false; } @Override @@ -144,5 +197,6 @@ public class MetricCopyExporter extends AbstractMetricExporter { this.buffer = null; return metric; } + }; } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/MetricExportProperties.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/MetricExportProperties.java index f666ba891e..eed59cdc57 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/MetricExportProperties.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/MetricExportProperties.java @@ -27,55 +27,29 @@ import org.springframework.util.PatternMatchUtils; import org.springframework.util.StringUtils; /** + * Configuration properties for metrics export. + * * @author Dave Syer + * @since 1.3.0 */ @ConfigurationProperties("spring.metrics.export") -public class MetricExportProperties extends Trigger { +public class MetricExportProperties extends TriggerProperties { /** * Flag to disable all metric exports (assuming any MetricWriters are available). */ private boolean enabled = true; - private Map triggers = new LinkedHashMap(); + private Map triggers = new LinkedHashMap(); private Redis redis = new Redis(); - /** - * Default values for trigger configuration for all writers. Can also be set by - * including a writer with name="*". - * - * @return the default trigger configuration - */ - public Trigger getDefault() { - return this; - } - - /** - * Configuration for triggers on individual named writers. Each value can individually - * specify a name pattern explicitly, or else the map key will be used if the name is - * not set. - * - * @return the writers - */ - public Map getTriggers() { - return this.triggers; - } - - public Redis getRedis() { - return redis; - } - - public void setRedis(Redis redis) { - this.redis = redis; - } - @PostConstruct public void setUpDefaults() { - Trigger defaults = this; - for (Entry entry : this.triggers.entrySet()) { + TriggerProperties defaults = this; + for (Entry entry : this.triggers.entrySet()) { String key = entry.getKey(); - SpecificTrigger value = entry.getValue(); + SpecificTriggerProperties value = entry.getValue(); if (value.getNames() == null || value.getNames().length == 0) { value.setNames(new String[] { key }); } @@ -86,7 +60,7 @@ public class MetricExportProperties extends Trigger { if (defaults.getDelayMillis() == null) { defaults.setDelayMillis(5000); } - for (Trigger value : this.triggers.values()) { + for (TriggerProperties value : this.triggers.values()) { if (value.isSendLatest() == null) { value.setSendLatest(defaults.isSendLatest()); } @@ -96,47 +70,56 @@ public class MetricExportProperties extends Trigger { } } + @Override public boolean isEnabled() { return this.enabled; } + @Override public void setEnabled(boolean enabled) { this.enabled = enabled; } + /** + * Configuration for triggers on individual named writers. Each value can individually + * specify a name pattern explicitly, or else the map key will be used if the name is + * not set. + * @return the writers + */ + public Map getTriggers() { + return this.triggers; + } + + public Redis getRedis() { + return this.redis; + } + + public void setRedis(Redis redis) { + this.redis = redis; + } + + /** + * Default values for trigger configuration for all writers. Can also be set by + * including a writer with {@code name="*"}. + * @return the default trigger configuration + */ + public TriggerProperties getDefault() { + return this; + } + /** * Find a matching trigger configuration. * @param name the bean name to match * @return a matching configuration if there is one */ - public Trigger findTrigger(String name) { - for (SpecificTrigger value : this.triggers.values()) { + public TriggerProperties findTrigger(String name) { + for (SpecificTriggerProperties value : this.triggers.values()) { if (PatternMatchUtils.simpleMatch(value.getNames(), name)) { return value; } } return this; } - - /** - * Trigger for specific bean names. - */ - public static class SpecificTrigger extends Trigger { - - /** - * Names (or patterns) for bean names that this configuration applies to. - */ - private String[] names; - - public String[] getNames() { - return this.names; - } - - public void setNames(String[] names) { - this.names = names; - } - - } public static class Redis { @@ -155,9 +138,9 @@ public class MetricExportProperties extends Trigger { * system sharing a redis repository. */ private String key = "keys.spring.metrics"; - + public String getPrefix() { - return prefix; + return this.prefix; } public void setPrefix(String prefix) { @@ -165,7 +148,7 @@ public class MetricExportProperties extends Trigger { } public String getKey() { - return key; + return this.key; } public void setKey(String key) { @@ -187,74 +170,3 @@ public class MetricExportProperties extends Trigger { } } - -class Trigger { - - /** - * Delay in milliseconds between export ticks. Metrics are exported to external - * sources on a schedule with this delay. - */ - private Long delayMillis; - - /** - * Flag to enable metric export (assuming a MetricWriter is available). - */ - private boolean enabled = true; - - /** - * Flag to switch off any available optimizations based on not exporting unchanged - * metric values. - */ - private Boolean sendLatest; - - /** - * List of patterns for metric names to include. - */ - private String[] includes; - - /** - * List of patterns for metric names to exclude. Applied after the includes. - */ - private String[] excludes; - - public String[] getIncludes() { - return this.includes; - } - - public void setIncludes(String[] includes) { - this.includes = includes; - } - - public void setExcludes(String[] excludes) { - this.excludes = excludes; - } - - public String[] getExcludes() { - return this.excludes; - } - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public Long getDelayMillis() { - return this.delayMillis; - } - - public void setDelayMillis(long delayMillis) { - this.delayMillis = delayMillis; - } - - public Boolean isSendLatest() { - return this.sendLatest; - } - - public void setSendLatest(boolean sendLatest) { - this.sendLatest = sendLatest; - } - -} diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/MetricExporters.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/MetricExporters.java index 395cd70edf..9d068d6f6c 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/MetricExporters.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/MetricExporters.java @@ -27,58 +27,68 @@ import org.springframework.scheduling.config.IntervalTask; import org.springframework.scheduling.config.ScheduledTaskRegistrar; /** + * {@link SchedulingConfigurer} to handle metrics {@link MetricCopyExporter export}. + * * @author Dave Syer + * @since 1.3.0 */ public class MetricExporters implements SchedulingConfigurer { - private MetricExportProperties export; + private final MetricReader reader; - private Map writers; + private final Map writers; - private Map exporters = new HashMap(); + private final MetricExportProperties properties; - private MetricReader reader; + private final Map exporters = new HashMap(); public MetricExporters(MetricReader reader, Map writers, - MetricExportProperties export) { + MetricExportProperties properties) { this.reader = reader; - this.export = export; this.writers = writers; + this.properties = properties; + } + + @Override + public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { + for (Entry entry : this.writers.entrySet()) { + String name = entry.getKey(); + MetricWriter writer = entry.getValue(); + TriggerProperties trigger = this.properties.findTrigger(name); + if (trigger != null) { + MetricCopyExporter exporter = getExporter(writer, trigger); + this.exporters.put(name, exporter); + ExportRunner runner = new ExportRunner(exporter); + IntervalTask task = new IntervalTask(runner, trigger.getDelayMillis(), + trigger.getDelayMillis()); + taskRegistrar.addFixedDelayTask(task); + } + } + } + + private MetricCopyExporter getExporter(MetricWriter writer, TriggerProperties trigger) { + MetricCopyExporter exporter = new MetricCopyExporter(this.reader, writer); + exporter.setIncludes(trigger.getIncludes()); + exporter.setExcludes(trigger.getExcludes()); + exporter.setSendLatest(trigger.isSendLatest()); + return exporter; } public Map getExporters() { return this.exporters; } - @Override - public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { + private static class ExportRunner implements Runnable { - for (Entry entry : this.writers.entrySet()) { - String name = entry.getKey(); - Trigger trigger = this.export.findTrigger(name); + private final MetricCopyExporter exporter; - if (trigger != null) { - - MetricWriter writer = entry.getValue(); - final MetricCopyExporter exporter = new MetricCopyExporter(this.reader, - writer); - if (trigger.getIncludes() != null || trigger.getExcludes() != null) { - exporter.setIncludes(trigger.getIncludes()); - exporter.setExcludes(trigger.getExcludes()); - } - exporter.setSendLatest(trigger.isSendLatest()); - - this.exporters.put(name, exporter); - - taskRegistrar.addFixedDelayTask(new IntervalTask(new Runnable() { - @Override - public void run() { - exporter.export(); - } - }, trigger.getDelayMillis(), trigger.getDelayMillis())); - - } + public ExportRunner(MetricCopyExporter exporter) { + this.exporter = exporter; + } + @Override + public void run() { + this.exporter.export(); } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/PrefixMetricGroupExporter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/PrefixMetricGroupExporter.java index dac8f16b11..2557f0056d 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/PrefixMetricGroupExporter.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/PrefixMetricGroupExporter.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. @@ -30,6 +30,7 @@ import org.springframework.boot.actuate.metrics.writer.PrefixMetricWriter; * all metrics whose name starts with a prefix (or all metrics if the prefix is empty). * * @author Dave Syer + * @since 1.3.0 */ public class PrefixMetricGroupExporter extends AbstractMetricExporter { @@ -64,6 +65,7 @@ public class PrefixMetricGroupExporter extends AbstractMetricExporter { } /** + * The groups to export. * @param groups the groups to set */ public void setGroups(Set groups) { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/RichGaugeExporter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/RichGaugeExporter.java index 62f8e76e16..4daf135be9 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/RichGaugeExporter.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/RichGaugeExporter.java @@ -30,14 +30,14 @@ import org.springframework.boot.actuate.metrics.writer.PrefixMetricWriter; /** * Exporter or converter for {@link RichGauge} data to a metric-based back end. Each gauge * measurement is stored as a set of related metrics with a common prefix (the name of the - * gauge), and suffixes that describe the data. For example, a gauge called - * foo is stored as - * [foo.min, foo.max. foo.val, foo.count, foo.avg, foo.alpha]. If the + * gauge), and suffixes that describe the data. For example, a gauge called {@code foo} is + * stored as {@code[foo.min, foo.max. foo.val, foo.count, foo.avg, foo.alpha]}. If the * {@link MetricWriter} provided is a {@link MultiMetricRepository} then the values for a * gauge will be stored as a group, and hence will be retrievable from the repository in a * single query (or optionally individually). * * @author Dave Syer + * @since 1.3.0 */ public class RichGaugeExporter extends AbstractMetricExporter { @@ -54,6 +54,7 @@ public class RichGaugeExporter extends AbstractMetricExporter { private static final String ALPHA = ".alpha"; private final RichGaugeReader reader; + private final PrefixMetricWriter writer; public RichGaugeExporter(RichGaugeReader reader, PrefixMetricWriter writer) { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/SpecificTriggerProperties.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/SpecificTriggerProperties.java new file mode 100644 index 0000000000..0b291dbb9e --- /dev/null +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/SpecificTriggerProperties.java @@ -0,0 +1,40 @@ +/* + * 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.metrics.export; + +/** + * Trigger for specific names or patterns. + * + * @author Dave Syer + * @since 1.3.0 + */ +public class SpecificTriggerProperties extends TriggerProperties { + + /** + * Names (or patterns) for bean names that this configuration applies to. + */ + private String[] names; + + public String[] getNames() { + return this.names; + } + + public void setNames(String[] names) { + this.names = names; + } + +} diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/TriggerProperties.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/TriggerProperties.java new file mode 100644 index 0000000000..513c0a0f37 --- /dev/null +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/export/TriggerProperties.java @@ -0,0 +1,94 @@ +/* + * 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.metrics.export; + +/** + * Abstract base class for trigger properties. + * + * @author Dave Syer + * @since 1.3.0 + */ +public abstract class TriggerProperties { + + /** + * Delay in milliseconds between export ticks. Metrics are exported to external + * sources on a schedule with this delay. + */ + private Long delayMillis; + + /** + * Flag to enable metric export (assuming a MetricWriter is available). + */ + private boolean enabled = true; + + /** + * Flag to switch off any available optimizations based on not exporting unchanged + * metric values. + */ + private Boolean sendLatest; + + /** + * List of patterns for metric names to include. + */ + private String[] includes; + + /** + * List of patterns for metric names to exclude. Applied after the includes. + */ + private String[] excludes; + + public String[] getIncludes() { + return this.includes; + } + + public void setIncludes(String[] includes) { + this.includes = includes; + } + + public void setExcludes(String[] excludes) { + this.excludes = excludes; + } + + public String[] getExcludes() { + return this.excludes; + } + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public Long getDelayMillis() { + return this.delayMillis; + } + + public void setDelayMillis(long delayMillis) { + this.delayMillis = delayMillis; + } + + public Boolean isSendLatest() { + return this.sendLatest; + } + + public void setSendLatest(boolean sendLatest) { + this.sendLatest = sendLatest; + } + +} 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 index 407e89c6b5..2936724e61 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2015 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. @@ -13,6 +13,7 @@ * 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; @@ -26,14 +27,15 @@ 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 + * A {@link MetricReader} for Spring Integration metrics (as provided by + * spring-integration-jmx). * + * @author Dave Syer + * @since 1.3.0 */ @UsesJava7 public class SpringIntegrationMetricReader implements MetricReader { - + private final IntegrationMBeanExporter exporter; public SpringIntegrationMetricReader(IntegrationMBeanExporter exporter) { @@ -47,23 +49,34 @@ public class SpringIntegrationMetricReader implements MetricReader { @Override public Iterable> findAll() { + IntegrationMBeanExporter exporter = this.exporter; 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))); + String prefix = "integration.channel." + name; + metrics.addAll(getStatistics(prefix + ".errorRate", + exporter.getChannelErrorRate(name))); + metrics.addAll(getStatistics(prefix + ".sendRate", + exporter.getChannelSendRate(name))); + metrics.add(new Metric(prefix + ".receiveCount", exporter + .getChannelReceiveCountLong(name))); } for (String name : exporter.getHandlerNames()) { - metrics.addAll(getStatistics("integration.handler." + name + ".duration", exporter.getHandlerDuration(name))); + 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; + 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> getStatistics(String name, Statistics statistic) { + private Collection> 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())); @@ -75,7 +88,9 @@ public class SpringIntegrationMetricReader implements MetricReader { @Override public long count() { - return exporter.getChannelCount()*11 + exporter.getHandlerCount()*5 + 4; + int totalChannelCount = this.exporter.getChannelCount() * 11; + int totalHandlerCount = this.exporter.getHandlerCount() * 5; + return totalChannelCount + totalHandlerCount + 4; } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/jmx/DefaultMetricNamingStrategy.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/jmx/DefaultMetricNamingStrategy.java index b5d3f31228..8e7bdb12cb 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/jmx/DefaultMetricNamingStrategy.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/jmx/DefaultMetricNamingStrategy.java @@ -33,6 +33,7 @@ import org.springframework.util.StringUtils; * domain is copied from the input key and the type in the input key is discarded. * * @author Dave Syer + * @since 1.3.0 */ public class DefaultMetricNamingStrategy implements ObjectNamingStrategy { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/jmx/JmxMetricWriter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/jmx/JmxMetricWriter.java index db345b7833..ec0507cb52 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/jmx/JmxMetricWriter.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/jmx/JmxMetricWriter.java @@ -21,6 +21,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -41,6 +42,7 @@ import org.springframework.jmx.export.naming.ObjectNamingStrategy; * and value keys by splitting up the metric name on periods. * * @author Dave Syer + * @since 1.3.0 */ @ManagedResource(description = "MetricWriter for pushing metrics to JMX MBeans.") public class JmxMetricWriter implements MetricWriter { @@ -97,10 +99,9 @@ public class JmxMetricWriter implements MetricWriter { try { // We can unregister the MBean, but if this writer is on the end of an // Exporter the chances are it will be re-registered almost immediately. - this.exporter.unregisterManagedResource(this.namingStrategy - .getObjectName(value, getKey(name))); + this.exporter.unregisterManagedResource(getName(name, value)); } - catch (MalformedObjectNameException e) { + catch (MalformedObjectNameException ex) { logger.warn("Could not unregister MBean for " + name); } } @@ -111,18 +112,19 @@ public class JmxMetricWriter implements MetricWriter { this.values.putIfAbsent(name, new MetricValue()); MetricValue value = this.values.get(name); try { - this.exporter.registerManagedResource(value, - this.namingStrategy.getObjectName(value, getKey(name))); + this.exporter.registerManagedResource(value, getName(name, value)); } - catch (Exception e) { + catch (Exception ex) { // Could not register mbean, maybe just a race condition } } return this.values.get(name); } - private String getKey(String name) { - return String.format(this.domain + ":type=MetricValue,name=%s", name); + private ObjectName getName(String name, MetricValue value) + throws MalformedObjectNameException { + String key = String.format(this.domain + ":type=MetricValue,name=%s", name); + return this.namingStrategy.getObjectName(value, key); } @ManagedResource diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/DefaultOpenTsdbNamingStrategy.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/DefaultOpenTsdbNamingStrategy.java index 50ec9d0831..c579555a5d 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/DefaultOpenTsdbNamingStrategy.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/DefaultOpenTsdbNamingStrategy.java @@ -34,6 +34,7 @@ import org.springframework.util.ObjectUtils; * (overwriting the default). * * @author Dave Syer + * @since 1.3.0 */ public class DefaultOpenTsdbNamingStrategy implements OpenTsdbNamingStrategy { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbData.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbData.java index 8e660f8300..df216ab965 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbData.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbData.java @@ -19,7 +19,10 @@ package org.springframework.boot.actuate.metrics.opentsdb; import java.util.Map; /** + * OpenTSDB Data. + * * @author Dave Syer + * @since 1.3.0 */ public class OpenTsdbData { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbMetricWriter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbMetricWriter.java index 13ae1ad39f..e1676a3bb8 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbMetricWriter.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbMetricWriter.java @@ -43,6 +43,7 @@ import org.springframework.web.client.RestTemplate; * @Scheduled} task to flush periodically. * * @author Dave Syer + * @since 1.3.0 */ public class OpenTsdbMetricWriter implements MetricWriter { @@ -141,4 +142,4 @@ public class OpenTsdbMetricWriter implements MetricWriter { set(new Metric(metricName, 0L)); } -} \ No newline at end of file +} diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbName.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbName.java index 228c58651b..e949de4742 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbName.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbName.java @@ -20,7 +20,10 @@ import java.util.LinkedHashMap; import java.util.Map; /** + * OpenTSDB Name. + * * @author Dave Syer + * @since 1.3.0 */ public class OpenTsdbName { diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbNamingStrategy.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbNamingStrategy.java index c3bebf7eb4..710fbbeba1 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbNamingStrategy.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbNamingStrategy.java @@ -17,10 +17,18 @@ package org.springframework.boot.actuate.metrics.opentsdb; /** + * Strategy used to convert a metric name into an {@link OpenTsdbName}. + * * @author Dave Syer + * @since 1.3.0 */ public interface OpenTsdbNamingStrategy { + /** + * Convert the metric name into a {@link OpenTsdbName} + * @param metricName the name of the metric + * @return an Open TSDB name + */ OpenTsdbName getName(String metricName); } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/statsd/StatsdMetricWriter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/statsd/StatsdMetricWriter.java index 2724ca9e42..877cf48975 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/statsd/StatsdMetricWriter.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/statsd/StatsdMetricWriter.java @@ -37,16 +37,16 @@ import com.timgroup.statsd.StatsDClientErrorHandler; * a gauge. * * @author Dave Syer + * @since 1.3.0 */ public class StatsdMetricWriter implements MetricWriter, Closeable { - private static Log logger = LogFactory.getLog(StatsdMetricWriter.class); + private static final Log logger = LogFactory.getLog(StatsdMetricWriter.class); private final NonBlockingStatsDClient client; /** - * Create a new writer with the given parameters. - * + * Create a new writer instance with the given parameters. * @param host the hostname for the statsd server * @param port the port for the statsd server */ @@ -56,7 +56,6 @@ public class StatsdMetricWriter implements MetricWriter, Closeable { /** * Create a new writer with the given parameters. - * * @param prefix the prefix to apply to all metric names (can be null) * @param host the hostname for the statsd server * @param port the port for the statsd server @@ -101,11 +100,13 @@ public class StatsdMetricWriter implements MetricWriter, Closeable { private static final class LoggingStatsdErrorHandler implements StatsDClientErrorHandler { + @Override public void handle(Exception e) { logger.debug("Failed to write metric. Exception: " + e.getClass() + ", message: " + e.getMessage()); } + } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/DefaultCounterService.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/DefaultCounterService.java index 28fe6ac479..8b727322a7 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/DefaultCounterService.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/DefaultCounterService.java @@ -65,4 +65,5 @@ public class DefaultCounterService implements CounterService { this.names.put(metricName, name); return name; } + } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/DefaultGaugeService.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/DefaultGaugeService.java index f11b6d0f23..01964d8425 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/DefaultGaugeService.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/DefaultGaugeService.java @@ -57,4 +57,5 @@ public class DefaultGaugeService implements GaugeService { this.names.put(metricName, name); return name; } + } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/WriterUtils.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/WriterUtils.java deleted file mode 100644 index 8ae662387c..0000000000 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/writer/WriterUtils.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.metrics.writer; - -import java.io.Flushable; -import java.lang.reflect.Method; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.boot.actuate.metrics.export.MetricCopyExporter; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; - -/** - * @author Dave Syer - */ -public class WriterUtils { - - private static final Log logger = LogFactory.getLog(MetricCopyExporter.class); - - public static void flush(MetricWriter writer) { - if (writer instanceof CompositeMetricWriter) { - for (MetricWriter element : (CompositeMetricWriter) writer) { - flush(element); - } - } - try { - if (ClassUtils.isPresent("java.io.Flushable", null)) { - if (writer instanceof Flushable) { - ((Flushable) writer).flush(); - return; - } - } - Method method = ReflectionUtils.findMethod(writer.getClass(), "flush"); - if (method != null) { - ReflectionUtils.invokeMethod(method, writer); - } - } - catch (Exception e) { - logger.warn("Could not flush MetricWriter: " + e.getClass() + ": " - + e.getMessage()); - } - } - -} diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/MetricExportAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/MetricExportAutoConfigurationTests.java index 40493b03f2..4adcc70813 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/MetricExportAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/MetricExportAutoConfigurationTests.java @@ -16,8 +16,6 @@ package org.springframework.boot.actuate.autoconfigure; -import static org.junit.Assert.assertNotNull; - import org.junit.After; import org.junit.Test; import org.mockito.Matchers; @@ -38,8 +36,10 @@ import org.springframework.messaging.MessageHandler; import org.springframework.messaging.MessagingException; import org.springframework.messaging.SubscribableChannel; +import static org.junit.Assert.assertNotNull; + /** - * Tests for {@link MetricRepositoryAutoConfiguration}. + * Tests for {@link MetricExportAutoConfiguration}. * * @author Phillip Webb * @author Dave Syer @@ -88,15 +88,15 @@ public class MetricExportAutoConfigurationTests { @Test public void exportMetricsEndpoint() { this.context = new AnnotationConfigApplicationContext(WriterConfig.class, - MetricEndpointConfiguration.class, - MetricExportAutoConfiguration.class, + MetricEndpointConfiguration.class, MetricExportAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class); MetricExporters exporters = this.context.getBean(MetricExporters.class); MetricCopyExporter exporter = (MetricCopyExporter) exporters.getExporters().get( "writer"); exporter.setIgnoreTimestamps(true); exporter.export(); - MetricsEndpointMetricReader reader = this.context.getBean("endpointReader", MetricsEndpointMetricReader.class); + MetricsEndpointMetricReader reader = this.context.getBean("endpointReader", + MetricsEndpointMetricReader.class); Mockito.verify(reader, Mockito.atLeastOnce()).findAll(); } 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 102a0d5943..9d00ca79ea 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 @@ -16,12 +16,6 @@ package org.springframework.boot.actuate.autoconfigure; -import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; - import org.junit.After; import org.junit.Test; import org.springframework.boot.actuate.metrics.CounterService; @@ -39,6 +33,12 @@ import org.springframework.context.annotation.Configuration; import com.codahale.metrics.Gauge; import com.codahale.metrics.MetricRegistry; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; + /** * Tests for {@link MetricRepositoryAutoConfiguration}. * diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/aggregate/AggregateMetricReaderTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/aggregate/AggregateMetricReaderTests.java index 5e3ee336aa..3f87f1fc45 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/aggregate/AggregateMetricReaderTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/aggregate/AggregateMetricReaderTests.java @@ -27,6 +27,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; /** + * Tests for {@link AggregateMetricReader}. + * * @author Dave Syer */ public class AggregateMetricReaderTests { diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/BufferGaugeServiceSpeedTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/BufferGaugeServiceSpeedTests.java index b0563c83df..eb680c30c7 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/BufferGaugeServiceSpeedTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/BufferGaugeServiceSpeedTests.java @@ -164,4 +164,5 @@ public class BufferGaugeServiceSpeedTests { } watch.stop(); } + } diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/CounterBuffersTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/CounterBuffersTests.java index 4a781ecde3..e871fa9aca 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/CounterBuffersTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/CounterBuffersTests.java @@ -61,4 +61,5 @@ public class CounterBuffersTests { public void findNonExistent() { assertNull(this.buffers.find("foo")); } + } diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/CounterServiceSpeedTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/CounterServiceSpeedTests.java index 970c16f26e..3bb4039d0d 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/CounterServiceSpeedTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/CounterServiceSpeedTests.java @@ -44,6 +44,7 @@ import static org.junit.Assert.assertEquals; /** * Speed tests for {@link CounterService}. + * * @author Dave Syer */ @RunWith(Theories.class) @@ -162,4 +163,5 @@ public class CounterServiceSpeedTests { } watch.stop(); } + } diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/DefaultGaugeServiceSpeedTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/DefaultGaugeServiceSpeedTests.java index 6688a3d0fe..63a6e8f223 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/DefaultGaugeServiceSpeedTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/buffer/DefaultGaugeServiceSpeedTests.java @@ -126,4 +126,5 @@ public class DefaultGaugeServiceSpeedTests { System.err.println("Read(" + count + ")=" + watch.getLastTaskTimeMillis() + "ms"); assertTrue(0 < total.longValue()); } + } diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/dropwizard/DropwizardMetricServicesTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/dropwizard/DropwizardMetricServicesTests.java index 13b499b4b7..0666a59642 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/dropwizard/DropwizardMetricServicesTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/dropwizard/DropwizardMetricServicesTests.java @@ -20,7 +20,6 @@ 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; @@ -114,13 +113,15 @@ public class DropwizardMetricServicesTests { } public static class WriterThread extends Thread { + private int index; + private boolean failed; + private DropwizardMetricServices writer; public WriterThread(ThreadGroup group, int index, DropwizardMetricServices writer) { super(group, "Writer-" + index); - this.index = index; this.writer = writer; } @@ -143,5 +144,7 @@ public class DropwizardMetricServicesTests { } } } + } + } 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 e8b1e50d3f..23b4cd4000 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 @@ -25,12 +25,16 @@ import org.springframework.boot.actuate.metrics.repository.InMemoryMetricReposit import static org.junit.Assert.assertEquals; /** + * Tests for {@link MetricCopyExporter}. + * * @author Dave Syer */ public class MetricCopyExporterTests { private final InMemoryMetricRepository writer = new InMemoryMetricRepository(); + private final InMemoryMetricRepository reader = new InMemoryMetricRepository(); + private final MetricCopyExporter exporter = new MetricCopyExporter(this.reader, this.writer); diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/MetricExportersTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/MetricExportersTests.java index 6b0c332ce9..34dea74373 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/MetricExportersTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/MetricExportersTests.java @@ -29,14 +29,20 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; /** + * Tests for {@link MetricExporters}. + * * @author Dave Syer */ public class MetricExportersTests { private MetricExporters exporters; + private MetricExportProperties export = new MetricExportProperties(); + private Map writers = new LinkedHashMap(); + private MetricReader reader = Mockito.mock(MetricReader.class); + private MetricWriter writer = Mockito.mock(MetricWriter.class); @Test diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/PrefixMetricGroupExporterTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/PrefixMetricGroupExporterTests.java index 6331245974..75e3639e9e 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/PrefixMetricGroupExporterTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/PrefixMetricGroupExporterTests.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. diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/RichGaugeExporterTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/RichGaugeExporterTests.java index d972c3ae1b..d832c8afb3 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/RichGaugeExporterTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/export/RichGaugeExporterTests.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. @@ -25,12 +25,16 @@ import org.springframework.boot.actuate.metrics.rich.InMemoryRichGaugeRepository import static org.junit.Assert.assertEquals; /** + * Tests for {@link RichGaugeExporter}. + * * @author Dave Syer */ public class RichGaugeExporterTests { private final InMemoryRichGaugeRepository reader = new InMemoryRichGaugeRepository(); + private final InMemoryMetricRepository writer = new InMemoryMetricRepository(); + private final RichGaugeExporter exporter = new RichGaugeExporter(this.reader, this.writer); 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 index b14c5468f7..8b909ad27c 100644 --- 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 @@ -1,6 +1,20 @@ -package org.springframework.boot.actuate.metrics.integration; +/* + * 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. + */ -import static org.junit.Assert.assertTrue; +package org.springframework.boot.actuate.metrics.integration; import org.junit.Test; import org.junit.runner.RunWith; @@ -17,22 +31,29 @@ import org.springframework.integration.monitor.IntegrationMBeanExporter; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import static org.junit.Assert.assertTrue; + +/** + * Tests for {@link SpringIntegrationMetricReader}. + * + * @author Dave Syer + */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes=TestConfiguration.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); + assertTrue(this.reader.count() > 0); } - + @Configuration - @Import({JmxAutoConfiguration.class, IntegrationAutoConfiguration.class}) + @Import({ JmxAutoConfiguration.class, IntegrationAutoConfiguration.class }) protected static class TestConfiguration { @Bean public SpringIntegrationMetricReader reader(IntegrationMBeanExporter exporter) { diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/jmx/DefaultMetricNamingStrategyTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/jmx/DefaultMetricNamingStrategyTests.java index 3da8bcfebf..20f0151627 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/jmx/DefaultMetricNamingStrategyTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/jmx/DefaultMetricNamingStrategyTests.java @@ -23,6 +23,8 @@ import org.junit.Test; import static org.junit.Assert.assertEquals; /** + * Tests for {@link DefaultMetricNamingStrategy}. + * * @author Dave Syer */ public class DefaultMetricNamingStrategyTests { diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbMetricWriterTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbMetricWriterTests.java index 0c68878203..35f5085d35 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbMetricWriterTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/opentsdb/OpenTsdbMetricWriterTests.java @@ -21,7 +21,6 @@ import java.util.Map; import org.junit.Before; import org.junit.Test; -import org.mockito.Matchers; import org.mockito.Mockito; import org.springframework.boot.actuate.metrics.Metric; import org.springframework.http.HttpStatus; @@ -29,9 +28,13 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestOperations; import static org.mockito.BDDMockito.given; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.verify; /** + * Tests for {@link OpenTsdbMetricWriter}. + * * @author Dave Syer */ public class OpenTsdbMetricWriterTests { @@ -48,25 +51,19 @@ public class OpenTsdbMetricWriterTests { @Test public void postSuccessfullyOnFlush() { this.writer.set(new Metric("foo", 2.4)); - given( - this.restTemplate.postForEntity(Matchers.anyString(), - Matchers.any(Object.class), anyMap())) + given(this.restTemplate.postForEntity(anyString(), any(Object.class), anyMap())) .willReturn(emptyResponse()); this.writer.flush(); - verify(this.restTemplate).postForEntity(Matchers.anyString(), - Matchers.any(Object.class), anyMap()); + verify(this.restTemplate).postForEntity(anyString(), any(Object.class), anyMap()); } @Test public void flushAutomaticlly() { - given( - this.restTemplate.postForEntity(Matchers.anyString(), - Matchers.any(Object.class), anyMap())) + given(this.restTemplate.postForEntity(anyString(), any(Object.class), anyMap())) .willReturn(emptyResponse()); this.writer.setBufferSize(0); this.writer.set(new Metric("foo", 2.4)); - verify(this.restTemplate).postForEntity(Matchers.anyString(), - Matchers.any(Object.class), anyMap()); + verify(this.restTemplate).postForEntity(anyString(), any(Object.class), anyMap()); } @SuppressWarnings("rawtypes") @@ -76,7 +73,7 @@ public class OpenTsdbMetricWriterTests { @SuppressWarnings({ "rawtypes", "unchecked" }) private Class anyMap() { - return Matchers.any(Class.class); + return any(Class.class); } } diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/statsd/StatsdMetricWriterTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/statsd/StatsdMetricWriterTests.java index c90f6f4a0d..d50b89d9a2 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/statsd/StatsdMetricWriterTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/statsd/StatsdMetricWriterTests.java @@ -99,6 +99,7 @@ public class StatsdMetricWriterTests { private static final class DummyStatsDServer { private final List messagesReceived = new ArrayList(); + private final DatagramSocket server; public DummyStatsDServer(int port) { @@ -141,5 +142,7 @@ public class StatsdMetricWriterTests { public List messagesReceived() { return new ArrayList(this.messagesReceived); } + } + } diff --git a/spring-boot-samples/spring-boot-sample-metrics-opentsdb/src/main/java/sample/metrics/opentsdb/HelloWorldService.java b/spring-boot-samples/spring-boot-sample-metrics-opentsdb/src/main/java/sample/metrics/opentsdb/HelloWorldService.java index e4bcc96cae..69ca04ebb9 100644 --- a/spring-boot-samples/spring-boot-sample-metrics-opentsdb/src/main/java/sample/metrics/opentsdb/HelloWorldService.java +++ b/spring-boot-samples/spring-boot-sample-metrics-opentsdb/src/main/java/sample/metrics/opentsdb/HelloWorldService.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. diff --git a/spring-boot-samples/spring-boot-sample-metrics-opentsdb/src/main/java/sample/metrics/opentsdb/SampleController.java b/spring-boot-samples/spring-boot-sample-metrics-opentsdb/src/main/java/sample/metrics/opentsdb/SampleController.java index d4f36f55e9..f34c550186 100644 --- a/spring-boot-samples/spring-boot-sample-metrics-opentsdb/src/main/java/sample/metrics/opentsdb/SampleController.java +++ b/spring-boot-samples/spring-boot-sample-metrics-opentsdb/src/main/java/sample/metrics/opentsdb/SampleController.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. diff --git a/spring-boot-samples/spring-boot-sample-metrics-opentsdb/src/main/java/sample/metrics/opentsdb/SampleOpenTsdbExportApplication.java b/spring-boot-samples/spring-boot-sample-metrics-opentsdb/src/main/java/sample/metrics/opentsdb/SampleOpenTsdbExportApplication.java index 06403caad9..7f9d63b63a 100644 --- a/spring-boot-samples/spring-boot-sample-metrics-opentsdb/src/main/java/sample/metrics/opentsdb/SampleOpenTsdbExportApplication.java +++ b/spring-boot-samples/spring-boot-sample-metrics-opentsdb/src/main/java/sample/metrics/opentsdb/SampleOpenTsdbExportApplication.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. diff --git a/spring-boot-samples/spring-boot-sample-metrics-opentsdb/src/test/java/sample/metrics/opentsdb/SampleOpenTsdbExportApplicationTests.java b/spring-boot-samples/spring-boot-sample-metrics-opentsdb/src/test/java/sample/metrics/opentsdb/SampleOpenTsdbExportApplicationTests.java index 8a2f70cdb1..e617f81591 100644 --- a/spring-boot-samples/spring-boot-sample-metrics-opentsdb/src/test/java/sample/metrics/opentsdb/SampleOpenTsdbExportApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-metrics-opentsdb/src/test/java/sample/metrics/opentsdb/SampleOpenTsdbExportApplicationTests.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. diff --git a/spring-boot-samples/spring-boot-sample-metrics-redis/README.adoc b/spring-boot-samples/spring-boot-sample-metrics-redis/README.adoc index 3038d54817..6626e0c0c1 100644 --- a/spring-boot-samples/spring-boot-sample-metrics-redis/README.adoc +++ b/spring-boot-samples/spring-boot-sample-metrics-redis/README.adoc @@ -1,4 +1,4 @@ -Spring Boot sample with Redis export for metrics. += Spring Boot sample with Redis export for metrics. Start redis, e.g. with [Docker Compose]() diff --git a/spring-boot-samples/spring-boot-sample-metrics-redis/src/main/java/sample/metrics/redis/AggregateMetricsConfiguration.java b/spring-boot-samples/spring-boot-sample-metrics-redis/src/main/java/sample/metrics/redis/AggregateMetricsConfiguration.java index 0e3a41d1dc..0f82a691b6 100644 --- a/spring-boot-samples/spring-boot-sample-metrics-redis/src/main/java/sample/metrics/redis/AggregateMetricsConfiguration.java +++ b/spring-boot-samples/spring-boot-sample-metrics-redis/src/main/java/sample/metrics/redis/AggregateMetricsConfiguration.java @@ -27,9 +27,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; -/** - * @author Dave Syer - */ @Configuration public class AggregateMetricsConfiguration { @@ -45,8 +42,8 @@ public class AggregateMetricsConfiguration { } private MetricReader globalMetricsForAggregation() { - return new RedisMetricRepository(this.connectionFactory, - this.export.getRedis().getAggregatePrefix(), this.export.getRedis().getKey()); + return new RedisMetricRepository(this.connectionFactory, this.export.getRedis() + .getAggregatePrefix(), this.export.getRedis().getKey()); } private MetricReader aggregatesMetricReader() { diff --git a/spring-boot-samples/spring-boot-sample-metrics-redis/src/main/java/sample/metrics/redis/SampleRedisExportApplication.java b/spring-boot-samples/spring-boot-sample-metrics-redis/src/main/java/sample/metrics/redis/SampleRedisExportApplication.java index 8286581115..b9a54ddcc9 100644 --- a/spring-boot-samples/spring-boot-sample-metrics-redis/src/main/java/sample/metrics/redis/SampleRedisExportApplication.java +++ b/spring-boot-samples/spring-boot-sample-metrics-redis/src/main/java/sample/metrics/redis/SampleRedisExportApplication.java @@ -42,8 +42,8 @@ public class SampleRedisExportApplication { @ExportMetricWriter public RedisMetricRepository redisMetricWriter( RedisConnectionFactory connectionFactory) { - return new RedisMetricRepository(connectionFactory, this.export.getRedis().getPrefix(), - this.export.getRedis().getKey()); + return new RedisMetricRepository(connectionFactory, this.export.getRedis() + .getPrefix(), this.export.getRedis().getKey()); } @Bean