From 928bc69251d16c932b048b33787ff2eefee577eb Mon Sep 17 00:00:00 2001 From: Henrique Miranda Date: Wed, 7 Jun 2017 08:54:08 +0200 Subject: [PATCH 1/2] Created a converter from gauge response actuator metrics to prometheus format. --- .../GaugeResponseActuatorMetricConverter.java | 55 +++++++++++++++++++ .../boot/SpringBootMetricsCollector.java | 30 +++++++--- .../boot/SpringBootMetricsCollectorTest.java | 14 +++++ 3 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/GaugeResponseActuatorMetricConverter.java diff --git a/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/GaugeResponseActuatorMetricConverter.java b/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/GaugeResponseActuatorMetricConverter.java new file mode 100644 index 000000000..496ec7aaa --- /dev/null +++ b/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/GaugeResponseActuatorMetricConverter.java @@ -0,0 +1,55 @@ +package io.prometheus.client.spring.boot; + +import io.prometheus.client.Collector.MetricFamilySamples; +import org.springframework.boot.actuate.metrics.Metric; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class GaugeResponseActuatorMetricConverter { + + private List labelsMerged; + private List labelsPerHttpMethod; + + private final static String GAUGE_RESPONSE_NAME = "gauge_response"; + + public GaugeResponseActuatorMetricConverter() { + this.labelsMerged = new ArrayList(); + this.labelsMerged.add("endpoint"); + + this.labelsPerHttpMethod = new ArrayList(labelsMerged); + this.labelsPerHttpMethod.add("method"); + } + + public MetricFamilySamples.Sample convert(Metric metric) { + MetricFamilySamples.Sample sample; + if (containsHttpMethod(metric.getName())) { + List labelValues = retrieveLabelValues("gauge.response.", metric.getName()); + return new MetricFamilySamples.Sample(GAUGE_RESPONSE_NAME, labelsPerHttpMethod, labelValues, metric.getValue().doubleValue()); + } else { + List labelValues = retrieveJustEndpoint("gauge.response.", metric.getName()); + return new MetricFamilySamples.Sample(GAUGE_RESPONSE_NAME, labelsMerged, labelValues, metric.getValue().doubleValue()); + } + } + + private List retrieveJustEndpoint(String keyToRemove, String name) { + return Arrays.asList(name.replace(keyToRemove , ".").replaceAll("\\.","/")); + } + + private List retrieveLabelValues(String keyToRemove, String name) { + String method = name.split("\\.")[2]; + String endpoint = name.substring(name.lastIndexOf(method) + method.length()).replaceAll("\\.","/"); + return Arrays.asList(method, endpoint); + } + + private boolean containsHttpMethod(String name) { + return name.contains(".GET.") + || name.contains(".POST.") + || name.contains(".PUT.") + || name.contains(".DELETE.") + || name.contains(".OPTIONS.") + || name.contains(".HEAD.") + || name.contains(".CONNECT."); + } +} diff --git a/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/SpringBootMetricsCollector.java b/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/SpringBootMetricsCollector.java index 2cf1f7d8b..8892caa81 100644 --- a/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/SpringBootMetricsCollector.java +++ b/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/SpringBootMetricsCollector.java @@ -25,28 +25,42 @@ @Component public class SpringBootMetricsCollector extends Collector implements Collector.Describable { private final Collection publicMetrics; - + private final GaugeResponseActuatorMetricConverter gaugeResponseActuatorMetricConverter; @Autowired public SpringBootMetricsCollector(Collection publicMetrics) { - this.publicMetrics = publicMetrics; + this.publicMetrics = publicMetrics; + this.gaugeResponseActuatorMetricConverter = new GaugeResponseActuatorMetricConverter(); } @Override public List collect() { ArrayList samples = new ArrayList(); + ArrayList gauges = new ArrayList(); + for (PublicMetrics publicMetrics : this.publicMetrics) { for (Metric metric : publicMetrics.metrics()) { - String name = Collector.sanitizeMetricName(metric.getName()); - double value = metric.getValue().doubleValue(); - MetricFamilySamples metricFamilySamples = new MetricFamilySamples( - name, Type.GAUGE, name, Collections.singletonList( - new MetricFamilySamples.Sample(name, Collections.emptyList(), Collections.emptyList(), value))); - samples.add(metricFamilySamples); + if (isResponseGaugeEndpointMetric(metric)) { + MetricFamilySamples.Sample metricFamilySamples = gaugeResponseActuatorMetricConverter.convert(metric); + gauges.add(metricFamilySamples); + } else { + String name = Collector.sanitizeMetricName(metric.getName()); + double value = metric.getValue().doubleValue(); + MetricFamilySamples metricFamilySamples = new MetricFamilySamples( + name, Type.GAUGE, name, Collections.singletonList( + new MetricFamilySamples.Sample(name, Collections.emptyList(), Collections.emptyList(), value))); + samples.add(metricFamilySamples); + } } } + + samples.add(new MetricFamilySamples("gauge_response", Type.GAUGE, "gauge_response", gauges)); return samples; } + private boolean isResponseGaugeEndpointMetric(Metric metric) { + return metric.getName().startsWith("gauge.response"); + } + @Override public List describe() { return new ArrayList(); diff --git a/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java b/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java index 9b0909962..ff1058ced 100644 --- a/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java +++ b/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java @@ -12,6 +12,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import java.util.Arrays; import java.util.Collection; import static org.hamcrest.Matchers.is; @@ -42,8 +43,21 @@ public void collect() throws Exception { counterService.increment("foo"); gaugeService.submit("bar", 3.14); + CollectorRegistry defaultRegistry = CollectorRegistry.defaultRegistry; assertThat(defaultRegistry.getSampleValue("counter_foo"), is(1.0)); assertThat(defaultRegistry.getSampleValue("gauge_bar"), is(3.14)); } + + @Test + public void collectConvertedMetrics() throws Exception { + gaugeService.submit("response.GET.info.details", 3.0); + gaugeService.submit("response.info.details", 3.0); + + + CollectorRegistry defaultRegistry = CollectorRegistry.defaultRegistry; + assertThat(defaultRegistry.getSampleValue("gauge_response", new String[]{"endpoint", "method"}, new String[]{"GET", "/info/details"}), is(3.0)); + assertThat(defaultRegistry.getSampleValue("gauge_response", new String[]{"endpoint"}, new String[]{"/info/details"}), is(3.0)); + } + } From 768d5f5e596d41ba5013388e7092c4cbe9a78030 Mon Sep 17 00:00:00 2001 From: Henrique Miranda Date: Wed, 7 Jun 2017 09:17:51 +0200 Subject: [PATCH 2/2] Fixed order of values --- .../spring/boot/GaugeResponseActuatorMetricConverter.java | 2 +- .../client/spring/boot/SpringBootMetricsCollectorTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/GaugeResponseActuatorMetricConverter.java b/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/GaugeResponseActuatorMetricConverter.java index 496ec7aaa..5580764f2 100644 --- a/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/GaugeResponseActuatorMetricConverter.java +++ b/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/GaugeResponseActuatorMetricConverter.java @@ -40,7 +40,7 @@ private List retrieveJustEndpoint(String keyToRemove, String name) { private List retrieveLabelValues(String keyToRemove, String name) { String method = name.split("\\.")[2]; String endpoint = name.substring(name.lastIndexOf(method) + method.length()).replaceAll("\\.","/"); - return Arrays.asList(method, endpoint); + return Arrays.asList(endpoint, method); } private boolean containsHttpMethod(String name) { diff --git a/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java b/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java index ff1058ced..dbb1667ed 100644 --- a/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java +++ b/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java @@ -56,7 +56,7 @@ public void collectConvertedMetrics() throws Exception { CollectorRegistry defaultRegistry = CollectorRegistry.defaultRegistry; - assertThat(defaultRegistry.getSampleValue("gauge_response", new String[]{"endpoint", "method"}, new String[]{"GET", "/info/details"}), is(3.0)); + assertThat(defaultRegistry.getSampleValue("gauge_response", new String[]{"endpoint", "method"}, new String[]{"/info/details", "GET"}), is(3.0)); assertThat(defaultRegistry.getSampleValue("gauge_response", new String[]{"endpoint"}, new String[]{"/info/details"}), is(3.0)); }