BAEL-397: netflix servo intro (#2159)

This commit is contained in:
Tian Baoqiang 2017-06-26 21:44:02 +08:00 committed by Grzegorz Piwowarek
parent c9111e635f
commit 52663a6bf5
6 changed files with 443 additions and 0 deletions

View File

@ -15,6 +15,7 @@
<properties>
<dep.ver.metrics>3.1.2</dep.ver.metrics>
<dep.ver.servlet>3.1.0</dep.ver.servlet>
<netflix.servo.ver>0.12.16</netflix.servo.ver>
</properties>
<dependencies>
@ -43,6 +44,11 @@
<artifactId>javax.servlet-api</artifactId>
<version>${dep.ver.servlet}</version>
</dependency>
<dependency>
<groupId>com.netflix.servo</groupId>
<artifactId>servo-core</artifactId>
<version>${netflix.servo.ver}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,56 @@
package com.baeldung.metrics.servo;
import com.netflix.servo.Metric;
import com.netflix.servo.annotations.DataSourceType;
import com.netflix.servo.annotations.Monitor;
import com.netflix.servo.annotations.MonitorTags;
import com.netflix.servo.monitor.Monitors;
import com.netflix.servo.tag.BasicTag;
import com.netflix.servo.tag.BasicTagList;
import com.netflix.servo.tag.TagList;
import org.junit.Test;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import static com.google.common.collect.Lists.newArrayList;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
* @author aiet
*/
public class MetricAnnotationTest extends MetricTestBase {
@Monitor(name = "integerCounter", type = DataSourceType.COUNTER, description = "Total number of update operations.")
private final AtomicInteger updateCount = new AtomicInteger(0);
@MonitorTags private TagList tags = new BasicTagList(newArrayList(new BasicTag("tag-key", "tag-value")));
@Test
public void givenAnnotatedMonitor_whenUpdated_thenDataCollected() throws Exception {
Monitors.registerObject("testObject", this);
assertTrue(Monitors.isObjectRegistered("testObject", this));
updateCount.incrementAndGet();
updateCount.incrementAndGet();
SECONDS.sleep(1);
List<List<Metric>> metrics = observer.getObservations();
System.out.println(metrics);
assertThat(metrics, hasSize(greaterThanOrEqualTo(1)));
Iterator<List<Metric>> metricIterator = metrics.iterator();
//skip first empty observation
metricIterator.next();
while (metricIterator.hasNext()) {
assertThat(metricIterator.next(), hasItem(hasProperty("config", hasProperty("name", is("integerCounter")))));
}
}
}

View File

@ -0,0 +1,70 @@
package com.baeldung.metrics.servo;
import com.netflix.servo.DefaultMonitorRegistry;
import com.netflix.servo.Metric;
import com.netflix.servo.monitor.BasicGauge;
import com.netflix.servo.monitor.DynamicCounter;
import com.netflix.servo.monitor.Gauge;
import com.netflix.servo.monitor.MonitorConfig;
import org.junit.Test;
import java.util.Iterator;
import java.util.List;
import static com.netflix.servo.annotations.DataSourceType.GAUGE;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
/**
* @author aiet
*/
public class MetricObserverTest extends MetricTestBase {
@Test
public void givenMetrics_whenRegister_thenMonitored() throws InterruptedException {
Gauge<Double> gauge = new BasicGauge<>(MonitorConfig
.builder("test")
.build(), () -> 2.32);
assertEquals(2.32, gauge.getValue(), 0.01);
DefaultMonitorRegistry
.getInstance()
.register(gauge);
for (int i = 0; i < 2; i++) {
SECONDS.sleep(1);
}
List<List<Metric>> metrics = observer.getObservations();
assertThat(metrics, hasSize(greaterThanOrEqualTo(2)));
Iterator<List<Metric>> metricIterator = metrics.iterator();
//skip first empty observation
metricIterator.next();
while (metricIterator.hasNext()) {
assertThat(metricIterator.next(), hasItem(allOf(hasProperty("config", hasProperty("tags", hasItem(GAUGE))), hasProperty("value", is(2.32)))));
}
}
@Test
public void givenMetrics_whenRegisterDynamically_thenMonitored() throws Exception {
for (int i = 0; i < 2; i++) {
DynamicCounter.increment("monitor-name", "tag-key", "tag-value");
SECONDS.sleep(1);
}
List<List<Metric>> metrics = observer.getObservations();
assertThat(metrics, hasSize(greaterThanOrEqualTo(2)));
Iterator<List<Metric>> metricIterator = metrics.iterator();
//skip first empty observation
metricIterator.next();
while (metricIterator.hasNext()) {
assertThat(metricIterator.next(), hasItem(hasProperty("value", greaterThanOrEqualTo(1.0))));
}
}
}

View File

@ -0,0 +1,50 @@
package com.baeldung.metrics.servo;
import com.netflix.servo.Metric;
import com.netflix.servo.publish.*;
import org.junit.Test;
import java.util.List;
import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.stream.Collectors.toList;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;
/**
* @author aiet
*/
public class MetricPollerTest {
@Test
public void givenJvmPoller_whenMonitor_thenDataCollected() throws Exception {
MemoryMetricObserver observer = new MemoryMetricObserver();
PollRunnable pollRunnable = new PollRunnable(new JvmMetricPoller(), new BasicMetricFilter(true), observer);
PollScheduler
.getInstance()
.start();
PollScheduler
.getInstance()
.addPoller(pollRunnable, 1, SECONDS);
SECONDS.sleep(1);
PollScheduler
.getInstance()
.stop();
List<List<Metric>> metrics = observer.getObservations();
assertThat(metrics, hasSize(greaterThanOrEqualTo(1)));
List<String> args = metrics
.stream()
.filter(m -> !m.isEmpty())
.flatMap(ms -> ms
.stream()
.map(m -> m
.getConfig()
.getName()))
.collect(toList());
assertThat(args, hasItems("loadedClassCount", "initUsage", "maxUsage", "threadCount"));
}
}

View File

@ -0,0 +1,40 @@
package com.baeldung.metrics.servo;
import com.netflix.servo.publish.*;
import org.junit.After;
import org.junit.Before;
import static java.util.concurrent.TimeUnit.SECONDS;
/**
* @author aiet
*/
abstract class MetricTestBase {
MemoryMetricObserver observer;
@Before
public void prepareScheduler() {
System.setProperty("servo.pollers", "1000");
observer = new MemoryMetricObserver();
PollScheduler
.getInstance()
.start();
MetricFilter metricFilter = new BasicMetricFilter(true);
PollRunnable task = new PollRunnable(new MonitorRegistryMetricPoller(), metricFilter, observer);
PollScheduler
.getInstance()
.addPoller(task, 1, SECONDS);
}
@After
public void stopScheduler() {
if (PollScheduler
.getInstance()
.isStarted()) {
PollScheduler
.getInstance()
.stop();
}
}
}

View File

@ -0,0 +1,221 @@
package com.baeldung.metrics.servo;
import com.netflix.servo.monitor.*;
import com.netflix.servo.stats.StatsConfig;
import org.junit.Ignore;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
/**
* Unit test for simple App.
*/
public class MetricTypeTest {
@Test
public void givenDefaultCounter_whenManipulate_thenCountValid() {
Counter counter = Monitors.newCounter("test");
assertEquals("counter should start with 0", 0, counter
.getValue()
.intValue());
counter.increment();
assertEquals("counter should have increased by 1", 1, counter
.getValue()
.intValue());
counter.increment(-1);
assertEquals("counter should have decreased by 1", 0, counter
.getValue()
.intValue());
}
@Test
public void givenBasicCounter_whenManipulate_thenCountValid() {
Counter counter = new BasicCounter(MonitorConfig
.builder("test")
.build());
assertEquals("counter should start with 0", 0, counter
.getValue()
.intValue());
counter.increment();
assertEquals("counter should have increased by 1", 1, counter
.getValue()
.intValue());
counter.increment(-1);
assertEquals("counter should have decreased by 1", 0, counter
.getValue()
.intValue());
}
@Ignore
@Test
public void givenStepCounter_whenManipulate_thenRateValid() throws Exception {
System.setProperty("servo.pollers", "1000");
Counter counter = new StepCounter(MonitorConfig
.builder("test")
.build());
assertEquals("counter should start with rate 0.0", 0.0, counter.getValue());
counter.increment();
SECONDS.sleep(1);
assertEquals("counter rate should have increased to 1.0", 1.0, counter.getValue());
}
@Test
public void givenPeakRateCounter_whenManipulate_thenPeakRateReturn() throws Exception {
Counter counter = new PeakRateCounter(MonitorConfig
.builder("test")
.build());
assertEquals("counter should start with 0", 0, counter
.getValue()
.intValue());
counter.increment();
SECONDS.sleep(1);
counter.increment();
counter.increment();
assertEquals("peak rate should have be 2", 2, counter
.getValue()
.intValue());
}
@Test
public void givenTimer_whenExecuteTask_thenTimerUpdated() throws Exception {
BasicTimer timer = new BasicTimer(MonitorConfig
.builder("test")
.build(), SECONDS);
Stopwatch stopwatch = timer.start();
SECONDS.sleep(1);
timer.record(2, SECONDS);
stopwatch.stop();
assertEquals("timer should count 1 second", 1, timer
.getValue()
.intValue());
assertEquals("timer should count 3 seconds in total", 3.0, timer.getTotalTime(), 0.01);
assertEquals("timer should record 2 updates", 2, timer
.getCount()
.intValue());
assertEquals("timer should have max 2", 2, timer.getMax(), 0.01);
}
@Test
public void givenBucketTimer_whenRecord_thenStatsCalculated() throws Exception {
BucketTimer timer = new BucketTimer(MonitorConfig
.builder("test")
.build(), new BucketConfig.Builder()
.withBuckets(new long[] { 2L, 5L })
.withTimeUnit(SECONDS)
.build(), SECONDS);
timer.record(3);
timer.record(6);
assertEquals("timer should count 9 seconds in total", 9, timer
.getTotalTime()
.intValue());
final Map<String, Long> metricMap = new HashMap<>(3);
timer
.getMonitors()
.stream()
.filter(monitor -> monitor
.getConfig()
.getTags()
.containsKey("servo.bucket"))
.forEach(monitor -> metricMap.put(getMonitorTagValue(monitor, "servo.bucket"), (Long) monitor.getValue()));
assertThat(metricMap, allOf(hasEntry("bucket=2s", 0L), hasEntry("bucket=5s", 1L), hasEntry("bucket=overflow", 1L)));
}
private static String getMonitorTagValue(Monitor monitor, String tagKey) {
return monitor
.getConfig()
.getTags()
.getTag(tagKey)
.getValue();
}
@Test
public void givenStatsTimer_whenExecuteTask_thenStatsCalculated() throws Exception {
System.setProperty("netflix.servo", "1000");
StatsTimer timer = new StatsTimer(MonitorConfig
.builder("test")
.build(), new StatsConfig.Builder()
.withComputeFrequencyMillis(2000)
.withPercentiles(new double[] { 99.0, 95.0, 90.0 })
.withPublishMax(true)
.withPublishMin(true)
.withPublishCount(true)
.withPublishMean(true)
.withPublishStdDev(true)
.withPublishVariance(true)
.build(), SECONDS);
Stopwatch stopwatch = timer.start();
SECONDS.sleep(1);
timer.record(3, SECONDS);
stopwatch.stop();
stopwatch = timer.start();
timer.record(6, SECONDS);
SECONDS.sleep(2);
stopwatch.stop();
assertEquals("timer should count 12 seconds in total", 12, timer.getTotalTime());
assertEquals("timer should count 12 seconds in total", 12, timer.getTotalMeasurement());
assertEquals("timer should record 4 updates", 4, timer.getCount());
assertEquals("stats timer value time-cost/update should be 2", 3, timer
.getValue()
.intValue());
final Map<String, Number> metricMap = new HashMap<>(10);
timer
.getMonitors()
.forEach(monitor -> metricMap.put(getMonitorTagValue(monitor, "statistic"), (Number) monitor.getValue()));
assertThat(metricMap.keySet(), containsInAnyOrder("count", "totalTime", "max", "min", "variance", "stdDev", "avg", "percentile_99", "percentile_95", "percentile_90"));
}
@Test
public void givenGauge_whenCall_thenValueReturned() {
Gauge<Double> gauge = new BasicGauge<>(MonitorConfig
.builder("test")
.build(), () -> 2.32);
assertEquals(2.32, gauge.getValue(), 0.01);
}
@Test
public void givenMaxGauge_whenUpdateMultipleTimes_thenMaxReturned() {
MaxGauge gauge = new MaxGauge(MonitorConfig
.builder("test")
.build());
assertEquals(0, gauge
.getValue()
.intValue());
gauge.update(4);
assertEquals(4, gauge.getCurrentValue(0));
gauge.update(1);
assertEquals(4, gauge.getCurrentValue(0));
}
@Test
public void givenInformationalMonitor_whenRecord_thenInformationCollected() throws Exception {
BasicInformational informational = new BasicInformational(MonitorConfig
.builder("test")
.build());
informational.setValue("information collected");
assertEquals("information collected", informational.getValue());
}
}