BAEL-397: netflix servo intro (#2159)
This commit is contained in:
parent
c9111e635f
commit
52663a6bf5
|
@ -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>
|
||||
|
|
|
@ -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")))));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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))));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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"));
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue