From 08a63831731047b2a23f5a20e55187ecab2720e2 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 27 Dec 2023 17:28:17 +0100 Subject: [PATCH 1/2] For long task timers fixes the percentiles above interpolatable line without this change for the provided test one of the histogram buckets gets removed and an ArrayIndexOutOfBoundsException is thrown with this change the exception is not thrown anymore fixes gh-3877 --- .../internal/DefaultLongTaskTimer.java | 2 +- .../core/tck/DefaultLongTaskTimerTest.java | 42 +++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/internal/DefaultLongTaskTimer.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/internal/DefaultLongTaskTimer.java index ad8591d573..4f1ae810d6 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/internal/DefaultLongTaskTimer.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/internal/DefaultLongTaskTimer.java @@ -141,7 +141,7 @@ public HistogramSnapshot takeSnapshot() { CountAtBucket[] countAtBucketsArr = new CountAtBucket[0]; List percentilesAboveInterpolatableLine = percentilesRequested.stream() - .filter(p -> p * (activeTasks.size() + 1) > activeTasks.size()) + .filter(p -> p * (activeTasks.size() + 1) >= activeTasks.size()) .collect(Collectors.toList()); percentilesRequested.removeAll(percentilesAboveInterpolatableLine); diff --git a/micrometer-test/src/main/java/io/micrometer/core/tck/DefaultLongTaskTimerTest.java b/micrometer-test/src/main/java/io/micrometer/core/tck/DefaultLongTaskTimerTest.java index d92e6830ba..c53ce03e05 100644 --- a/micrometer-test/src/main/java/io/micrometer/core/tck/DefaultLongTaskTimerTest.java +++ b/micrometer-test/src/main/java/io/micrometer/core/tck/DefaultLongTaskTimerTest.java @@ -24,8 +24,12 @@ import io.micrometer.core.instrument.internal.DefaultLongTaskTimer; import io.micrometer.core.instrument.simple.SimpleConfig; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; + +import java.io.PrintStream; + +import org.junit.jupiter.api.*; import java.time.Duration; import java.util.Arrays; @@ -33,10 +37,22 @@ import java.util.concurrent.TimeUnit; import static io.micrometer.core.instrument.MockClock.clock; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.*; public class DefaultLongTaskTimerTest { + final ByteArrayOutputStream myErr = new ByteArrayOutputStream(); + + @BeforeEach + void setup() { + System.setErr(new PrintStream(myErr)); + } + + @AfterAll + static void cleanup() { + System.setErr(System.err); + } + @Test @DisplayName("supports sending histograms of active task duration") void histogram() { @@ -97,4 +113,24 @@ protected LongTaskTimer newLongTaskTimer(Meter.Id id, } } + @Test + void histogramToStringNotThrowingException() throws InterruptedException { + SimpleMeterRegistry simpleMeterRegistry = new SimpleMeterRegistry(); + + LongTaskTimer timer = LongTaskTimer.builder("jobrunr.jobs") + .publishPercentiles(0.25, 0.5, 0.75, 0.8, 0.9, 0.95) + .publishPercentileHistogram() + .register(simpleMeterRegistry); + LongTaskTimer.Sample start = timer.start(); + Thread.sleep(10); + + assertThatNoException().isThrownBy(() -> { + simpleMeterRegistry.getMetersAsString(); + start.stop(); + simpleMeterRegistry.getMetersAsString(); + String standardOutput = myErr.toString(); + assertThat(standardOutput).doesNotContain("ArrayIndexOutOfBoundsException"); + }); + } + } From 954916d9a5f54da9838ce5bc8c203fab05e9497c Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 17 Jan 2024 10:49:34 +0100 Subject: [PATCH 2/2] Polish --- .../core/instrument/distribution/HistogramGauges.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/distribution/HistogramGauges.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/distribution/HistogramGauges.java index 242661852b..0ab675d340 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/distribution/HistogramGauges.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/distribution/HistogramGauges.java @@ -116,7 +116,7 @@ private HistogramGauges(HistogramSupport meter, MeterRegistry registry, ToDoubleFunction percentileValueFunction = m -> { snapshotIfNecessary(); polledGaugesLatch.countDown(); - return percentileValue.apply(snapshot.percentileValues()[index]); + return percentileValue.apply(valueAtPercentiles[index]); }; Gauge.builder(percentileName.apply(valueAtPercentiles[i]), meter, percentileValueFunction)