diff --git a/metrics/pom.xml b/metrics/pom.xml index 2020cd28cf..0ba590ceec 100644 --- a/metrics/pom.xml +++ b/metrics/pom.xml @@ -81,13 +81,18 @@ ${assertj-core.version} test + + com.netflix.spectator + spectator-api + 0.132.0 + 3.1.2 3.1.0 0.12.17 - 0.12.0.RELEASE + 1.7.1 2.0.7.RELEASE 3.11.1 diff --git a/metrics/src/main/java/com/baeldung/metrics/micrometer/MicrometerApp.java b/metrics/src/main/java/com/baeldung/metrics/micrometer/MicrometerApp.java index 1d738085ce..8fdb87cfe7 100644 --- a/metrics/src/main/java/com/baeldung/metrics/micrometer/MicrometerApp.java +++ b/metrics/src/main/java/com/baeldung/metrics/micrometer/MicrometerApp.java @@ -1,10 +1,10 @@ package com.baeldung.metrics.micrometer; +import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; -import io.micrometer.core.instrument.binder.JvmThreadMetrics; @SpringBootApplication public class MicrometerApp { @@ -14,7 +14,7 @@ public class MicrometerApp { return new JvmThreadMetrics(); } - public static void main(String[] args) throws Exception { + public static void main(String[] args) { SpringApplication.run(MicrometerApp.class, args); } diff --git a/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasIntegrationTest.java b/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasIntegrationTest.java index 689e23ad6d..02ef926794 100644 --- a/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasIntegrationTest.java +++ b/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasIntegrationTest.java @@ -1,11 +1,7 @@ package com.baeldung.metrics.micrometer; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.within; -import static org.assertj.core.api.Assertions.withinPercentage; -import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.collection.IsMapContaining.hasEntry; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -16,29 +12,25 @@ import io.micrometer.core.instrument.DistributionSummary; import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.LongTaskTimer; import io.micrometer.core.instrument.Measurement; -import io.micrometer.core.instrument.Meter.Type; -import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Metrics; -import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.Timer; import io.micrometer.core.instrument.composite.CompositeMeterRegistry; +import io.micrometer.core.instrument.distribution.HistogramSnapshot; +import io.micrometer.core.instrument.distribution.ValueAtPercentile; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import io.micrometer.core.instrument.stats.hist.Histogram; -import io.micrometer.core.instrument.stats.quantile.WindowSketchQuantiles; import java.time.Duration; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Arrays; import java.util.Map; +import java.util.TreeMap; import java.util.Optional; import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; -import org.assertj.core.data.Percentage; import org.junit.Before; import org.junit.Test; -import org.junit.jupiter.api.Assertions; import com.netflix.spectator.atlas.AtlasConfig; @@ -55,7 +47,7 @@ public class MicrometerAtlasIntegrationTest { @Override public Duration step() { - return Duration.ofSeconds(1); + return Duration.ofSeconds(10); } @Override @@ -77,9 +69,9 @@ public class MicrometerAtlasIntegrationTest { compositeRegistry.gauge("baeldung.heat", 90); - Optional oneGauge = oneSimpleMeter + Optional oneGauge = Optional.ofNullable(oneSimpleMeter .find("baeldung.heat") - .gauge(); + .gauge()); assertTrue(oneGauge.isPresent()); Iterator measurements = oneGauge .get() @@ -91,9 +83,9 @@ public class MicrometerAtlasIntegrationTest { .next() .getValue(), equalTo(90.00)); - Optional atlasGauge = atlasMeterRegistry + Optional atlasGauge = Optional.ofNullable(atlasMeterRegistry .find("baeldung.heat") - .gauge(); + .gauge()); assertTrue(atlasGauge.isPresent()); Iterator anotherMeasurements = atlasGauge .get() @@ -122,14 +114,14 @@ public class MicrometerAtlasIntegrationTest { .increment(); new CountedObject(); - Optional counterOptional = Metrics.globalRegistry + Optional counterOptional = Optional.ofNullable(Metrics.globalRegistry .find("objects.instance") - .counter(); + .counter()); assertTrue(counterOptional.isPresent()); - assertTrue(counterOptional + assertEquals(counterOptional .get() - .count() == 2.0); + .count() , 2.0, 0.0); } @Test @@ -142,10 +134,10 @@ public class MicrometerAtlasIntegrationTest { .register(registry); counter.increment(2.0); - assertTrue(counter.count() == 2); + assertEquals(counter.count(), 2, 0); counter.increment(-1); - assertTrue(counter.count() == 2); + assertEquals(counter.count(), 1, 0); } @Test @@ -161,8 +153,8 @@ public class MicrometerAtlasIntegrationTest { timer.record(30, TimeUnit.MILLISECONDS); - assertTrue(2 == timer.count()); - + assertEquals(2, timer.count(), 0); + assertThat(timer.totalTime(TimeUnit.MILLISECONDS)).isBetween(40.0, 55.0); } @@ -173,12 +165,12 @@ public class MicrometerAtlasIntegrationTest { .builder("3rdPartyService") .register(registry); - long currentTaskId = longTaskTimer.start(); + LongTaskTimer.Sample currentTaskId = longTaskTimer.start(); try { TimeUnit.MILLISECONDS.sleep(2); } catch (InterruptedException ignored) { } - long timeElapsed = longTaskTimer.stop(currentTaskId); + long timeElapsed = currentTaskId.stop(); assertEquals(2L, timeElapsed/((int) 1e6),1L); } @@ -191,10 +183,10 @@ public class MicrometerAtlasIntegrationTest { .builder("cache.size", list, List::size) .register(registry); - assertTrue(gauge.value() == 0.0); + assertEquals(gauge.value(), 0.0, 0.0); list.add("1"); - assertTrue(gauge.value() == 1.0); + assertEquals(gauge.value(), 1.0, 0.0); } @Test @@ -208,18 +200,17 @@ public class MicrometerAtlasIntegrationTest { distributionSummary.record(4); distributionSummary.record(5); - assertTrue(3 == distributionSummary.count()); - assertTrue(12 == distributionSummary.totalAmount()); + assertEquals(3, distributionSummary.count(), 0); + assertEquals(12, distributionSummary.totalAmount(), 0); } @Test - public void givenTimer_whenEnrichWithQuantile_thenQuantilesComputed() { + public void givenTimer_whenEnrichWithPercentile_thenPercentilesComputed() { SimpleMeterRegistry registry = new SimpleMeterRegistry(); Timer timer = Timer .builder("test.timer") - .quantiles(WindowSketchQuantiles - .quantiles(0.3, 0.5, 0.95) - .create()) + .publishPercentiles(0.3, 0.5, 0.95) + .publishPercentileHistogram() .register(registry); timer.record(2, TimeUnit.SECONDS); @@ -229,27 +220,18 @@ public class MicrometerAtlasIntegrationTest { timer.record(8, TimeUnit.SECONDS); timer.record(13, TimeUnit.SECONDS); - Map quantileMap = extractTagValueMap(registry, Type.Gauge, 1e9); - assertThat(quantileMap, allOf(hasEntry("quantile=0.3", 2), hasEntry("quantile=0.5", 3), hasEntry("quantile=0.95", 8))); - } + Map expectedMicrometer = new TreeMap<>(); + expectedMicrometer.put(0.3, 1946.157056); + expectedMicrometer.put(0.5, 3019.89888); + expectedMicrometer.put(0.95, 13354.663936); - private Map extractTagValueMap(MeterRegistry registry, Type meterType, double valueDivisor) { - return registry - .getMeters() - .stream() - .filter(meter -> meter.getType() == meterType) - .collect(Collectors.toMap(meter -> { - Tag tag = meter - .getId() - .getTags() - .iterator() - .next(); - return tag.getKey() + "=" + tag.getValue(); - }, meter -> (int) (meter - .measure() - .iterator() - .next() - .getValue() / valueDivisor))); + Map actualMicrometer = new TreeMap<>(); + ValueAtPercentile[] percentiles = timer.takeSnapshot().percentileValues(); + for (ValueAtPercentile percentile : percentiles) { + actualMicrometer.put(percentile.percentile(), percentile.value(TimeUnit.MILLISECONDS)); + } + + assertEquals(expectedMicrometer, actualMicrometer); } @Test @@ -257,7 +239,7 @@ public class MicrometerAtlasIntegrationTest { SimpleMeterRegistry registry = new SimpleMeterRegistry(); DistributionSummary hist = DistributionSummary .builder("summary") - .histogram(Histogram.linear(0, 10, 5)) + .serviceLevelObjectives(1, 10, 5) .register(registry); hist.record(3); @@ -267,17 +249,28 @@ public class MicrometerAtlasIntegrationTest { hist.record(13); hist.record(26); - Map histograms = extractTagValueMap(registry, Type.Counter, 1.0); + Map expectedMicrometer = new TreeMap<>(); + expectedMicrometer.put(1,0D); + expectedMicrometer.put(10,2D); + expectedMicrometer.put(5,1D); - assertThat(histograms, allOf(hasEntry("bucket=0.0", 0), hasEntry("bucket=10.0", 2), hasEntry("bucket=20.0", 2), hasEntry("bucket=30.0", 1), hasEntry("bucket=40.0", 1), hasEntry("bucket=Infinity", 0))); + Map actualMicrometer = new TreeMap<>(); + HistogramSnapshot snapshot = hist.takeSnapshot(); + Arrays.stream(snapshot.histogramCounts()).forEach(p -> { + actualMicrometer.put((Integer.valueOf((int) p.bucket())), p.count()); + }); + + assertEquals(expectedMicrometer, actualMicrometer); } @Test public void givenTimer_whenEnrichWithTimescaleHistogram_thenTimeScaleDataCollected() { SimpleMeterRegistry registry = new SimpleMeterRegistry(); + Duration[] durations = {Duration.ofMillis(25), Duration.ofMillis(300), Duration.ofMillis(600)}; Timer timer = Timer .builder("timer") - .histogram(Histogram.linearTime(TimeUnit.MILLISECONDS, 0, 200, 3)) + .sla(durations) + .publishPercentileHistogram() .register(registry); timer.record(1000, TimeUnit.MILLISECONDS); @@ -286,10 +279,18 @@ public class MicrometerAtlasIntegrationTest { timer.record(341, TimeUnit.MILLISECONDS); timer.record(500, TimeUnit.MILLISECONDS); - Map histograms = extractTagValueMap(registry, Type.Counter, 1.0); + Map expectedMicrometer = new TreeMap<>(); + expectedMicrometer.put(2.5E7,1D); + expectedMicrometer.put(3.0E8,1D); + expectedMicrometer.put(6.0E8,4D); - assertThat(histograms, allOf(hasEntry("bucket=0.0", 0), hasEntry("bucket=2.0E8", 1), hasEntry("bucket=4.0E8", 1), hasEntry("bucket=Infinity", 3))); + Map actualMicrometer = new TreeMap<>(); + HistogramSnapshot snapshot = timer.takeSnapshot(); + Arrays.stream(snapshot.histogramCounts()).forEach(p -> { + actualMicrometer.put((Double.valueOf((int) p.bucket())), p.count()); + }); + assertEquals(expectedMicrometer, actualMicrometer); } }