Refactor metrics to expose richer feature set
Main user-facing interface is still Counter/GaugeService but the back end behind that has more options. The Default*Services write metrics to a MetricWriter and there are some variants of that, and also variants of MetricReader (basic read-only actions). MetricRepository is now a combination of MetricReader, MetricWriter and some more methods that make it a bit more repository like. There is also a MultiMetricReader and a MultiMetricRepository for the common case where metrics are stored in related (often open ended) groups. Examples would be complex metrics like histograms and "rich" metrics with averages and statistics attached (which are both closed) and "field counters" which count the occurrences of values of a particular named field or slot in an incoming message (e.g. counting Twitter hastags, open ended). In memory and redis implementations are provided for the repositories. Generally speaking the in memory repository should be used as a local buffer and then scheduled "exports" can be executed to copy metric values accross to a remote repository for aggregation. There is an Exporter interface to support this and a few implementations dealing with different strategies for storing the results (singly or grouped). Codahale metrics are also supported through the MetricWriter interface. Currently implemented through a naming convention (since Codahale has a fixed object model this makes sense): metrics beginning with "histogram" are Histograms, "timer" for Timers, "meter" for Meters etc. Support for message driven metric consumption and production are provided through a MetricWriterMessageHandler and a MessageChannelMetricWriter. No support yet for pagination in the repositories, or for HATEOAS style HTTP endpoints.
This commit is contained in:
@@ -64,7 +64,7 @@ public class MetricFilterAutoConfigurationTests {
|
||||
}).given(chain).doFilter(request, response);
|
||||
filter.doFilter(request, response, chain);
|
||||
verify(context.getBean(CounterService.class)).increment("status.200.test.path");
|
||||
verify(context.getBean(GaugeService.class)).set(eq("response.test.path"),
|
||||
verify(context.getBean(GaugeService.class)).submit(eq("response.test.path"),
|
||||
anyDouble());
|
||||
context.close();
|
||||
}
|
||||
|
||||
@@ -16,34 +16,79 @@
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.actuate.autoconfigure.MetricRepositoryAutoConfiguration;
|
||||
import org.springframework.boot.actuate.metrics.CounterService;
|
||||
import org.springframework.boot.actuate.metrics.DefaultCounterService;
|
||||
import org.springframework.boot.actuate.metrics.DefaultGaugeService;
|
||||
import org.springframework.boot.actuate.metrics.GaugeService;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
||||
import org.springframework.boot.actuate.metrics.writer.DefaultCounterService;
|
||||
import org.springframework.boot.actuate.metrics.writer.DefaultGaugeService;
|
||||
import org.springframework.boot.actuate.metrics.writer.MetricWriter;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.task.SyncTaskExecutor;
|
||||
|
||||
import com.codahale.metrics.Gauge;
|
||||
import com.codahale.metrics.MetricRegistry;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link MetricRepositoryAutoConfiguration}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class MetricRepositoryAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void createServices() {
|
||||
public void createServices() throws Exception {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
SyncTaskExecutorConfiguration.class,
|
||||
MetricRepositoryAutoConfiguration.class);
|
||||
assertNotNull(context.getBean(DefaultGaugeService.class));
|
||||
DefaultGaugeService gaugeService = context.getBean(DefaultGaugeService.class);
|
||||
assertNotNull(gaugeService);
|
||||
assertNotNull(context.getBean(DefaultCounterService.class));
|
||||
gaugeService.submit("foo", 2.7);
|
||||
assertEquals(2.7, context.getBean(MetricReader.class).findOne("gauge.foo")
|
||||
.getValue());
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void provideAdditionalWriter() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
SyncTaskExecutorConfiguration.class, WriterConfig.class,
|
||||
MetricRepositoryAutoConfiguration.class);
|
||||
DefaultGaugeService gaugeService = context.getBean(DefaultGaugeService.class);
|
||||
assertNotNull(gaugeService);
|
||||
gaugeService.submit("foo", 2.7);
|
||||
MetricWriter writer = context.getBean("writer", MetricWriter.class);
|
||||
verify(writer).set(any(Metric.class));
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void codahaleInstalledIfPresent() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
SyncTaskExecutorConfiguration.class, WriterConfig.class,
|
||||
MetricRepositoryAutoConfiguration.class);
|
||||
DefaultGaugeService gaugeService = context.getBean(DefaultGaugeService.class);
|
||||
assertNotNull(gaugeService);
|
||||
gaugeService.submit("foo", 2.7);
|
||||
MetricRegistry registry = context.getBean(MetricRegistry.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
Gauge<Double> gauge = (Gauge<Double>) registry.getMetrics().get("gauge.foo");
|
||||
assertEquals(new Double(2.7), gauge.getValue());
|
||||
context.close();
|
||||
}
|
||||
|
||||
@@ -56,6 +101,26 @@ public class MetricRepositoryAutoConfigurationTests {
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class SyncTaskExecutorConfiguration {
|
||||
|
||||
@Bean
|
||||
public Executor metricsExecutor() {
|
||||
return new SyncTaskExecutor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class WriterConfig {
|
||||
|
||||
@Bean
|
||||
public MetricWriter writer() {
|
||||
return mock(MetricWriter.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class Config {
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ public class MetricsEndpointTests extends AbstractEndpointTests<MetricsEndpoint>
|
||||
|
||||
@Test
|
||||
public void invoke() throws Exception {
|
||||
assertThat(getEndpointBean().invoke().get("a"), equalTo((Object) 0.5));
|
||||
assertThat(getEndpointBean().invoke().get("a"), equalTo((Object) 0.5f));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -50,11 +50,11 @@ public class MetricsEndpointTests extends AbstractEndpointTests<MetricsEndpoint>
|
||||
|
||||
@Bean
|
||||
public MetricsEndpoint endpoint() {
|
||||
final Metric metric = new Metric("a", 0.5f);
|
||||
final Metric<Float> metric = new Metric<Float>("a", 0.5f);
|
||||
PublicMetrics metrics = new PublicMetrics() {
|
||||
@Override
|
||||
public Collection<Metric> metrics() {
|
||||
return Collections.singleton(metric);
|
||||
public Collection<Metric<?>> metrics() {
|
||||
return Collections.<Metric<?>> singleton(metric);
|
||||
}
|
||||
};
|
||||
return new MetricsEndpoint(metrics);
|
||||
|
||||
@@ -21,9 +21,8 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.actuate.endpoint.VanillaPublicMetrics;
|
||||
import org.springframework.boot.actuate.metrics.InMemoryMetricRepository;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.repository.InMemoryMetricRepository;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
@@ -39,14 +38,14 @@ public class VanillaPublicMetricsTests {
|
||||
@Test
|
||||
public void testMetrics() throws Exception {
|
||||
InMemoryMetricRepository repository = new InMemoryMetricRepository();
|
||||
repository.set("a", 0.5, new Date());
|
||||
repository.set(new Metric<Double>("a", 0.5, new Date()));
|
||||
VanillaPublicMetrics publicMetrics = new VanillaPublicMetrics(repository);
|
||||
Map<String, Metric> results = new HashMap<String, Metric>();
|
||||
for (Metric metric : publicMetrics.metrics()) {
|
||||
Map<String, Metric<?>> results = new HashMap<String, Metric<?>>();
|
||||
for (Metric<?> metric : publicMetrics.metrics()) {
|
||||
results.put(metric.getName(), metric);
|
||||
}
|
||||
assertTrue(results.containsKey("mem"));
|
||||
assertTrue(results.containsKey("mem.free"));
|
||||
assertThat(results.get("a").getValue(), equalTo(0.5));
|
||||
assertThat(results.get("a").getValue().doubleValue(), equalTo(0.5));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests for {@link InMemoryMetricRepository}.
|
||||
*/
|
||||
public class InMemoryMetricRepositoryTests {
|
||||
|
||||
private InMemoryMetricRepository repository = new InMemoryMetricRepository();
|
||||
|
||||
@Test
|
||||
public void increment() {
|
||||
this.repository.increment("foo", 1, new Date());
|
||||
assertEquals(1.0, this.repository.findOne("foo").getValue(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void incrementConcurrent() throws Exception {
|
||||
Collection<Callable<Boolean>> tasks = new ArrayList<Callable<Boolean>>();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
tasks.add(new Callable<Boolean>() {
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
InMemoryMetricRepositoryTests.this.repository.increment("foo", 1,
|
||||
new Date());
|
||||
return true;
|
||||
}
|
||||
});
|
||||
tasks.add(new Callable<Boolean>() {
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
InMemoryMetricRepositoryTests.this.repository.increment("foo", -1,
|
||||
new Date());
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
List<Future<Boolean>> all = Executors.newFixedThreadPool(10).invokeAll(tasks);
|
||||
for (Future<Boolean> future : all) {
|
||||
assertTrue(future.get(1, TimeUnit.SECONDS));
|
||||
}
|
||||
assertEquals(0, this.repository.findOne("foo").getValue(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void set() {
|
||||
this.repository.set("foo", 1, new Date());
|
||||
assertEquals(1.0, this.repository.findOne("foo").getValue(), 0.01);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public abstract class Iterables {
|
||||
|
||||
public static <T> Collection<T> collection(Iterable<T> iterable) {
|
||||
if (iterable instanceof Collection) {
|
||||
return (Collection<T>) iterable;
|
||||
}
|
||||
ArrayList<T> list = new ArrayList<T>();
|
||||
for (T t : iterable) {
|
||||
list.add(t);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.export;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.repository.InMemoryMetricRepository;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class MetricCopyExporterTests {
|
||||
|
||||
private InMemoryMetricRepository writer = new InMemoryMetricRepository();
|
||||
private InMemoryMetricRepository reader = new InMemoryMetricRepository();
|
||||
private MetricCopyExporter exporter = new MetricCopyExporter(this.reader, this.writer);
|
||||
|
||||
@Test
|
||||
public void export() {
|
||||
this.reader.set(new Metric<Number>("foo", 2.3));
|
||||
this.exporter.export();
|
||||
assertEquals(1, this.writer.count());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void timestamp() {
|
||||
this.reader.set(new Metric<Number>("foo", 2.3));
|
||||
this.exporter.setEarliestTimestamp(new Date(System.currentTimeMillis() + 10000));
|
||||
this.exporter.export();
|
||||
assertEquals(0, this.writer.count());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ignoreTimestamp() {
|
||||
this.reader.set(new Metric<Number>("foo", 2.3));
|
||||
this.exporter.setIgnoreTimestamps(true);
|
||||
this.exporter.setEarliestTimestamp(new Date(System.currentTimeMillis() + 10000));
|
||||
this.exporter.export();
|
||||
assertEquals(1, this.writer.count());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.export;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
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 static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class PrefixMetricGroupExporterTests {
|
||||
|
||||
private InMemoryMetricRepository writer = new InMemoryMetricRepository();
|
||||
private InMemoryMetricRepository reader = new InMemoryMetricRepository();
|
||||
private 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.exporter.setGroups(Collections.singleton("foo"));
|
||||
this.exporter.export();
|
||||
assertEquals(1, Iterables.collection(this.writer.groups()).size());
|
||||
}
|
||||
|
||||
@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.exporter.setGroups(Collections.singleton("bar"));
|
||||
this.exporter.export();
|
||||
assertEquals(0, Iterables.collection(this.writer.groups()).size());
|
||||
}
|
||||
|
||||
@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.exporter.setGroups(Collections.singleton("foo"));
|
||||
this.exporter.export();
|
||||
assertEquals(1, Iterables.collection(this.writer.groups()).size());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.export;
|
||||
|
||||
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.rich.InMemoryRichGaugeRepository;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class RichGaugeExporterTests {
|
||||
|
||||
private InMemoryRichGaugeRepository reader = new InMemoryRichGaugeRepository();
|
||||
private InMemoryMetricRepository writer = new InMemoryMetricRepository();
|
||||
private RichGaugeExporter exporter = new RichGaugeExporter(this.reader, this.writer);
|
||||
|
||||
@Test
|
||||
public void prefixedMetricsCopied() {
|
||||
this.reader.set(new Metric<Number>("foo", 2.3));
|
||||
this.exporter.export();
|
||||
assertEquals(1, Iterables.collection(this.writer.groups()).size());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.Date;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.repository.InMemoryMetricRepository;
|
||||
import org.springframework.boot.actuate.metrics.writer.Delta;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Tests for {@link InMemoryMetricRepository}.
|
||||
*/
|
||||
public class InMemoryMetricRepositoryTests {
|
||||
|
||||
private InMemoryMetricRepository repository = new InMemoryMetricRepository();
|
||||
|
||||
@Test
|
||||
public void increment() {
|
||||
this.repository.increment(new Delta<Integer>("foo", 1, new Date()));
|
||||
assertEquals(1.0, this.repository.findOne("foo").getValue().doubleValue(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void set() {
|
||||
this.repository.set(new Metric<Double>("foo", 2.5, new Date()));
|
||||
assertEquals(2.5, this.repository.findOne("foo").getValue().doubleValue(), 0.01);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.writer.Delta;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class InMemoryPrefixMetricRepositoryTests {
|
||||
|
||||
private InMemoryMetricRepository repository = new InMemoryMetricRepository();
|
||||
|
||||
@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));
|
||||
Set<String> names = new HashSet<String>();
|
||||
for (Metric<?> metric : this.repository.findAll("foo")) {
|
||||
names.add(metric.getName());
|
||||
}
|
||||
assertEquals(2, names.size());
|
||||
assertTrue(names.contains("foo.bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void perfixWithWildcard() {
|
||||
this.repository.increment(new Delta<Number>("foo.bar", 1));
|
||||
Set<String> names = new HashSet<String>();
|
||||
for (Metric<?> metric : this.repository.findAll("foo.*")) {
|
||||
names.add(metric.getName());
|
||||
}
|
||||
assertEquals(1, names.size());
|
||||
assertTrue(names.contains("foo.bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void perfixWithPeriod() {
|
||||
this.repository.increment(new Delta<Number>("foo.bar", 1));
|
||||
Set<String> names = new HashSet<String>();
|
||||
for (Metric<?> metric : this.repository.findAll("foo.")) {
|
||||
names.add(metric.getName());
|
||||
}
|
||||
assertEquals(1, names.size());
|
||||
assertTrue(names.contains("foo.bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onlyRegisteredPrefixCounted() {
|
||||
this.repository.increment(new Delta<Number>("foo.bar", 1));
|
||||
this.repository.increment(new Delta<Number>("foobar.spam", 1));
|
||||
Set<String> names = new HashSet<String>();
|
||||
for (Metric<?> metric : this.repository.findAll("foo")) {
|
||||
names.add(metric.getName());
|
||||
}
|
||||
assertEquals(1, names.size());
|
||||
assertTrue(names.contains("foo.bar"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.redis;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.actuate.metrics.Iterables;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.writer.Delta;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class RedisMetricRepositoryTests {
|
||||
|
||||
@Rule
|
||||
public RedisServer redis = RedisServer.running();
|
||||
private RedisMetricRepository repository;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
this.repository = new RedisMetricRepository(this.redis.getResource());
|
||||
}
|
||||
|
||||
@After
|
||||
public void clear() {
|
||||
assertNotNull(new StringRedisTemplate(this.redis.getResource()).opsForValue()
|
||||
.get("spring.metrics.foo"));
|
||||
this.repository.reset("foo");
|
||||
this.repository.reset("bar");
|
||||
assertNull(new StringRedisTemplate(this.redis.getResource()).opsForValue().get(
|
||||
"spring.metrics.foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndGet() {
|
||||
this.repository.set(new Metric<Number>("foo", 12.3));
|
||||
Metric<?> metric = this.repository.findOne("foo");
|
||||
assertEquals("foo", metric.getName());
|
||||
assertEquals(12.3, metric.getValue().doubleValue(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void incrementAndGet() {
|
||||
this.repository.increment(new Delta<Long>("foo", 3L));
|
||||
assertEquals(3, this.repository.findOne("foo").getValue().longValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findAll() {
|
||||
this.repository.increment(new Delta<Long>("foo", 3L));
|
||||
this.repository.set(new Metric<Number>("bar", 12.3));
|
||||
assertEquals(2, Iterables.collection(this.repository.findAll()).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findOneWithAll() {
|
||||
this.repository.increment(new Delta<Long>("foo", 3L));
|
||||
Metric<?> metric = this.repository.findAll().iterator().next();
|
||||
assertEquals("foo", metric.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void count() {
|
||||
this.repository.increment(new Delta<Long>("foo", 3L));
|
||||
this.repository.set(new Metric<Number>("bar", 12.3));
|
||||
assertEquals(2, this.repository.count());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.redis;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.actuate.metrics.Iterables;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class RedisMultiMetricRepositoryTests {
|
||||
|
||||
@Rule
|
||||
public RedisServer redis = RedisServer.running();
|
||||
private RedisMultiMetricRepository repository;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
this.repository = new RedisMultiMetricRepository(this.redis.getResource());
|
||||
}
|
||||
|
||||
@After
|
||||
public void clear() {
|
||||
assertTrue(new StringRedisTemplate(this.redis.getResource()).opsForZSet().size(
|
||||
"spring.groups.foo") > 0);
|
||||
this.repository.reset("foo");
|
||||
this.repository.reset("bar");
|
||||
assertNull(new StringRedisTemplate(this.redis.getResource()).opsForValue().get(
|
||||
"spring.groups.foo"));
|
||||
assertNull(new StringRedisTemplate(this.redis.getResource()).opsForValue().get(
|
||||
"spring.groups.bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndGet() {
|
||||
this.repository.save("foo", Arrays.<Metric<?>> asList(new Metric<Number>(
|
||||
"foo.val", 12.3), new Metric<Number>("foo.bar", 11.3)));
|
||||
assertEquals(2, Iterables.collection(this.repository.findAll("foo")).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void groups() {
|
||||
this.repository.save("foo", Arrays.<Metric<?>> asList(new Metric<Number>(
|
||||
"foo.val", 12.3), new Metric<Number>("foo.bar", 11.3)));
|
||||
this.repository.save("bar", Arrays.<Metric<?>> asList(new Metric<Number>(
|
||||
"bar.val", 12.3), new Metric<Number>("bar.foo", 11.3)));
|
||||
assertEquals(2, Iterables.collection(this.repository.groups()).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void count() {
|
||||
this.repository.save("foo", Arrays.<Metric<?>> asList(new Metric<Number>(
|
||||
"foo.val", 12.3), new Metric<Number>("foo.bar", 11.3)));
|
||||
this.repository.save("bar", Arrays.<Metric<?>> asList(new Metric<Number>(
|
||||
"bar.val", 12.3), new Metric<Number>("bar.foo", 11.3)));
|
||||
assertEquals(2, this.repository.count());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.redis;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Assume;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* @author Eric Bottard
|
||||
* @author Gary Russell
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class RedisServer implements TestRule {
|
||||
|
||||
private static final String EXTERNAL_SERVERS_REQUIRED = "EXTERNAL_SERVERS_REQUIRED";
|
||||
|
||||
protected LettuceConnectionFactory resource;
|
||||
|
||||
private String resourceDescription = "Redis ConnectionFactory";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(RedisServer.class);
|
||||
|
||||
public static RedisServer running() {
|
||||
return new RedisServer();
|
||||
}
|
||||
|
||||
private RedisServer() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement apply(final Statement base, Description description) {
|
||||
try {
|
||||
this.resource = obtainResource();
|
||||
}
|
||||
catch (Exception e) {
|
||||
maybeCleanup();
|
||||
|
||||
return failOrSkip(e);
|
||||
}
|
||||
|
||||
return new Statement() {
|
||||
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
try {
|
||||
base.evaluate();
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
cleanupResource();
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
RedisServer.logger.warn(
|
||||
"Exception while trying to cleanup proper resource",
|
||||
ignored);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private Statement failOrSkip(Exception e) {
|
||||
String serversRequired = System.getenv(EXTERNAL_SERVERS_REQUIRED);
|
||||
if ("true".equalsIgnoreCase(serversRequired)) {
|
||||
logger.error(this.resourceDescription + " IS REQUIRED BUT NOT AVAILABLE", e);
|
||||
fail(this.resourceDescription + " IS NOT AVAILABLE");
|
||||
// Never reached, here to satisfy method signature
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
logger.error(this.resourceDescription + " IS NOT AVAILABLE, SKIPPING TESTS",
|
||||
e);
|
||||
return new Statement() {
|
||||
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
Assume.assumeTrue("Skipping test due to "
|
||||
+ RedisServer.this.resourceDescription
|
||||
+ " not being available", false);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeCleanup() {
|
||||
if (this.resource != null) {
|
||||
try {
|
||||
cleanupResource();
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
logger.warn("Exception while trying to cleanup failed resource", ignored);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RedisConnectionFactory getResource() {
|
||||
return this.resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform cleanup of the {@link #resource} field, which is guaranteed to be non null.
|
||||
*
|
||||
* @throws Exception any exception thrown by this method will be logged and swallowed
|
||||
*/
|
||||
protected void cleanupResource() throws Exception {
|
||||
this.resource.destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to obtain and validate a resource. Implementors should either set the
|
||||
* {@link #resource} field with a valid resource and return normally, or throw an
|
||||
* exception.
|
||||
*/
|
||||
protected LettuceConnectionFactory obtainResource() throws Exception {
|
||||
LettuceConnectionFactory resource = new LettuceConnectionFactory();
|
||||
resource.afterPropertiesSet();
|
||||
resource.getConnection().close();
|
||||
return resource;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.rich;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class InMemoryRichGaugeRepositoryTests {
|
||||
|
||||
private InMemoryRichGaugeRepository repository = new InMemoryRichGaugeRepository();
|
||||
|
||||
@Test
|
||||
public void writeAndRead() {
|
||||
this.repository.set(new Metric<Double>("foo", 1d));
|
||||
this.repository.set(new Metric<Double>("foo", 2d));
|
||||
assertEquals(2L, this.repository.findOne("foo").getCount());
|
||||
assertEquals(2d, this.repository.findOne("foo").getValue(), 0.01);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.actuate.metrics.util.SimpleInMemoryRepository.Callback;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class InMemoryRepositoryTests {
|
||||
|
||||
private SimpleInMemoryRepository<String> repository = new SimpleInMemoryRepository<String>();
|
||||
|
||||
@Test
|
||||
public void setAndGet() {
|
||||
this.repository.set("foo", "bar");
|
||||
assertEquals("bar", this.repository.findOne("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateExisting() {
|
||||
this.repository.set("foo", "spam");
|
||||
this.repository.update("foo", new Callback<String>() {
|
||||
@Override
|
||||
public String modify(String current) {
|
||||
return "bar";
|
||||
}
|
||||
});
|
||||
assertEquals("bar", this.repository.findOne("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateNonexistent() {
|
||||
this.repository.update("foo", new Callback<String>() {
|
||||
@Override
|
||||
public String modify(String current) {
|
||||
return "bar";
|
||||
}
|
||||
});
|
||||
assertEquals("bar", this.repository.findOne("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findWithPrefix() {
|
||||
this.repository.set("foo", "bar");
|
||||
this.repository.set("foo.bar", "one");
|
||||
this.repository.set("foo.min", "two");
|
||||
this.repository.set("foo.max", "three");
|
||||
assertEquals(3, ((Collection<?>) this.repository.findAllWithPrefix("foo")).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patternsAcceptedForRegisteredPrefix() {
|
||||
this.repository.set("foo.bar", "spam");
|
||||
Iterator<String> iterator = this.repository.findAllWithPrefix("foo.*").iterator();
|
||||
assertEquals("spam", iterator.next());
|
||||
assertFalse(iterator.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateConcurrent() throws Exception {
|
||||
final SimpleInMemoryRepository<Integer> repository = new SimpleInMemoryRepository<Integer>();
|
||||
Collection<Callable<Boolean>> tasks = new ArrayList<Callable<Boolean>>();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
tasks.add(new Callable<Boolean>() {
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
repository.update("foo", new Callback<Integer>() {
|
||||
@Override
|
||||
public Integer modify(Integer current) {
|
||||
if (current == null) {
|
||||
return 1;
|
||||
}
|
||||
return current + 1;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
tasks.add(new Callable<Boolean>() {
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
repository.update("foo", new Callback<Integer>() {
|
||||
@Override
|
||||
public Integer modify(Integer current) {
|
||||
if (current == null) {
|
||||
return -1;
|
||||
}
|
||||
return current - 1;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
List<Future<Boolean>> all = Executors.newFixedThreadPool(10).invokeAll(tasks);
|
||||
for (Future<Boolean> future : all) {
|
||||
assertTrue(future.get(1, TimeUnit.SECONDS));
|
||||
}
|
||||
assertEquals(new Integer(0), repository.findOne("foo"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.writer;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
|
||||
import com.codahale.metrics.Gauge;
|
||||
import com.codahale.metrics.MetricRegistry;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class CodahaleMetricWriterTests {
|
||||
|
||||
private MetricRegistry registry = new MetricRegistry();
|
||||
private CodahaleMetricWriter writer = new CodahaleMetricWriter(this.registry);
|
||||
|
||||
@Test
|
||||
public void incrementCounter() {
|
||||
this.writer.increment(new Delta<Number>("foo", 2));
|
||||
this.writer.increment(new Delta<Number>("foo", 1));
|
||||
assertEquals(3, this.registry.counter("foo").getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePredefinedMeter() {
|
||||
this.writer.increment(new Delta<Number>("meter.foo", 2));
|
||||
this.writer.increment(new Delta<Number>("meter.foo", 1));
|
||||
assertEquals(3, this.registry.meter("meter.foo").getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePredefinedCounter() {
|
||||
this.writer.increment(new Delta<Number>("counter.foo", 2));
|
||||
this.writer.increment(new Delta<Number>("counter.foo", 1));
|
||||
assertEquals(3, this.registry.counter("counter.foo").getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setGauge() {
|
||||
this.writer.set(new Metric<Number>("foo", 2.1));
|
||||
this.writer.set(new Metric<Number>("foo", 2.3));
|
||||
@SuppressWarnings("unchecked")
|
||||
Gauge<Double> gauge = (Gauge<Double>) this.registry.getMetrics().get("foo");
|
||||
assertEquals(new Double(2.3), gauge.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setPredfinedTimer() {
|
||||
this.writer.set(new Metric<Number>("timer.foo", 200));
|
||||
this.writer.set(new Metric<Number>("timer.foo", 300));
|
||||
assertEquals(2, this.registry.timer("timer.foo").getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setPredfinedHistogram() {
|
||||
this.writer.set(new Metric<Number>("histogram.foo", 2.1));
|
||||
this.writer.set(new Metric<Number>("histogram.foo", 2.3));
|
||||
assertEquals(2, this.registry.histogram("histogram.foo").getCount());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,14 +14,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics;
|
||||
|
||||
import java.util.Date;
|
||||
package org.springframework.boot.actuate.metrics.writer;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.boot.actuate.metrics.writer.DefaultCounterService;
|
||||
import org.springframework.boot.actuate.metrics.writer.Delta;
|
||||
import org.springframework.boot.actuate.metrics.writer.MetricWriter;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@@ -30,19 +31,26 @@ import static org.mockito.Mockito.verify;
|
||||
*/
|
||||
public class DefaultCounterServiceTests {
|
||||
|
||||
private MetricRepository repository = mock(MetricRepository.class);
|
||||
private MetricWriter repository = mock(MetricWriter.class);
|
||||
|
||||
private DefaultCounterService service = new DefaultCounterService(this.repository);
|
||||
|
||||
@Test
|
||||
public void incrementPrependsCounter() {
|
||||
this.service.increment("foo");
|
||||
verify(this.repository).increment(eq("counter.foo"), eq(1), any(Date.class));
|
||||
@SuppressWarnings("rawtypes")
|
||||
ArgumentCaptor<Delta> captor = ArgumentCaptor.forClass(Delta.class);
|
||||
verify(this.repository).increment(captor.capture());
|
||||
assertEquals("counter.foo", captor.getValue().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decrementPrependsCounter() {
|
||||
this.service.decrement("foo");
|
||||
verify(this.repository).increment(eq("counter.foo"), eq(-1), any(Date.class));
|
||||
@SuppressWarnings("rawtypes")
|
||||
ArgumentCaptor<Delta> captor = ArgumentCaptor.forClass(Delta.class);
|
||||
verify(this.repository).increment(captor.capture());
|
||||
assertEquals("counter.foo", captor.getValue().getName());
|
||||
assertEquals(-1L, captor.getValue().getValue());
|
||||
}
|
||||
}
|
||||
@@ -14,14 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics;
|
||||
|
||||
import java.util.Date;
|
||||
package org.springframework.boot.actuate.metrics.writer;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@@ -30,14 +29,18 @@ import static org.mockito.Mockito.verify;
|
||||
*/
|
||||
public class DefaultGaugeServiceTests {
|
||||
|
||||
private MetricRepository repository = mock(MetricRepository.class);
|
||||
private MetricWriter repository = mock(MetricWriter.class);
|
||||
|
||||
private DefaultGaugeService service = new DefaultGaugeService(this.repository);
|
||||
|
||||
@Test
|
||||
public void setPrependsGuager() {
|
||||
this.service.set("foo", 2.3);
|
||||
verify(this.repository).set(eq("gauge.foo"), eq(2.3), any(Date.class));
|
||||
public void setPrependsGauge() {
|
||||
this.service.submit("foo", 2.3);
|
||||
@SuppressWarnings("rawtypes")
|
||||
ArgumentCaptor<Metric> captor = ArgumentCaptor.forClass(Metric.class);
|
||||
verify(this.repository).set(captor.capture());
|
||||
assertEquals("gauge.foo", captor.getValue().getName());
|
||||
assertEquals(2.3, captor.getValue().getValue());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.writer;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class MessageChannelMetricWriterTests {
|
||||
|
||||
private MessageChannel channel = mock(MessageChannel.class);
|
||||
|
||||
private MessageChannelMetricWriter observer = new MessageChannelMetricWriter(
|
||||
this.channel);
|
||||
|
||||
@Test
|
||||
public void messageSentOnAdd() {
|
||||
this.observer.increment(new Delta<Integer>("foo", 1));
|
||||
verify(this.channel).send(any(Message.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void messageSentOnSet() {
|
||||
this.observer.set(new Metric<Double>("foo", 1d));
|
||||
verify(this.channel).send(any(Message.class));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user