Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

For long task timers fixes the percentiles above interpolatable line #4511

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ private HistogramGauges(HistogramSupport meter, MeterRegistry registry,
ToDoubleFunction<HistogramSupport> percentileValueFunction = m -> {
snapshotIfNecessary();
polledGaugesLatch.countDown();
return percentileValue.apply(snapshot.percentileValues()[index]);
return percentileValue.apply(valueAtPercentiles[index]);
};

Gauge.builder(percentileName.apply(valueAtPercentiles[i]), meter, percentileValueFunction)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public HistogramSnapshot takeSnapshot() {
CountAtBucket[] countAtBucketsArr = new CountAtBucket[0];

List<Double> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,35 @@
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;
import java.util.List;
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() {
Expand Down Expand Up @@ -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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test fails if this is changed to the other example given in the issue: 0.11, 0.22, 0.33, 0.44. I'm not sure why it makes a difference to be honest but the following change makes both cases pass without the change to DefaultLongTaskTimer.

Index: micrometer-core/src/main/java/io/micrometer/core/instrument/distribution/HistogramGauges.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
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
--- a/micrometer-core/src/main/java/io/micrometer/core/instrument/distribution/HistogramGauges.java	(revision e38f5e87dac6566e7909628afa7aa4f7fde6f170)
+++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/distribution/HistogramGauges.java	(date 1705478240207)
@@ -116,7 +116,7 @@
             ToDoubleFunction<HistogramSupport> percentileValueFunction = m -> {
                 snapshotIfNecessary();
                 polledGaugesLatch.countDown();
-                return percentileValue.apply(snapshot.percentileValues()[index]);
+                return percentileValue.apply(valueAtPercentiles[index]);
             };
 
             Gauge.builder(percentileName.apply(valueAtPercentiles[i]), meter, percentileValueFunction)

Copy link
Member

@shakuzen shakuzen Mar 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My suggested change is not correct. We definitely need more tests in this area of the code to be confident the behavior is correct. I'll take a closer look tomorrow soon.

.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");
});
}

}