Skip to content

Commit 9a37fdc

Browse files
authored
Handle ArrayIndexOutOfBoundsException from DoubleHistogram in TimeWindowPercentileHistogram.accumulate() defensively (#6563)
Signed-off-by: Johnny Lim <[email protected]>
1 parent 16a662d commit 9a37fdc

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

micrometer-core/src/main/java/io/micrometer/core/instrument/distribution/TimeWindowPercentileHistogram.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package io.micrometer.core.instrument.distribution;
1717

18+
import io.micrometer.common.util.internal.logging.WarnThenDebugLogger;
1819
import io.micrometer.core.instrument.Clock;
1920
import org.HdrHistogram.DoubleHistogram;
2021
import org.HdrHistogram.DoubleRecorder;
@@ -36,6 +37,9 @@
3637
*/
3738
public class TimeWindowPercentileHistogram extends AbstractTimeWindowHistogram<DoubleRecorder, DoubleHistogram> {
3839

40+
private static final WarnThenDebugLogger WARN_THEN_DEBUG_LOGGER = new WarnThenDebugLogger(
41+
TimeWindowPercentileHistogram.class);
42+
3943
private final DoubleHistogram intervalHistogram;
4044

4145
private final double[] histogramBuckets;
@@ -102,7 +106,12 @@ DoubleHistogram newAccumulatedHistogram(DoubleRecorder[] ringBuffer) {
102106
@Override
103107
void accumulate() {
104108
currentHistogram().getIntervalHistogramInto(intervalHistogram);
105-
accumulatedHistogram().add(intervalHistogram);
109+
try {
110+
accumulatedHistogram().add(intervalHistogram);
111+
}
112+
catch (ArrayIndexOutOfBoundsException ex) {
113+
WARN_THEN_DEBUG_LOGGER.log("Failed to accumulate.", ex);
114+
}
106115
}
107116

108117
@Override

micrometer-core/src/test/java/io/micrometer/core/instrument/DistributionSummaryTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,14 @@
1919
import io.micrometer.core.instrument.simple.CountingMode;
2020
import io.micrometer.core.instrument.simple.SimpleConfig;
2121
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
22+
import io.micrometer.core.testsupport.system.CapturedOutput;
23+
import io.micrometer.core.testsupport.system.OutputCaptureExtension;
2224
import org.junit.jupiter.api.Test;
25+
import org.junit.jupiter.api.extension.ExtendWith;
2326

2427
import static org.assertj.core.api.Assertions.assertThat;
2528

29+
@ExtendWith(OutputCaptureExtension.class)
2630
class DistributionSummaryTest {
2731

2832
@Test
@@ -67,4 +71,18 @@ public CountingMode mode() {
6771
assertThat(summary.takeSnapshot().histogramCounts()).containsExactly(new CountAtBucket(1.0, 0));
6872
}
6973

74+
@Test
75+
void takeSnapshotShouldNotThrowExceptionEvenIfDoubleHistogramThrowsException(CapturedOutput output) {
76+
SimpleMeterRegistry registry = new SimpleMeterRegistry();
77+
DistributionSummary summary = DistributionSummary.builder("my.summary")
78+
.publishPercentiles(0.1, 0.25, 0.5, 0.75, 0.9, 0.95, 0.99)
79+
.register(registry);
80+
summary.record(1);
81+
summary.record(1E-10);
82+
summary.takeSnapshot();
83+
summary.record(1E-20);
84+
summary.takeSnapshot();
85+
assertThat(output).contains("Failed to accumulate.");
86+
}
87+
7088
}

0 commit comments

Comments
 (0)