Fix off-by-one error in funcHistogramQuantile / ensureMonotonic (#7393)

* Fix off-by-one error in funcHistogramQuantile / ensureMonotonic
* Additional coverage for nonmonotonic histogram buckets

Signed-off-by: Linas Medziunas <linas.medziunas@gmail.com>
This commit is contained in:
Linas Medžiūnas 2020-06-15 13:32:10 +03:00 committed by GitHub
parent abb4fba3c2
commit 7eaffa7180
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 10 deletions

View file

@ -168,7 +168,7 @@ func coalesceBuckets(buckets buckets) buckets {
func ensureMonotonic(buckets buckets) {
max := buckets[0].count
for i := range buckets[1:] {
for i := 1; i < len(buckets); i++ {
switch {
case buckets[i].count > max:
max = buckets[i].count

View file

@ -151,21 +151,25 @@ eval instant at 50m histogram_quantile(0.5, rate(request_duration_seconds_bucket
# A histogram with nonmonotonic bucket counts. This may happen when recording
# rule evaluation or federation races scrape ingestion, causing some buckets
# counts to be derived from fewer samples. The wrong answer we want to avoid
# is for histogram_quantile(0.99, nonmonotonic_bucket) to return ~1000 instead
# of 1.
# counts to be derived from fewer samples.
load 5m
nonmonotonic_bucket{le="0.1"} 0+1x10
nonmonotonic_bucket{le="1"} 0+9x10
nonmonotonic_bucket{le="10"} 0+8x10
nonmonotonic_bucket{le="100"} 0+8x10
nonmonotonic_bucket{le="0.1"} 0+2x10
nonmonotonic_bucket{le="1"} 0+1x10
nonmonotonic_bucket{le="10"} 0+5x10
nonmonotonic_bucket{le="100"} 0+4x10
nonmonotonic_bucket{le="1000"} 0+9x10
nonmonotonic_bucket{le="+Inf"} 0+9x10
nonmonotonic_bucket{le="+Inf"} 0+8x10
# Nonmonotonic buckets
eval instant at 50m histogram_quantile(0.01, nonmonotonic_bucket)
{} 0.0045
eval instant at 50m histogram_quantile(0.5, nonmonotonic_bucket)
{} 8.5
eval instant at 50m histogram_quantile(0.99, nonmonotonic_bucket)
{} 0.989875
{} 979.75
# Buckets with different representations of the same upper bound.
eval instant at 50m histogram_quantile(0.5, rate(mixed_bucket[5m]))