Merge branch '2.0.x'

This commit is contained in:
Phillip Webb
2018-10-11 16:19:29 -07:00
4 changed files with 82 additions and 14 deletions

View File

@@ -17,6 +17,7 @@
package org.springframework.boot.actuate.metrics;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -81,15 +82,15 @@ public class MetricsEndpoint {
public MetricResponse metric(@Selector String requiredMetricName,
@Nullable List<String> tag) {
List<Tag> tags = parseTags(tag);
List<Meter> meters = new ArrayList<>();
collectMeters(meters, this.registry, requiredMetricName, tags);
Collection<Meter> meters = findFirstMatchingMeters(this.registry,
requiredMetricName, tags);
if (meters.isEmpty()) {
return null;
}
Map<Statistic, Double> samples = getSamples(meters);
Map<String, Set<String>> availableTags = getAvailableTags(meters);
tags.forEach((t) -> availableTags.remove(t.getKey()));
Meter.Id meterId = meters.get(0).getId();
Meter.Id meterId = meters.iterator().next().getId();
return new MetricResponse(requiredMetricName, meterId.getDescription(),
meterId.getBaseUnit(), asList(samples, Sample::new),
asList(availableTags, AvailableTag::new));
@@ -112,18 +113,23 @@ public class MetricsEndpoint {
return Tag.of(parts[0], parts[1]);
}
private void collectMeters(List<Meter> meters, MeterRegistry registry, String name,
private Collection<Meter> findFirstMatchingMeters(MeterRegistry registry, String name,
Iterable<Tag> tags) {
if (registry instanceof CompositeMeterRegistry) {
((CompositeMeterRegistry) registry).getRegistries()
.forEach((member) -> collectMeters(meters, member, name, tags));
}
else {
meters.addAll(registry.find(name).tags(tags).meters());
return findFirstMatchingMeters((CompositeMeterRegistry) registry, name, tags);
}
return registry.find(name).tags(tags).meters();
}
private Map<Statistic, Double> getSamples(List<Meter> meters) {
private Collection<Meter> findFirstMatchingMeters(CompositeMeterRegistry composite,
String name, Iterable<Tag> tags) {
return composite.getRegistries().stream()
.map((registry) -> findFirstMatchingMeters(registry, name, tags))
.filter((matching) -> !matching.isEmpty()).findFirst()
.orElse(Collections.emptyList());
}
private Map<Statistic, Double> getSamples(Collection<Meter> meters) {
Map<Statistic, Double> samples = new LinkedHashMap<>();
meters.forEach((meter) -> mergeMeasurements(samples, meter));
return samples;
@@ -138,7 +144,7 @@ public class MetricsEndpoint {
return Statistic.MAX.equals(statistic) ? Double::max : Double::sum;
}
private Map<String, Set<String>> getAvailableTags(List<Meter> meters) {
private Map<String, Set<String>> getAvailableTags(Collection<Meter> meters) {
Map<String, Set<String>> availableTags = new HashMap<>();
meters.forEach((meter) -> mergeAvailableTags(availableTags, meter));
return availableTags;

View File

@@ -91,6 +91,42 @@ public class MetricsEndpointTests {
assertThat(getCount(response)).hasValue(4.0);
}
@Test
public void findFirstMatchingMetersFromNestedRegistries() {
CompositeMeterRegistry composite = new CompositeMeterRegistry();
SimpleMeterRegistry firstLevel0 = new SimpleMeterRegistry();
CompositeMeterRegistry firstLevel1 = new CompositeMeterRegistry();
SimpleMeterRegistry secondLevel = new SimpleMeterRegistry();
composite.add(firstLevel0);
composite.add(firstLevel1);
firstLevel1.add(secondLevel);
secondLevel.counter("cache", "result", "hit", "host", "1").increment(2);
secondLevel.counter("cache", "result", "miss", "host", "1").increment(2);
secondLevel.counter("cache", "result", "hit", "host", "2").increment(2);
MetricsEndpoint endpoint = new MetricsEndpoint(composite);
MetricsEndpoint.MetricResponse response = endpoint.metric("cache",
Collections.emptyList());
assertThat(response.getName()).isEqualTo("cache");
assertThat(availableTagKeys(response)).containsExactly("result", "host");
assertThat(getCount(response)).hasValue(6.0);
response = endpoint.metric("cache", Collections.singletonList("result:hit"));
assertThat(availableTagKeys(response)).containsExactly("host");
assertThat(getCount(response)).hasValue(4.0);
}
@Test
public void matchingMeterNotFoundInNestedRegistries() {
CompositeMeterRegistry composite = new CompositeMeterRegistry();
CompositeMeterRegistry firstLevel = new CompositeMeterRegistry();
SimpleMeterRegistry secondLevel = new SimpleMeterRegistry();
composite.add(firstLevel);
firstLevel.add(secondLevel);
MetricsEndpoint endpoint = new MetricsEndpoint(composite);
MetricsEndpoint.MetricResponse response = endpoint.metric("invalid.metric.name",
Collections.emptyList());
assertThat(response).isNull();
}
@Test
public void metricTagValuesAreDeduplicated() {
this.registry.counter("cache", "host", "1", "region", "east", "result", "hit");