Move InMemoryMultiMetricRepository to a separate class
This commit moves the `MultiMetricRepository` implementation from `InMemoryMetricRepository` to `InMemoryMultiMetricRepository`. Both implementations can share the same underlying store (and are for backward compatible reasons). The side effect is that `reset` now works as expected for a group. Closes gh-7687
This commit is contained in:
parent
25bd0e0455
commit
8b7055719f
|
|
@ -28,6 +28,7 @@ import org.springframework.boot.actuate.metrics.buffer.GaugeBuffers;
|
|||
import org.springframework.boot.actuate.metrics.export.Exporter;
|
||||
import org.springframework.boot.actuate.metrics.export.MetricCopyExporter;
|
||||
import org.springframework.boot.actuate.metrics.repository.InMemoryMetricRepository;
|
||||
import org.springframework.boot.actuate.metrics.repository.InMemoryMultiMetricRepository;
|
||||
import org.springframework.boot.actuate.metrics.writer.DefaultCounterService;
|
||||
import org.springframework.boot.actuate.metrics.writer.DefaultGaugeService;
|
||||
import org.springframework.boot.actuate.metrics.writer.MetricWriter;
|
||||
|
|
@ -154,6 +155,13 @@ public class MetricRepositoryAutoConfiguration {
|
|||
return new InMemoryMetricRepository();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ExportMetricReader
|
||||
@ActuatorMetricWriter
|
||||
public InMemoryMultiMetricRepository actuatorMultiMetricRepository() {
|
||||
return new InMemoryMultiMetricRepository(actuatorMetricRepository());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,7 @@
|
|||
|
||||
package org.springframework.boot.actuate.metrics.repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ConcurrentNavigableMap;
|
||||
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
|
|
@ -28,17 +25,15 @@ import org.springframework.boot.actuate.metrics.util.SimpleInMemoryRepository.Ca
|
|||
import org.springframework.boot.actuate.metrics.writer.Delta;
|
||||
|
||||
/**
|
||||
* {@link MetricRepository} and {@link MultiMetricRepository} implementation that stores
|
||||
* metrics in memory.
|
||||
* {@link MetricRepository} implementation that stores metrics in memory.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class InMemoryMetricRepository implements MetricRepository, MultiMetricRepository {
|
||||
public class InMemoryMetricRepository implements MetricRepository {
|
||||
|
||||
private final SimpleInMemoryRepository<Metric<?>> metrics = new SimpleInMemoryRepository<Metric<?>>();
|
||||
|
||||
private final Collection<String> groups = new HashSet<String>();
|
||||
|
||||
public void setValues(ConcurrentNavigableMap<String, Metric<?>> values) {
|
||||
this.metrics.setValues(values);
|
||||
}
|
||||
|
|
@ -52,12 +47,11 @@ public class InMemoryMetricRepository implements MetricRepository, MultiMetricRe
|
|||
@Override
|
||||
public Metric<?> modify(Metric<?> current) {
|
||||
if (current != null) {
|
||||
Metric<? extends Number> metric = current;
|
||||
return new Metric<Long>(metricName,
|
||||
metric.increment(amount).getValue(), timestamp);
|
||||
current.increment(amount).getValue(), timestamp);
|
||||
}
|
||||
else {
|
||||
return new Metric<Long>(metricName, Long.valueOf(amount), timestamp);
|
||||
return new Metric<Long>(metricName, (long) amount, timestamp);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -68,51 +62,11 @@ public class InMemoryMetricRepository implements MetricRepository, MultiMetricRe
|
|||
this.metrics.set(value.getName(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(String group, Collection<Metric<?>> values) {
|
||||
String prefix = group;
|
||||
if (!prefix.endsWith(".")) {
|
||||
prefix = prefix + ".";
|
||||
}
|
||||
for (Metric<?> metric : values) {
|
||||
if (!metric.getName().startsWith(prefix)) {
|
||||
metric = new Metric<Number>(prefix + metric.getName(), metric.getValue(),
|
||||
metric.getTimestamp());
|
||||
}
|
||||
set(metric);
|
||||
}
|
||||
this.groups.add(group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increment(String group, Delta<?> delta) {
|
||||
String prefix = group;
|
||||
if (!prefix.endsWith(".")) {
|
||||
prefix = prefix + ".";
|
||||
}
|
||||
if (!delta.getName().startsWith(prefix)) {
|
||||
delta = new Delta<Number>(prefix + delta.getName(), delta.getValue(),
|
||||
delta.getTimestamp());
|
||||
}
|
||||
increment(delta);
|
||||
this.groups.add(group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> groups() {
|
||||
return Collections.unmodifiableCollection(this.groups);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
return this.metrics.count();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long countGroups() {
|
||||
return this.groups.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(String metricName) {
|
||||
this.metrics.remove(metricName);
|
||||
|
|
@ -128,9 +82,8 @@ public class InMemoryMetricRepository implements MetricRepository, MultiMetricRe
|
|||
return this.metrics.findAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Metric<?>> findAll(String metricNamePrefix) {
|
||||
return this.metrics.findAllWithPrefix(metricNamePrefix);
|
||||
public Iterable<Metric<?>> findAllWithPrefix(String prefix) {
|
||||
return this.metrics.findAllWithPrefix(prefix);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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.repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.writer.Delta;
|
||||
|
||||
/**
|
||||
* {@link MultiMetricRepository} implementation backed by a
|
||||
* {@link InMemoryMetricRepository}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class InMemoryMultiMetricRepository implements MultiMetricRepository {
|
||||
|
||||
private final InMemoryMetricRepository repository;
|
||||
|
||||
private final Collection<String> groups = new HashSet<String>();
|
||||
|
||||
public InMemoryMultiMetricRepository(InMemoryMetricRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public InMemoryMultiMetricRepository() {
|
||||
this(new InMemoryMetricRepository());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(String group, Collection<Metric<?>> values) {
|
||||
String prefix = group;
|
||||
if (!prefix.endsWith(".")) {
|
||||
prefix = prefix + ".";
|
||||
}
|
||||
for (Metric<?> metric : values) {
|
||||
if (!metric.getName().startsWith(prefix)) {
|
||||
metric = new Metric<Number>(prefix + metric.getName(), metric.getValue(),
|
||||
metric.getTimestamp());
|
||||
}
|
||||
this.repository.set(metric);
|
||||
}
|
||||
this.groups.add(group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increment(String group, Delta<?> delta) {
|
||||
String prefix = group;
|
||||
if (!prefix.endsWith(".")) {
|
||||
prefix = prefix + ".";
|
||||
}
|
||||
if (!delta.getName().startsWith(prefix)) {
|
||||
delta = new Delta<Number>(prefix + delta.getName(), delta.getValue(),
|
||||
delta.getTimestamp());
|
||||
}
|
||||
this.repository.increment(delta);
|
||||
this.groups.add(group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> groups() {
|
||||
return Collections.unmodifiableCollection(this.groups);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long countGroups() {
|
||||
return this.groups.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(String group) {
|
||||
for (Metric<?> metric : findAll(group)) {
|
||||
this.repository.reset(metric.getName());
|
||||
}
|
||||
this.groups.remove(group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Metric<?>> findAll(String metricNamePrefix) {
|
||||
return this.repository.findAllWithPrefix(metricNamePrefix);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ import org.junit.Test;
|
|||
|
||||
import org.springframework.boot.actuate.metrics.Iterables;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.repository.InMemoryMetricRepository;
|
||||
import org.springframework.boot.actuate.metrics.repository.InMemoryMultiMetricRepository;
|
||||
import org.springframework.boot.actuate.metrics.writer.Delta;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
|
@ -35,17 +35,17 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
*/
|
||||
public class PrefixMetricGroupExporterTests {
|
||||
|
||||
private final InMemoryMetricRepository reader = new InMemoryMetricRepository();
|
||||
private final InMemoryMultiMetricRepository reader = new InMemoryMultiMetricRepository();
|
||||
|
||||
private final InMemoryMetricRepository writer = new InMemoryMetricRepository();
|
||||
private final InMemoryMultiMetricRepository writer = new InMemoryMultiMetricRepository();
|
||||
|
||||
private final PrefixMetricGroupExporter exporter = new PrefixMetricGroupExporter(
|
||||
this.reader, this.writer);
|
||||
|
||||
@Test
|
||||
public void prefixedMetricsCopied() {
|
||||
this.reader.set(new Metric<Number>("foo.bar", 2.3));
|
||||
this.reader.set(new Metric<Number>("foo.spam", 1.3));
|
||||
this.reader.set("foo", Arrays.<Metric<?>>asList(new Metric<Number>("bar", 2.3),
|
||||
new Metric<Number>("spam", 1.3)));
|
||||
this.exporter.setGroups(Collections.singleton("foo"));
|
||||
this.exporter.export();
|
||||
assertThat(Iterables.collection(this.writer.groups())).hasSize(1);
|
||||
|
|
@ -54,7 +54,8 @@ public class PrefixMetricGroupExporterTests {
|
|||
@Test
|
||||
public void countersIncremented() {
|
||||
this.writer.increment("counter.foo", new Delta<Long>("bar", 1L));
|
||||
this.reader.set(new Metric<Number>("counter.foo.bar", 1));
|
||||
this.reader.set("counter", Collections.<Metric<?>>singletonList(
|
||||
new Metric<Number>("counter.foo.bar", 1)));
|
||||
this.exporter.setGroups(Collections.singleton("counter.foo"));
|
||||
this.exporter.export();
|
||||
assertThat(this.writer.findAll("counter.foo").iterator().next().getValue())
|
||||
|
|
@ -63,8 +64,9 @@ public class PrefixMetricGroupExporterTests {
|
|||
|
||||
@Test
|
||||
public void unprefixedMetricsNotCopied() {
|
||||
this.reader.set(new Metric<Number>("foo.bar", 2.3));
|
||||
this.reader.set(new Metric<Number>("foo.spam", 1.3));
|
||||
this.reader.set("foo", Arrays.<Metric<?>>asList(
|
||||
new Metric<Number>("foo.bar", 2.3),
|
||||
new Metric<Number>("foo.spam", 1.3)));
|
||||
this.exporter.setGroups(Collections.singleton("bar"));
|
||||
this.exporter.export();
|
||||
assertThat(Iterables.collection(this.writer.groups())).isEmpty();
|
||||
|
|
@ -81,9 +83,11 @@ public class PrefixMetricGroupExporterTests {
|
|||
|
||||
@Test
|
||||
public void onlyPrefixedMetricsCopied() {
|
||||
this.reader.set(new Metric<Number>("foo.bar", 2.3));
|
||||
this.reader.set(new Metric<Number>("foo.spam", 1.3));
|
||||
this.reader.set(new Metric<Number>("foobar.spam", 1.3));
|
||||
this.reader.set("foo", Arrays.<Metric<?>>asList(
|
||||
new Metric<Number>("foo.bar", 2.3),
|
||||
new Metric<Number>("foo.spam", 1.3)));
|
||||
this.reader.set("foobar", Collections.<Metric<?>>singletonList(
|
||||
new Metric<Number>("foobar.spam", 1.3)));
|
||||
this.exporter.setGroups(Collections.singleton("foo"));
|
||||
this.exporter.export();
|
||||
assertThat(Iterables.collection(this.writer.groups())).hasSize(1);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import org.junit.Test;
|
|||
|
||||
import org.springframework.boot.actuate.metrics.Iterables;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.repository.InMemoryMetricRepository;
|
||||
import org.springframework.boot.actuate.metrics.repository.InMemoryMultiMetricRepository;
|
||||
import org.springframework.boot.actuate.metrics.rich.InMemoryRichGaugeRepository;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
|
@ -34,7 +34,7 @@ public class RichGaugeExporterTests {
|
|||
|
||||
private final InMemoryRichGaugeRepository reader = new InMemoryRichGaugeRepository();
|
||||
|
||||
private final InMemoryMetricRepository writer = new InMemoryMetricRepository();
|
||||
private final InMemoryMultiMetricRepository writer = new InMemoryMultiMetricRepository();
|
||||
|
||||
private final RichGaugeExporter exporter = new RichGaugeExporter(this.reader,
|
||||
this.writer);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@
|
|||
|
||||
package org.springframework.boot.actuate.metrics.repository;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
|
@ -29,15 +31,16 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class InMemoryPrefixMetricRepositoryTests {
|
||||
public class InMemoryMultiMetricRepositoryTests {
|
||||
|
||||
private final InMemoryMetricRepository repository = new InMemoryMetricRepository();
|
||||
private final InMemoryMultiMetricRepository repository =
|
||||
new InMemoryMultiMetricRepository();
|
||||
|
||||
@Test
|
||||
public void registeredPrefixCounted() {
|
||||
this.repository.increment(new Delta<Number>("foo.bar", 1));
|
||||
this.repository.increment(new Delta<Number>("foo.bar", 1));
|
||||
this.repository.increment(new Delta<Number>("foo.spam", 1));
|
||||
this.repository.increment("foo", new Delta<Number>("bar", 1));
|
||||
this.repository.increment("foo", new Delta<Number>("bar", 1));
|
||||
this.repository.increment("foo", new Delta<Number>("spam", 1));
|
||||
Set<String> names = new HashSet<String>();
|
||||
for (Metric<?> metric : this.repository.findAll("foo")) {
|
||||
names.add(metric.getName());
|
||||
|
|
@ -48,7 +51,7 @@ public class InMemoryPrefixMetricRepositoryTests {
|
|||
|
||||
@Test
|
||||
public void prefixWithWildcard() {
|
||||
this.repository.increment(new Delta<Number>("foo.bar", 1));
|
||||
this.repository.increment("foo", new Delta<Number>("bar", 1));
|
||||
Set<String> names = new HashSet<String>();
|
||||
for (Metric<?> metric : this.repository.findAll("foo.*")) {
|
||||
names.add(metric.getName());
|
||||
|
|
@ -59,7 +62,7 @@ public class InMemoryPrefixMetricRepositoryTests {
|
|||
|
||||
@Test
|
||||
public void prefixWithPeriod() {
|
||||
this.repository.increment(new Delta<Number>("foo.bar", 1));
|
||||
this.repository.increment("foo", new Delta<Number>("bar", 1));
|
||||
Set<String> names = new HashSet<String>();
|
||||
for (Metric<?> metric : this.repository.findAll("foo.")) {
|
||||
names.add(metric.getName());
|
||||
|
|
@ -70,8 +73,8 @@ public class InMemoryPrefixMetricRepositoryTests {
|
|||
|
||||
@Test
|
||||
public void onlyRegisteredPrefixCounted() {
|
||||
this.repository.increment(new Delta<Number>("foo.bar", 1));
|
||||
this.repository.increment(new Delta<Number>("foobar.spam", 1));
|
||||
this.repository.increment("foo", new Delta<Number>("bar", 1));
|
||||
this.repository.increment("foobar", new Delta<Number>("spam", 1));
|
||||
Set<String> names = new HashSet<String>();
|
||||
for (Metric<?> metric : this.repository.findAll("foo")) {
|
||||
names.add(metric.getName());
|
||||
|
|
@ -85,13 +88,13 @@ public class InMemoryPrefixMetricRepositoryTests {
|
|||
this.repository.increment("foo", new Delta<Number>("foo.bar", 1));
|
||||
this.repository.increment("foo", new Delta<Number>("foo.bar", 2));
|
||||
this.repository.increment("foo", new Delta<Number>("foo.spam", 1));
|
||||
Set<String> names = new HashSet<String>();
|
||||
Map<String, Metric<?>> metrics = new HashMap<String, Metric<?>>();
|
||||
for (Metric<?> metric : this.repository.findAll("foo")) {
|
||||
names.add(metric.getName());
|
||||
metrics.put(metric.getName(), metric);
|
||||
}
|
||||
assertThat(names).hasSize(2);
|
||||
assertThat(names.contains("foo.bar")).isTrue();
|
||||
assertThat(this.repository.findOne("foo.bar").getValue()).isEqualTo(3L);
|
||||
assertThat(metrics).hasSize(2);
|
||||
assertThat(metrics).containsKeys("foo.bar", "foo.spam");
|
||||
assertThat(metrics.get("foo.bar").getValue()).isEqualTo(3L);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ import org.junit.Test;
|
|||
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.export.RichGaugeExporter;
|
||||
import org.springframework.boot.actuate.metrics.repository.InMemoryMetricRepository;
|
||||
import org.springframework.boot.actuate.metrics.repository.InMemoryMultiMetricRepository;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
*/
|
||||
public class MultiMetricRichGaugeReaderTests {
|
||||
|
||||
private InMemoryMetricRepository repository = new InMemoryMetricRepository();
|
||||
private InMemoryMultiMetricRepository repository = new InMemoryMultiMetricRepository();
|
||||
|
||||
private MultiMetricRichGaugeReader reader = new MultiMetricRichGaugeReader(
|
||||
this.repository);
|
||||
|
|
@ -47,7 +47,7 @@ public class MultiMetricRichGaugeReaderTests {
|
|||
this.data.set(new Metric<Integer>("foo", 1));
|
||||
this.exporter.export();
|
||||
// Check the exporter worked
|
||||
assertThat(this.repository.count()).isEqualTo(6);
|
||||
assertThat(this.repository.countGroups()).isEqualTo(1);
|
||||
assertThat(this.reader.count()).isEqualTo(1);
|
||||
RichGauge one = this.reader.findOne("foo");
|
||||
assertThat(one).isNotNull();
|
||||
|
|
|
|||
Loading…
Reference in New Issue