Merge pull request #11492 from jkschneider:metrics-endpoint-tag-dedup

* pr/11492:
  Polish "Deduplicate tag values in metrics actuator endpoint"
  Deduplicate tag values in metrics actuator endpoint
pull/11527/head
Stephane Nicoll 7 years ago
commit 2a7b2f304a

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,6 +19,7 @@ package org.springframework.boot.actuate.metrics;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
@ -88,7 +89,7 @@ public class MetricsEndpoint {
return null; return null;
} }
Map<Statistic, Double> samples = getSamples(meters); Map<Statistic, Double> samples = getSamples(meters);
Map<String, List<String>> availableTags = getAvailableTags(meters); Map<String, Set<String>> availableTags = getAvailableTags(meters);
tags.forEach((t) -> availableTags.remove(t.getKey())); tags.forEach((t) -> availableTags.remove(t.getKey()));
return new MetricResponse(requiredMetricName, return new MetricResponse(requiredMetricName,
asList(samples, MetricResponse.Sample::new), asList(samples, MetricResponse.Sample::new),
@ -124,24 +125,24 @@ public class MetricsEndpoint {
measurement.getValue(), Double::sum)); measurement.getValue(), Double::sum));
} }
private Map<String, List<String>> getAvailableTags(List<Meter> meters) { private Map<String, Set<String>> getAvailableTags(List<Meter> meters) {
Map<String, List<String>> availableTags = new HashMap<>(); Map<String, Set<String>> availableTags = new HashMap<>();
meters.forEach((meter) -> mergeAvailableTags(availableTags, meter)); meters.forEach((meter) -> mergeAvailableTags(availableTags, meter));
return availableTags; return availableTags;
} }
private void mergeAvailableTags(Map<String, List<String>> availableTags, private void mergeAvailableTags(Map<String, Set<String>> availableTags,
Meter meter) { Meter meter) {
meter.getId().getTags().forEach((tag) -> { meter.getId().getTags().forEach((tag) -> {
List<String> value = Collections.singletonList(tag.getValue()); Set<String> value = Collections.singleton(tag.getValue());
availableTags.merge(tag.getKey(), value, this::merge); availableTags.merge(tag.getKey(), value, this::merge);
}); });
} }
private <T> List<T> merge(List<T> list1, List<T> list2) { private <T> Set<T> merge(Set<T> set1, Set<T> set2) {
List<T> result = new ArrayList<>(list1.size() + list2.size()); Set<T> result = new HashSet<>(set1.size() + set2.size());
result.addAll(list1); result.addAll(set1);
result.addAll(list2); result.addAll(set2);
return result; return result;
} }
@ -204,9 +205,9 @@ public class MetricsEndpoint {
private final String tag; private final String tag;
private final List<String> values; private final Set<String> values;
AvailableTag(String tag, List<String> values) { AvailableTag(String tag, Set<String> values) {
this.tag = tag; this.tag = tag;
this.values = values; this.values = values;
} }
@ -215,7 +216,7 @@ public class MetricsEndpoint {
return this.tag; return this.tag;
} }
public List<String> getValues() { public Set<String> getValues() {
return this.values; return this.values;
} }
} }

@ -87,6 +87,19 @@ public class MetricsEndpointTests {
assertThat(getCount(response)).hasValue(4.0); assertThat(getCount(response)).hasValue(4.0);
} }
@Test
public void metricTagValuesAreDeduplicated() {
this.registry.counter("cache", "host", "1", "region", "east", "result", "hit");
this.registry.counter("cache", "host", "1", "region", "east", "result", "miss");
MetricsEndpoint.MetricResponse response = this.endpoint.metric("cache",
Collections.singletonList("host:1"));
assertThat(response.getAvailableTags()
.stream()
.filter(t -> t.getTag().equals("region"))
.flatMap(t -> t.getValues().stream()))
.containsExactly("east");
}
@Test @Test
public void metricWithSpaceInTagValue() { public void metricWithSpaceInTagValue() {
this.registry.counter("counter", "key", "a space").increment(2); this.registry.counter("counter", "key", "a space").increment(2);

Loading…
Cancel
Save