From 27da0bc12e51923fcc3ce1b84c96e4c66a8908bd Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 11 Dec 2014 10:24:39 +0000 Subject: [PATCH] Simplify implementation of servo metrics --- .../eureka/EurekaClientAutoConfiguration.java | 7 ++- ...cReader.java => ServoMetricCollector.java} | 60 +++++-------------- .../servo/ServoMetricsAutoConfiguration.java | 6 +- 3 files changed, 21 insertions(+), 52 deletions(-) rename spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/{ServoMetricReader.java => ServoMetricCollector.java} (65%) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java index 447cffdc..9e26b4d3 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java @@ -18,12 +18,12 @@ package org.springframework.cloud.netflix.eureka; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.metrics.reader.MetricReader; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.netflix.servo.ServoMetricReader; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -69,8 +69,9 @@ public class EurekaClientAutoConfiguration { @Bean @ConditionalOnMissingBean - public EurekaHealthIndicator eurekaHealthIndicator(EurekaInstanceConfig config) { - return new EurekaHealthIndicator(discoveryClient, new ServoMetricReader(), config); + @ConditionalOnBean(MetricReader.class) + public EurekaHealthIndicator eurekaHealthIndicator(EurekaInstanceConfig config, MetricReader metrics) { + return new EurekaHealthIndicator(discoveryClient, metrics, config); } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricReader.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricCollector.java similarity index 65% rename from spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricReader.java rename to spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricCollector.java index 15bd4029..d2d67326 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricReader.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricCollector.java @@ -17,15 +17,13 @@ package org.springframework.cloud.netflix.servo; import java.util.ArrayList; -import java.util.Collections; import java.util.Date; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.concurrent.TimeUnit; import org.springframework.boot.actuate.metrics.Metric; import org.springframework.boot.actuate.metrics.reader.MetricReader; +import org.springframework.boot.actuate.metrics.writer.MetricWriter; import com.netflix.servo.monitor.MonitorConfig; import com.netflix.servo.publish.BaseMetricObserver; @@ -37,23 +35,19 @@ import com.netflix.servo.publish.PollScheduler; /** * {@link MetricReader} implementation that registers a {@link MetricObserver} with the - * Netflix Servo library and exposes Servo metrics to the /metric endpoint. + * Netflix Servo library and exposes Servo metrics to the /metric endpoint. * * @author Dave Syer * @author Christian Dupuis */ -public class ServoMetricReader implements MetricReader { +public class ServoMetricCollector { - private static final Object monitor = new Object(); - - private final Map> metrics = new HashMap>(); - - public ServoMetricReader() { + public ServoMetricCollector(MetricWriter metrics) { List observers = new ArrayList(); - observers.add(new ServoMetricObserver(this.metrics)); + observers.add(new ServoMetricObserver(metrics)); PollRunnable task = new PollRunnable(new MonitorRegistryMetricPoller(), BasicMetricFilter.MATCH_ALL, true, observers); - + if (!PollScheduler.getInstance().isStarted()) { PollScheduler.getInstance().start(); } @@ -61,58 +55,32 @@ public class ServoMetricReader implements MetricReader { PollScheduler.getInstance().addPoller(task, 5, TimeUnit.SECONDS); } - @Override - public Metric findOne(String metricName) { - synchronized (monitor) { - return this.metrics.get(metricName); - } - } - - @Override - public Iterable> findAll() { - synchronized (monitor) { - return Collections.unmodifiableCollection(this.metrics.values()); - } - } - - @Override - public long count() { - synchronized (monitor) { - return this.metrics.size(); - } - } - /** - * {@link MetricObserver} to convert Servo metrics into Spring Boot {@link Metric} instances. + * {@link MetricObserver} to convert Servo metrics into Spring Boot {@link Metric} + * instances. */ private static final class ServoMetricObserver extends BaseMetricObserver { - private final Map> metrics; + private final MetricWriter metrics; - public ServoMetricObserver(Map> metrics) { + public ServoMetricObserver(MetricWriter metrics) { super("spring-boot"); this.metrics = metrics; } @Override public void updateImpl(List servoMetrics) { - Map> newMetrics = new HashMap>(); for (com.netflix.servo.Metric servoMetric : servoMetrics) { MonitorConfig config = servoMetric.getConfig(); String type = config.getTags().getValue("type"); - String key = new StringBuilder(type).append(".servo.").append(config.getName()) - .toString().toLowerCase(); - + String key = new StringBuilder(type).append(".servo.") + .append(config.getName()).toString().toLowerCase(); + if (servoMetric.hasNumberValue()) { - newMetrics.put(key, new Metric(key, servoMetric.getNumberValue(), + metrics.set(new Metric(key, servoMetric.getNumberValue(), new Date(servoMetric.getTimestamp()))); } } - - synchronized (monitor) { - this.metrics.clear(); - this.metrics.putAll(newMetrics); - } } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricsAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricsAutoConfiguration.java index c05d7ff5..6cb131e2 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricsAutoConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/servo/ServoMetricsAutoConfiguration.java @@ -18,8 +18,8 @@ package org.springframework.cloud.netflix.servo; import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.MetricRepositoryAutoConfiguration; -import org.springframework.boot.actuate.endpoint.MetricReaderPublicMetrics; import org.springframework.boot.actuate.metrics.reader.MetricReader; +import org.springframework.boot.actuate.metrics.writer.MetricWriter; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -45,7 +45,7 @@ public class ServoMetricsAutoConfiguration { @Bean @ConditionalOnMissingBean - public MetricReaderPublicMetrics servoPublicMetrics() { - return new MetricReaderPublicMetrics(new ServoMetricReader()); + public ServoMetricCollector servoMetricCollector(MetricWriter metrics) { + return new ServoMetricCollector(metrics); } }