address code review comments

Signed-off-by: Kapil Lamba <kapillamba4@gmail.com>
This commit is contained in:
Kapil Lamba 2025-07-09 07:25:31 +05:30
parent 030835560b
commit df0e034314
5 changed files with 257 additions and 16 deletions

View File

@ -232,6 +232,7 @@ load 5m
http_requests_histogram{job="api-server", instance="3", group="canary"} {{schema:2 count:4 sum:10 buckets:[1 0 0 0 1 0 0 1 1]}}
eval instant at 0m max(http_requests)
expect no_info
{} 4
# The histogram is ignored here so the result doesn't change but it has an info annotation now.
@ -244,6 +245,7 @@ eval instant at 0m max(http_requests_histogram)
expect info
eval instant at 0m min(http_requests)
expect no_info
{} 1
# The histogram is ignored here so the result doesn't change but it has an info annotation now.
@ -256,10 +258,12 @@ eval instant at 0m min(http_requests_histogram)
expect info
eval instant at 0m max by (group) (http_requests)
expect no_info
{group="production"} 2
{group="canary"} 4
eval instant at 0m min by (group) (http_requests)
expect no_info
{group="production"} 1
{group="canary"} 3
@ -484,6 +488,7 @@ load 10s
foo 0 1 0 1 0 1 0.8
eval instant at 1m quantile without(point)(0.8, data)
expect no_info
{test="two samples"} 0.8
{test="three samples"} 1.6
{test="uneven samples"} 2.8

View File

@ -228,24 +228,30 @@ load 5m
http_requests_histogram{path="/g"} 0 0 {{schema:-53 sum:3 count:3 custom_values:[1] buckets:[3]}} {{schema:-53 sum:3 count:3 custom_values:[5 10] buckets:[3]}}
eval instant at 50m irate(http_requests_total[50m])
expect no_warn
{path="/foo"} .03333333333333333333
{path="/bar"} .03333333333333333333
# Counter reset.
eval instant at 30m irate(http_requests_total[50m])
expect no_warn
{path="/foo"} .03333333333333333333
{path="/bar"} 0
eval range from 0 to 20m step 5m irate(http_requests_nan[15m1s])
expect no_warn
{} _ NaN NaN NaN 0.02
eval instant at 20m irate(http_requests_histogram{path="/a"}[20m])
expect no_warn
{path="/a"} {{sum:0.01 count:0.01 counter_reset_hint:gauge}}
eval instant at 20m irate(http_requests_histogram{path="/b"}[20m])
expect no_warn
{path="/b"} {{sum:0.01 count:0.01 counter_reset_hint:gauge}}
eval instant at 20m irate(http_requests_histogram{path="/b"}[6m])
expect no_warn
eval instant at 20m irate(http_requests_histogram{path="/c"}[20m])
expect warn
@ -259,9 +265,11 @@ eval instant at 20m irate(http_requests_histogram{path="/e"}[20m])
expect warn
eval instant at 20m irate(http_requests_histogram{path="/f"}[20m])
expect no_warn
{path="/f"} {{schema:-53 sum:0.01 count:0.01 custom_values:[5 10] buckets:[0.01]}}
eval instant at 20m irate(http_requests_histogram{path="/g"}[20m])
expect no_warn
{path="/g"} {{schema:-53 sum:0.01 count:0.01 custom_values:[5 10] buckets:[0.01]}}
clear
@ -275,10 +283,12 @@ load 5m
http_requests_mix{path="/foo"} 0 50 100 {{schema:0 sum:0 count:0 buckets:[0 0 0] counter_reset_hint:gauge}} {{schema:0 sum:1 count:2 buckets:[1 1 1] counter_reset_hint:gauge}}
eval instant at 20m delta(http_requests[20m])
expect no_warn
{path="/foo"} 200
{path="/bar"} -200
eval instant at 20m delta(http_requests_gauge[20m])
expect no_warn
{path="/foo"} {{schema:0 sum:4 count:8 buckets:[4 4 4]}}
# delta emits warn annotation for non-gauge histogram types.
@ -307,19 +317,24 @@ load 5m
http_requests_histogram{path="/g"} 0 0 {{schema:-53 sum:1 count:1 custom_values:[1] buckets:[2] counter_reset_hint:gauge}} {{schema:-53 sum:1 count:1 custom_values:[5 10] buckets:[1] counter_reset_hint:gauge}}
eval instant at 20m idelta(http_requests[20m])
expect no_warn
{path="/foo"} 50
{path="/bar"} -50
eval range from 0 to 20m step 5m idelta(http_requests_nan[15m1s])
expect no_warn
{} _ NaN NaN NaN 6
eval instant at 20m idelta(http_requests_histogram{path="/a"}[20m])
expect no_warn
{path="/a"} {{sum:1 count:3 counter_reset_hint:gauge}}
eval instant at 20m idelta(http_requests_histogram{path="/b"}[20m])
expect no_warn
{path="/b"} {{sum:1 count:1 counter_reset_hint:gauge}}
eval instant at 20m idelta(http_requests_histogram{path="/b"}[6m])
expect no_warn
eval instant at 20m idelta(http_requests_histogram{path="/c"}[20m])
expect warn
@ -351,13 +366,16 @@ load 5m
# deriv should return the same as rate in simple cases.
eval instant at 50m rate(http_requests_total{group="canary", instance="1", job="app-server"}[50m])
expect no_info
{group="canary", instance="1", job="app-server"} 0.26666666666666666
eval instant at 50m deriv(http_requests_total{group="canary", instance="1", job="app-server"}[50m])
expect no_info
{group="canary", instance="1", job="app-server"} 0.26666666666666666
# deriv should return correct result.
eval instant at 50m deriv(testcounter_reset_middle_total[100m])
expect no_info
{} 0.010606060606060607
# deriv should ignore histograms in a mixed range of floats and histograms, flagged by an info annotation.
@ -370,7 +388,6 @@ eval instant at 100m deriv(testcounter_reset_middle_mix[110m])
{} 0.010606060606060607
# deriv should silently ignore ranges consisting only of histograms.
# expects both an empty result and no info/warn annotations.
eval instant at 50m deriv(http_requests_histogram[60m])
expect no_info
expect no_warn
@ -378,6 +395,7 @@ eval instant at 50m deriv(http_requests_histogram[60m])
# deriv should return NaN in case of +Inf or -Inf found.
eval instant at 100m deriv(http_requests_inf[100m])
expect no_info
{job="app-server", instance="1", group="canary"} NaN
# predict_linear should return correct result.
@ -395,24 +413,30 @@ eval instant at 100m deriv(http_requests_inf[100m])
# intercept at t=3000: 38.63636363636364
# intercept at t=3000+3600: 76.81818181818181
eval instant at 50m predict_linear(testcounter_reset_middle_total[50m], 3600)
expect no_info
{} 70
eval instant at 50m predict_linear(testcounter_reset_middle_total[50m], 1h)
expect no_info
{} 70
# intercept at t = 3000+3600 = 6600
eval instant at 50m predict_linear(testcounter_reset_middle_total[55m] @ 3000, 3600)
expect no_info
{} 76.81818181818181
eval instant at 50m predict_linear(testcounter_reset_middle_total[55m] @ 3000, 1h)
expect no_info
{} 76.81818181818181
# intercept at t = 600+3600 = 4200
eval instant at 10m predict_linear(testcounter_reset_middle_total[55m] @ 3000, 3600)
expect no_info
{} 51.36363636363637
# intercept at t = 4200+3600 = 7800
eval instant at 70m predict_linear(testcounter_reset_middle_total[55m] @ 3000, 3600)
expect no_info
{} 89.54545454545455
# predict_linear should ignore histograms in a mixed range of floats and histograms, flagged by an info annotation.
@ -870,6 +894,7 @@ load 10s
http_requests_histogram{job="api-server", instance="1", group="canary"} {{schema:0 count:1 sum:2}}x1000
eval instant at 8000s double_exponential_smoothing(http_requests[1m], 0.01, 0.1)
expect no_info
{job="api-server", instance="0", group="production"} 8000
{job="api-server", instance="1", group="production"} 16000
{job="api-server", instance="0", group="canary"} 24000
@ -885,6 +910,7 @@ eval instant at 20010s double_exponential_smoothing(http_requests_mix[1m], 0.01,
# double_exponential_smoothing should silently ignore ranges consisting only of histograms.
eval instant at 10000s double_exponential_smoothing(http_requests_histogram[1m], 0.01, 0.1)
expect no_info
#empty
# negative trends
@ -1193,6 +1219,7 @@ eval instant at 1m stddev_over_time(metric_histogram{type="mix"}[2m])
{type="mix"} 0
eval instant at 1m stdvar_over_time(metric_histogram{type="only_histogram"}[2m])
expect no_info
#empty
eval instant at 1m stdvar_over_time(metric_histogram{type="mix"}[2m])
@ -1218,9 +1245,11 @@ load 10s
metric_histogram{type="mix"} 1 1 1 {{schema:1 sum:2 count:3}} {{schema:1 sum:2 count:3}}
eval instant at 70s mad_over_time(metric[70s])
expect no_info
{} 1
eval instant at 70s mad_over_time(metric_histogram{type="only_histogram"}[70s])
expect no_info
#empty
eval instant at 70s mad_over_time(metric_histogram{type="mix"}[70s])
@ -1268,53 +1297,69 @@ load 10s
data_histogram{test="mix samples"} 0 1 2 {{schema:0 sum:1 count:2}}x2
eval instant at 1m quantile_over_time(0, data[2m])
expect no_info
expect no_warn
{test="two samples"} 0
{test="three samples"} 0
{test="uneven samples"} 0
eval instant at 1m quantile_over_time(0.5, data[2m])
expect no_info
expect no_warn
{test="two samples"} 0.5
{test="three samples"} 1
{test="uneven samples"} 1
eval instant at 1m quantile_over_time(0.75, data[2m])
expect no_info
expect no_warn
{test="two samples"} 0.75
{test="three samples"} 1.5
{test="uneven samples"} 2.5
eval instant at 1m quantile_over_time(0.8, data[2m])
expect no_info
expect no_warn
{test="two samples"} 0.8
{test="three samples"} 1.6
{test="uneven samples"} 2.8
eval instant at 1m quantile_over_time(1, data[2m])
expect no_info
expect no_warn
{test="two samples"} 1
{test="three samples"} 2
{test="uneven samples"} 4
eval instant at 1m quantile_over_time(-1, data[2m])
expect no_info
expect warn
{test="two samples"} -Inf
{test="three samples"} -Inf
{test="uneven samples"} -Inf
eval instant at 1m quantile_over_time(2, data[2m])
expect no_info
expect warn
{test="two samples"} +Inf
{test="three samples"} +Inf
{test="uneven samples"} +Inf
eval instant at 1m (quantile_over_time(2, (data[2m])))
expect no_info
expect warn
{test="two samples"} +Inf
{test="three samples"} +Inf
{test="uneven samples"} +Inf
eval instant at 1m quantile_over_time(0.5, data_histogram{test="only histogram samples"}[2m])
expect no_info
expect no_warn
#empty
eval instant at 1m quantile_over_time(0.5, data_histogram{test="mix samples"}[2m])
expect info
expect no_warn
{test="mix samples"} 1
clear
@ -1444,6 +1489,7 @@ load 10s
data_histogram{type="mix_samples"} 0 1 {{schema:0 sum:1 count:2}} {{schema:0 sum:2 count:3}}
eval instant at 1m min_over_time(data[2m])
expect no_info
{type="numbers"} 0
{type="some_nan"} 0
{type="some_nan2"} 1
@ -1451,6 +1497,7 @@ eval instant at 1m min_over_time(data[2m])
{type="only_nan"} NaN
eval instant at 1m min_over_time(data_histogram{type="only_histogram"}[2m])
expect no_info
#empty
eval instant at 1m min_over_time(data_histogram{type="mix_samples"}[2m])
@ -1458,6 +1505,7 @@ eval instant at 1m min_over_time(data_histogram{type="mix_samples"}[2m])
{type="mix_samples"} 0
eval instant at 1m max_over_time(data[2m])
expect no_info
{type="numbers"} 3
{type="some_nan"} 2
{type="some_nan2"} 2
@ -1465,6 +1513,7 @@ eval instant at 1m max_over_time(data[2m])
{type="only_nan"} NaN
eval instant at 1m max_over_time(data_histogram{type="only_histogram"}[2m])
expect no_info
#empty
eval instant at 1m max_over_time(data_histogram{type="mix_samples"}[2m])
@ -1472,6 +1521,7 @@ eval instant at 1m max_over_time(data_histogram{type="mix_samples"}[2m])
{type="mix_samples"} 1
eval instant at 1m last_over_time({__name__=~"data(_histogram)?"}[2m])
expect no_info
data{type="numbers"} 3
data{type="some_nan"} NaN
data{type="some_nan2"} 1
@ -1481,6 +1531,7 @@ eval instant at 1m last_over_time({__name__=~"data(_histogram)?"}[2m])
data_histogram{type="mix_samples"} {{schema:0 sum:2 count:3}}
eval instant at 1m count_over_time({__name__=~"data(_histogram)?"}[2m])
expect no_info
{type="numbers"} 3
{type="some_nan"} 3
{type="some_nan2"} 3

View File

@ -70,74 +70,91 @@ load_with_nhcb 5m
# Test histogram_count.
eval instant at 50m histogram_count(testhistogram3)
expect no_warn
{start="positive"} 110
{start="negative"} 20
# Classic way of accessing the count still works.
eval instant at 50m testhistogram3_count
expect no_warn
testhistogram3_count{start="positive"} 110
testhistogram3_count{start="negative"} 20
# Test histogram_sum.
eval instant at 50m histogram_sum(testhistogram3)
expect no_warn
{start="positive"} 330
{start="negative"} 80
# Classic way of accessing the sum still works.
eval instant at 50m testhistogram3_sum
expect no_warn
testhistogram3_sum{start="positive"} 330
testhistogram3_sum{start="negative"} 80
# Test histogram_avg. This has no classic equivalent.
eval instant at 50m histogram_avg(testhistogram3)
expect no_warn
{start="positive"} 3
{start="negative"} 4
# Test histogram_stddev. This has no classic equivalent.
eval instant at 50m histogram_stddev(testhistogram3)
expect no_warn
{start="positive"} 2.7435461458749795
{start="negative"} 4.187667907081458
# Test histogram_stdvar. This has no classic equivalent.
eval instant at 50m histogram_stdvar(testhistogram3)
expect no_warn
{start="positive"} 7.527045454545455
{start="negative"} 17.5365625
# Test histogram_fraction.
#
eval instant at 50m histogram_fraction(0, 4, testhistogram2)
expect no_warn
{} 0.6666666666666666
eval instant at 50m histogram_fraction(0, 4, testhistogram2_bucket)
expect no_warn
{} 0.6666666666666666
eval instant at 50m histogram_fraction(0, 6, testhistogram2)
expect no_warn
{} 1
eval instant at 50m histogram_fraction(0, 6, testhistogram2_bucket)
expect no_warn
{} 1
eval instant at 50m histogram_fraction(0, 3.5, testhistogram2)
expect no_warn
{} 0.5833333333333334
eval instant at 50m histogram_fraction(0, 3.5, testhistogram2_bucket)
expect no_warn
{} 0.5833333333333334
eval instant at 50m histogram_fraction(0, 0.2, testhistogram3)
expect no_warn
{start="positive"} 0.6363636363636364
{start="negative"} 0
eval instant at 50m histogram_fraction(0, 0.2, testhistogram3_bucket)
expect no_warn
{start="positive"} 0.6363636363636364
{start="negative"} 0
eval instant at 50m histogram_fraction(0, 0.2, rate(testhistogram3[10m]))
expect no_warn
{start="positive"} 0.6363636363636364
{start="negative"} 0
eval instant at 50m histogram_fraction(0, 0.2, rate(testhistogram3_bucket[10m]))
expect no_warn
{start="positive"} 0.6363636363636364
{start="negative"} 0
@ -145,50 +162,62 @@ eval instant at 50m histogram_fraction(0, 0.2, rate(testhistogram3_bucket[10m]))
# it exists) and divide by the count to get the same result.
eval instant at 50m testhistogram3_bucket{le=".2"} / ignoring(le) testhistogram3_count
expect no_warn
{start="positive"} 0.6363636363636364
eval instant at 50m rate(testhistogram3_bucket{le=".2"}[10m]) / ignoring(le) rate(testhistogram3_count[10m])
expect no_warn
{start="positive"} 0.6363636363636364
# Test histogram_quantile, native and classic.
eval instant at 50m histogram_quantile(0, testhistogram3)
expect no_warn
{start="positive"} 0
{start="negative"} -0.25
eval instant at 50m histogram_quantile(0, testhistogram3_bucket)
expect no_warn
{start="positive"} 0
{start="negative"} -0.25
eval instant at 50m histogram_quantile(0.25, testhistogram3)
expect no_warn
{start="positive"} 0.055
{start="negative"} -0.225
eval instant at 50m histogram_quantile(0.25, testhistogram3_bucket)
expect no_warn
{start="positive"} 0.055
{start="negative"} -0.225
eval instant at 50m histogram_quantile(0.5, testhistogram3)
expect no_warn
{start="positive"} 0.125
{start="negative"} -0.2
eval instant at 50m histogram_quantile(0.5, testhistogram3_bucket)
expect no_warn
{start="positive"} 0.125
{start="negative"} -0.2
eval instant at 50m histogram_quantile(0.75, testhistogram3)
expect no_warn
{start="positive"} 0.45
{start="negative"} -0.15
eval instant at 50m histogram_quantile(0.75, testhistogram3_bucket)
expect no_warn
{start="positive"} 0.45
{start="negative"} -0.15
eval instant at 50m histogram_quantile(1, testhistogram3)
expect no_warn
{start="positive"} 1
{start="negative"} -0.1
eval instant at 50m histogram_quantile(1, testhistogram3_bucket)
expect no_warn
{start="positive"} 1
{start="negative"} -0.1
@ -231,196 +260,244 @@ eval instant at 50m histogram_quantile(NaN, testhistogram_bucket)
# Quantile value in lowest bucket.
eval instant at 50m histogram_quantile(0, testhistogram)
expect no_warn
{start="positive"} 0
{start="negative"} -0.2
eval instant at 50m histogram_quantile(0, testhistogram_bucket)
expect no_warn
{start="positive"} 0
{start="negative"} -0.2
# Quantile value in highest bucket.
eval instant at 50m histogram_quantile(1, testhistogram)
expect no_warn
{start="positive"} 1
{start="negative"} 0.3
eval instant at 50m histogram_quantile(1, testhistogram_bucket)
expect no_warn
{start="positive"} 1
{start="negative"} 0.3
# Finally some useful quantiles.
eval instant at 50m histogram_quantile(0.2, testhistogram)
expect no_warn
{start="positive"} 0.048
{start="negative"} -0.2
eval instant at 50m histogram_quantile(0.2, testhistogram_bucket)
expect no_warn
{start="positive"} 0.048
{start="negative"} -0.2
eval instant at 50m histogram_quantile(0.5, testhistogram)
expect no_warn
{start="positive"} 0.15
{start="negative"} -0.15
eval instant at 50m histogram_quantile(0.5, testhistogram_bucket)
expect no_warn
{start="positive"} 0.15
{start="negative"} -0.15
eval instant at 50m histogram_quantile(0.8, testhistogram)
expect no_warn
{start="positive"} 0.72
{start="negative"} 0.3
eval instant at 50m histogram_quantile(0.8, testhistogram_bucket)
expect no_warn
{start="positive"} 0.72
{start="negative"} 0.3
# More realistic with rates.
eval instant at 50m histogram_quantile(0.2, rate(testhistogram[10m]))
expect no_warn
{start="positive"} 0.048
{start="negative"} -0.2
eval instant at 50m histogram_quantile(0.2, rate(testhistogram_bucket[10m]))
expect no_warn
{start="positive"} 0.048
{start="negative"} -0.2
eval instant at 50m histogram_quantile(0.5, rate(testhistogram[10m]))
expect no_warn
{start="positive"} 0.15
{start="negative"} -0.15
eval instant at 50m histogram_quantile(0.5, rate(testhistogram_bucket[10m]))
expect no_warn
{start="positive"} 0.15
{start="negative"} -0.15
eval instant at 50m histogram_quantile(0.8, rate(testhistogram[10m]))
expect no_warn
{start="positive"} 0.72
{start="negative"} 0.3
eval instant at 50m histogram_quantile(0.8, rate(testhistogram_bucket[10m]))
expect no_warn
{start="positive"} 0.72
{start="negative"} 0.3
# Want results exactly in the middle of the bucket.
eval instant at 7m histogram_quantile(1./6., testhistogram2)
expect no_warn
{} 1
eval instant at 7m histogram_quantile(1./6., testhistogram2_bucket)
expect no_warn
{} 1
eval instant at 7m histogram_quantile(0.5, testhistogram2)
expect no_warn
{} 3
eval instant at 7m histogram_quantile(0.5, testhistogram2_bucket)
expect no_warn
{} 3
eval instant at 7m histogram_quantile(5./6., testhistogram2)
expect no_warn
{} 5
eval instant at 7m histogram_quantile(5./6., testhistogram2_bucket)
expect no_warn
{} 5
eval instant at 47m histogram_quantile(1./6., rate(testhistogram2[15m]))
expect no_warn
{} 1
eval instant at 47m histogram_quantile(1./6., rate(testhistogram2_bucket[15m]))
expect no_warn
{} 1
eval instant at 47m histogram_quantile(0.5, rate(testhistogram2[15m]))
expect no_warn
{} 3
eval instant at 47m histogram_quantile(0.5, rate(testhistogram2_bucket[15m]))
expect no_warn
{} 3
eval instant at 47m histogram_quantile(5./6., rate(testhistogram2[15m]))
expect no_warn
{} 5
eval instant at 47m histogram_quantile(5./6., rate(testhistogram2_bucket[15m]))
expect no_warn
{} 5
# Aggregated histogram: Everything in one. Note how native histograms
# don't require aggregation by le.
eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds[10m])))
expect no_warn
{} 0.075
eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[10m])) by (le))
expect no_warn
{} 0.075
eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds[10m])))
expect no_warn
{} 0.1277777777777778
eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[10m])) by (le))
expect no_warn
{} 0.1277777777777778
# Aggregated histogram: Everything in one. Now with avg, which does not change anything.
eval instant at 50m histogram_quantile(0.3, avg(rate(request_duration_seconds[10m])))
expect no_warn
{} 0.075
eval instant at 50m histogram_quantile(0.3, avg(rate(request_duration_seconds_bucket[10m])) by (le))
expect no_warn
{} 0.075
eval instant at 50m histogram_quantile(0.5, avg(rate(request_duration_seconds[10m])))
expect no_warn
{} 0.12777777777777778
eval instant at 50m histogram_quantile(0.5, avg(rate(request_duration_seconds_bucket[10m])) by (le))
expect no_warn
{} 0.12777777777777778
# Aggregated histogram: By instance.
eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds[10m])) by (instance))
expect no_warn
{instance="ins1"} 0.075
{instance="ins2"} 0.075
eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[10m])) by (le, instance))
expect no_warn
{instance="ins1"} 0.075
{instance="ins2"} 0.075
eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds[10m])) by (instance))
expect no_warn
{instance="ins1"} 0.1333333333
{instance="ins2"} 0.125
eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[10m])) by (le, instance))
expect no_warn
{instance="ins1"} 0.1333333333
{instance="ins2"} 0.125
# Aggregated histogram: By job.
eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds[10m])) by (job))
expect no_warn
{job="job1"} 0.1
{job="job2"} 0.0642857142857143
eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[10m])) by (le, job))
expect no_warn
{job="job1"} 0.1
{job="job2"} 0.0642857142857143
eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds[10m])) by (job))
expect no_warn
{job="job1"} 0.14
{job="job2"} 0.1125
eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[10m])) by (le, job))
expect no_warn
{job="job1"} 0.14
{job="job2"} 0.1125
# Aggregated histogram: By job and instance.
eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds[10m])) by (job, instance))
expect no_warn
{instance="ins1", job="job1"} 0.11
{instance="ins2", job="job1"} 0.09
{instance="ins1", job="job2"} 0.06
{instance="ins2", job="job2"} 0.0675
eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[10m])) by (le, job, instance))
expect no_warn
{instance="ins1", job="job1"} 0.11
{instance="ins2", job="job1"} 0.09
{instance="ins1", job="job2"} 0.06
{instance="ins2", job="job2"} 0.0675
eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds[10m])) by (job, instance))
expect no_warn
{instance="ins1", job="job1"} 0.15
{instance="ins2", job="job1"} 0.1333333333333333
{instance="ins1", job="job2"} 0.1
{instance="ins2", job="job2"} 0.1166666666666667
eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[10m])) by (le, job, instance))
expect no_warn
{instance="ins1", job="job1"} 0.15
{instance="ins2", job="job1"} 0.1333333333333333
{instance="ins1", job="job2"} 0.1
@ -428,24 +505,28 @@ eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bu
# The unaggregated histogram for comparison. Same result as the previous one.
eval instant at 50m histogram_quantile(0.3, rate(request_duration_seconds[10m]))
expect no_warn
{instance="ins1", job="job1"} 0.11
{instance="ins2", job="job1"} 0.09
{instance="ins1", job="job2"} 0.06
{instance="ins2", job="job2"} 0.0675
eval instant at 50m histogram_quantile(0.3, rate(request_duration_seconds_bucket[10m]))
expect no_warn
{instance="ins1", job="job1"} 0.11
{instance="ins2", job="job1"} 0.09
{instance="ins1", job="job2"} 0.06
{instance="ins2", job="job2"} 0.0675
eval instant at 50m histogram_quantile(0.5, rate(request_duration_seconds[10m]))
expect no_warn
{instance="ins1", job="job1"} 0.15
{instance="ins2", job="job1"} 0.13333333333333333
{instance="ins1", job="job2"} 0.1
{instance="ins2", job="job2"} 0.11666666666666667
eval instant at 50m histogram_quantile(0.5, rate(request_duration_seconds_bucket[10m]))
expect no_warn
{instance="ins1", job="job1"} 0.15
{instance="ins2", job="job1"} 0.13333333333333333
{instance="ins1", job="job2"} 0.1
@ -453,25 +534,32 @@ eval instant at 50m histogram_quantile(0.5, rate(request_duration_seconds_bucket
# All NHCBs summed into one.
eval instant at 50m sum(request_duration_seconds)
expect no_warn
{} {{schema:-53 count:250 custom_values:[0.1 0.2] buckets:[100 90 60]}}
eval instant at 50m sum(request_duration_seconds{job="job1",instance="ins1"} + ignoring(job,instance) request_duration_seconds{job="job1",instance="ins2"} + ignoring(job,instance) request_duration_seconds{job="job2",instance="ins1"} + ignoring(job,instance) request_duration_seconds{job="job2",instance="ins2"})
expect no_warn
{} {{schema:-53 count:250 custom_values:[0.1 0.2] buckets:[100 90 60]}}
eval instant at 50m avg(request_duration_seconds)
expect no_warn
{} {{schema:-53 count:62.5 custom_values:[0.1 0.2] buckets:[25 22.5 15]}}
# To verify the result above, calculate from classic histogram as well.
eval instant at 50m avg (request_duration_seconds_bucket{le="0.1"})
expect no_warn
{} 25
eval instant at 50m avg (request_duration_seconds_bucket{le="0.2"}) - avg (request_duration_seconds_bucket{le="0.1"})
expect no_warn
{} 22.5
eval instant at 50m avg (request_duration_seconds_bucket{le="+Inf"}) - avg (request_duration_seconds_bucket{le="0.2"})
expect no_warn
{} 15
eval instant at 50m count(request_duration_seconds)
expect no_warn
{} 4
# A histogram with nonmonotonic bucket counts. This may happen when recording

View File

@ -401,28 +401,35 @@ eval instant at 10m histogram_quantile(1.001, histogram_quantile_1)
{} Inf
eval instant at 10m histogram_quantile(1, histogram_quantile_1)
expect no_warn
{} 16
# The following quantiles are within a bucket. Exponential
# interpolation is applied (rather than linear, as it is done for
# classic histograms), leading to slightly different quantile values.
eval instant at 10m histogram_quantile(0.99, histogram_quantile_1)
expect no_warn
{} 15.67072476139083
eval instant at 10m histogram_quantile(0.9, histogram_quantile_1)
expect no_warn
{} 12.99603834169977
eval instant at 10m histogram_quantile(0.6, histogram_quantile_1)
expect no_warn
{} 4.594793419988138
eval instant at 10m histogram_quantile(0.5, histogram_quantile_1)
expect no_warn
{} 1.5874010519681994
# Linear interpolation within the zero bucket after all.
eval instant at 10m histogram_quantile(0.1, histogram_quantile_1)
expect no_warn
{} 0.0006
eval instant at 10m histogram_quantile(0, histogram_quantile_1)
expect no_warn
{} 0
eval instant at 10m histogram_quantile(-1, histogram_quantile_1)
@ -440,24 +447,30 @@ eval instant at 10m histogram_quantile(1.001, histogram_quantile_2)
{} Inf
eval instant at 10m histogram_quantile(1, histogram_quantile_2)
expect no_warn
{} 0
# Again, the quantile values here are slightly different from what
# they would be with linear interpolation. Note that quantiles
# ending up in the zero bucket are linearly interpolated after all.
eval instant at 10m histogram_quantile(0.99, histogram_quantile_2)
expect no_warn
{} -0.00006
eval instant at 10m histogram_quantile(0.9, histogram_quantile_2)
expect no_warn
{} -0.0006
eval instant at 10m histogram_quantile(0.5, histogram_quantile_2)
expect no_warn
{} -1.5874010519681996
eval instant at 10m histogram_quantile(0.1, histogram_quantile_2)
expect no_warn
{} -12.996038341699768
eval instant at 10m histogram_quantile(0, histogram_quantile_2)
expect no_warn
{} -16
eval instant at 10m histogram_quantile(-1, histogram_quantile_2)
@ -477,39 +490,50 @@ eval instant at 10m histogram_quantile(1.001, histogram_quantile_3)
{} Inf
eval instant at 10m histogram_quantile(1, histogram_quantile_3)
expect no_warn
{} 16
eval instant at 10m histogram_quantile(0.99, histogram_quantile_3)
expect no_warn
{} 15.34822590920423
eval instant at 10m histogram_quantile(0.9, histogram_quantile_3)
expect no_warn
{} 10.556063286183155
eval instant at 10m histogram_quantile(0.7, histogram_quantile_3)
expect no_warn
{} 1.2030250360821164
# Linear interpolation in the zero bucket, symmetrically centered around
# the zero point.
eval instant at 10m histogram_quantile(0.55, histogram_quantile_3)
expect no_warn
{} 0.0006
eval instant at 10m histogram_quantile(0.5, histogram_quantile_3)
expect no_warn
{} 0
eval instant at 10m histogram_quantile(0.45, histogram_quantile_3)
expect no_warn
{} -0.0006
# Finally negative buckets with mirrored exponential interpolation.
eval instant at 10m histogram_quantile(0.3, histogram_quantile_3)
expect no_warn
{} -1.2030250360821169
eval instant at 10m histogram_quantile(0.1, histogram_quantile_3)
expect no_warn
{} -10.556063286183155
eval instant at 10m histogram_quantile(0.01, histogram_quantile_3)
expect no_warn
{} -15.34822590920423
eval instant at 10m histogram_quantile(0, histogram_quantile_3)
expect no_warn
{} -16
eval instant at 10m histogram_quantile(-1, histogram_quantile_3)
@ -913,54 +937,71 @@ load 10m
float_series_0 0+0x1
eval instant at 10m histogram_mul_div*3
expect no_info
{} {{schema:0 count:90 sum:99 z_bucket:9 z_bucket_w:0.001 buckets:[9 9 9] n_buckets:[18 18 18]}}
eval instant at 10m histogram_mul_div*-1
expect no_info
{} {{schema:0 count:-30 sum:-33 z_bucket:-3 z_bucket_w:0.001 buckets:[-3 -3 -3] n_buckets:[-6 -6 -6]}}
eval instant at 10m -histogram_mul_div
expect no_info
{} {{schema:0 count:-30 sum:-33 z_bucket:-3 z_bucket_w:0.001 buckets:[-3 -3 -3] n_buckets:[-6 -6 -6]}}
eval instant at 10m histogram_mul_div*-3
expect no_info
{} {{schema:0 count:-90 sum:-99 z_bucket:-9 z_bucket_w:0.001 buckets:[-9 -9 -9] n_buckets:[-18 -18 -18]}}
eval instant at 10m 3*histogram_mul_div
expect no_info
{} {{schema:0 count:90 sum:99 z_bucket:9 z_bucket_w:0.001 buckets:[9 9 9] n_buckets:[18 18 18]}}
eval instant at 10m histogram_mul_div*float_series_3
expect no_info
{} {{schema:0 count:90 sum:99 z_bucket:9 z_bucket_w:0.001 buckets:[9 9 9] n_buckets:[18 18 18]}}
eval instant at 10m float_series_3*histogram_mul_div
expect no_info
{} {{schema:0 count:90 sum:99 z_bucket:9 z_bucket_w:0.001 buckets:[9 9 9] n_buckets:[18 18 18]}}
eval instant at 10m histogram_mul_div/3
expect no_info
{} {{schema:0 count:10 sum:11 z_bucket:1 z_bucket_w:0.001 buckets:[1 1 1] n_buckets:[2 2 2]}}
eval instant at 10m histogram_mul_div/-3
expect no_info
{} {{schema:0 count:-10 sum:-11 z_bucket:-1 z_bucket_w:0.001 buckets:[-1 -1 -1] n_buckets:[-2 -2 -2]}}
eval instant at 10m histogram_mul_div/float_series_3
expect no_info
{} {{schema:0 count:10 sum:11 z_bucket:1 z_bucket_w:0.001 buckets:[1 1 1] n_buckets:[2 2 2]}}
eval instant at 10m histogram_mul_div*0
expect no_info
{} {{schema:0 count:0 sum:0 z_bucket:0 z_bucket_w:0.001 buckets:[0 0 0] n_buckets:[0 0 0]}}
eval instant at 10m 0*histogram_mul_div
expect no_info
{} {{schema:0 count:0 sum:0 z_bucket:0 z_bucket_w:0.001 buckets:[0 0 0] n_buckets:[0 0 0]}}
eval instant at 10m histogram_mul_div*float_series_0
expect no_info
{} {{schema:0 count:0 sum:0 z_bucket:0 z_bucket_w:0.001 buckets:[0 0 0] n_buckets:[0 0 0]}}
eval instant at 10m float_series_0*histogram_mul_div
expect no_info
{} {{schema:0 count:0 sum:0 z_bucket:0 z_bucket_w:0.001 buckets:[0 0 0] n_buckets:[0 0 0]}}
eval instant at 10m histogram_mul_div/0
expect no_info
{} {{schema:0 count:Inf sum:Inf z_bucket_w:0.001 z_bucket:Inf}}
eval instant at 10m histogram_mul_div/float_series_0
expect no_info
{} {{schema:0 count:Inf sum:Inf z_bucket_w:0.001 z_bucket:Inf}}
eval instant at 10m histogram_mul_div*0/0
expect no_info
{} {{schema:0 count:NaN sum:NaN z_bucket_w:0.001 z_bucket:NaN}}
eval instant at 10m histogram_mul_div*histogram_mul_div
@ -1193,10 +1234,12 @@ load 6m
metric2 {{schema:-53 sum:1 count:1 custom_values:[5 10] buckets:[1]}} {{schema:-53 sum:1 count:1 custom_values:[5 10] buckets:[1]}}
eval range from 0 to 6m step 6m metric1 == metric2
metric1{} _ {{schema:-53 count:1 sum:1 custom_values:[5 10] buckets:[1]}}
expect no_info
metric1{} _ {{schema:-53 count:1 sum:1 custom_values:[5 10] buckets:[1]}}
eval range from 0 to 6m step 6m metric1 != metric2
metric1{} {{schema:-53 sum:1 count:1 custom_values:[2] buckets:[1]}} _
expect no_info
metric1{} {{schema:-53 sum:1 count:1 custom_values:[2] buckets:[1]}} _
eval range from 0 to 6m step 6m metric2 > metric2
expect info
@ -1216,16 +1259,20 @@ eval instant at 12m avg_over_time(nhcb_metric[13m])
expect warn
eval instant at 12m last_over_time(nhcb_metric[13m])
nhcb_metric{} {{schema:-53 sum:1 count:1 custom_values:[5 10] buckets:[1]}}
expect no_warn
nhcb_metric{} {{schema:-53 sum:1 count:1 custom_values:[5 10] buckets:[1]}}
eval instant at 12m count_over_time(nhcb_metric[13m])
{} 3
expect no_warn
{} 3
eval instant at 12m present_over_time(nhcb_metric[13m])
{} 1
expect no_warn
{} 1
eval instant at 12m changes(nhcb_metric[13m])
{} 1
expect no_warn
{} 1
eval instant at 12m delta(nhcb_metric[13m])
expect warn
@ -1237,7 +1284,8 @@ eval instant at 12m rate(nhcb_metric[13m])
expect warn
eval instant at 12m resets(nhcb_metric[13m])
{} 1
expect no_warn
{} 1
# Now doing the same again, but at 18m, where the first NHCB has
# different custom_values compared to the other two. This now
@ -1251,28 +1299,35 @@ eval instant at 18m avg_over_time(nhcb_metric[13m])
expect warn
eval instant at 18m last_over_time(nhcb_metric[13m])
nhcb_metric{} {{schema:-53 sum:1 count:1 custom_values:[5 10] buckets:[1]}}
expect no_warn
nhcb_metric{} {{schema:-53 sum:1 count:1 custom_values:[5 10] buckets:[1]}}
eval instant at 18m count_over_time(nhcb_metric[13m])
{} 3
expect no_warn
{} 3
eval instant at 18m present_over_time(nhcb_metric[13m])
{} 1
expect no_warn
{} 1
eval instant at 18m changes(nhcb_metric[13m])
{} 1
expect no_warn
{} 1
eval instant at 18m delta(nhcb_metric[13m])
expect warn
eval instant at 18m increase(nhcb_metric[13m])
{} {{schema:-53 count:1.0833333333333333 sum:1.0833333333333333 custom_values:[5 10] buckets:[1.0833333333333333]}}
expect no_warn
{} {{schema:-53 count:1.0833333333333333 sum:1.0833333333333333 custom_values:[5 10] buckets:[1.0833333333333333]}}
eval instant at 18m rate(nhcb_metric[13m])
{} {{schema:-53 count:0.0013888888888888887 sum:0.0013888888888888887 custom_values:[5 10] buckets:[0.0013888888888888887]}}
expect no_warn
{} {{schema:-53 count:0.0013888888888888887 sum:0.0013888888888888887 custom_values:[5 10] buckets:[0.0013888888888888887]}}
eval instant at 18m resets(nhcb_metric[13m])
{} 1
expect no_warn
{} 1
clear
@ -1307,18 +1362,22 @@ load 10m
histogram_sum_float{idx="0"} 42.0x1
eval instant at 10m sum(histogram_sum)
expect no_warn
{} {{schema:0 count:107 sum:4691.2 z_bucket:14 z_bucket_w:0.001 buckets:[3 8 2 5 3 2 2] n_buckets:[2 6 8 4 15 9 0 0 0 10 10 4]}}
eval instant at 10m sum({idx="0"})
expect warn
eval instant at 10m sum(histogram_sum{idx="0"} + ignoring(idx) histogram_sum{idx="1"} + ignoring(idx) histogram_sum{idx="2"} + ignoring(idx) histogram_sum{idx="3"})
expect no_warn
{} {{schema:0 count:107 sum:4691.2 z_bucket:14 z_bucket_w:0.001 buckets:[3 8 2 5 3 2 2] n_buckets:[2 6 8 4 15 9 0 0 0 10 10 4]}}
eval instant at 10m count(histogram_sum)
expect no_warn
{} 4
eval instant at 10m avg(histogram_sum)
expect no_warn
{} {{schema:0 count:26.75 sum:1172.8 z_bucket:3.5 z_bucket_w:0.001 buckets:[0.75 2 0.5 1.25 0.75 0.5 0.5] n_buckets:[0.5 1.5 2 1 3.75 2.25 0 0 0 2.5 2.5 1]}}
clear

View File

@ -310,9 +310,11 @@ eval instant at 5m http_requests_histogram <= 80
# Should produce valid results in case of (in)equality between two histograms.
eval instant at 5m http_requests_histogram == http_requests_histogram
expect no_info
http_requests_histogram{job="app-server", instance="1", group="production"} {{schema:1 sum:15 count:10 buckets:[3 2 5 7 9]}}
eval instant at 5m http_requests_histogram != http_requests_histogram
expect no_info
# group_left/group_right.
@ -527,20 +529,23 @@ load 6m
right_floats_for_histograms 0 -1 2 3 4
eval range from 0 to 60m step 6m left_floats == right_floats
expect no_info
left_floats _ _ _ _ 3 _ _ _ _ Inf -Inf
eval range from 0 to 60m step 6m left_floats == bool right_floats
expect no_info
{} 0 _ _ _ 1 _ 0 0 0 1 1
eval range from 0 to 60m step 6m left_floats == does_not_match
expect no_info
expect no_info
# No results.
eval range from 0 to 24m step 6m left_histograms == right_histograms
expect no_info
left_histograms {{schema:3 sum:4 count:4 buckets:[1 2 1]}} _ _ _ _
eval range from 0 to 24m step 6m left_histograms == bool right_histograms
expect no_info
{} 1 0 _ _ _
eval range from 0 to 24m step 6m left_histograms == right_floats_for_histograms
@ -552,15 +557,19 @@ eval range from 0 to 24m step 6m left_histograms == bool right_floats_for_histog
# No results.
eval range from 0 to 60m step 6m left_floats != right_floats
expect no_info
left_floats 1 _ _ _ _ _ 4 5 NaN _ _
eval range from 0 to 60m step 6m left_floats != bool right_floats
expect no_info
{} 1 _ _ _ 0 _ 1 1 1 0 0
eval range from 0 to 24m step 6m left_histograms != right_histograms
expect no_info
left_histograms _ {{schema:3 sum:4.5 count:5 buckets:[1 3 1]}} _ _ _
eval range from 0 to 24m step 6m left_histograms != bool right_histograms
expect no_info
{} 0 1 _ _ _
eval range from 0 to 24m step 6m left_histograms != right_floats_for_histograms
@ -572,9 +581,11 @@ eval range from 0 to 24m step 6m left_histograms != bool right_floats_for_histog
# No results.
eval range from 0 to 60m step 6m left_floats > right_floats
expect no_info
left_floats _ _ _ _ _ _ 4 _ _ _ _
eval range from 0 to 60m step 6m left_floats > bool right_floats
expect no_info
{} 0 _ _ _ 0 _ 1 0 0 0 0
eval range from 0 to 24m step 6m left_histograms > right_histograms
@ -594,9 +605,11 @@ eval range from 0 to 24m step 6m left_histograms > bool right_floats_for_histogr
# No results.
eval range from 0 to 60m step 6m left_floats >= right_floats
expect no_info
left_floats _ _ _ _ 3 _ 4 _ _ Inf -Inf
eval range from 0 to 60m step 6m left_floats >= bool right_floats
expect no_info
{} 0 _ _ _ 1 _ 1 0 0 1 1
eval range from 0 to 24m step 6m left_histograms >= right_histograms
@ -616,9 +629,11 @@ eval range from 0 to 24m step 6m left_histograms >= bool right_floats_for_histog
# No results.
eval range from 0 to 60m step 6m left_floats < right_floats
expect no_info
left_floats 1 _ _ _ _ _ _ 5 _ _ _
eval range from 0 to 60m step 6m left_floats < bool right_floats
expect no_info
{} 1 _ _ _ 0 _ 0 1 0 0 0
eval range from 0 to 24m step 6m left_histograms < right_histograms
@ -638,9 +653,11 @@ eval range from 0 to 24m step 6m left_histograms < bool right_floats_for_histogr
# No results.
eval range from 0 to 60m step 6m left_floats <= right_floats
expect no_info
left_floats 1 _ _ _ 3 _ _ 5 _ Inf -Inf
eval range from 0 to 60m step 6m left_floats <= bool right_floats
expect no_info
{} 1 _ _ _ 1 _ 0 1 0 1 1
eval range from 0 to 24m step 6m left_histograms <= right_histograms
@ -661,36 +678,47 @@ eval range from 0 to 24m step 6m left_histograms <= bool right_floats_for_histog
# Vector / scalar combinations with scalar on right side
eval range from 0 to 60m step 6m left_floats == 3
expect no_info
left_floats _ _ _ _ 3 _ _ _ _ _ _
eval range from 0 to 60m step 6m left_floats != 3
expect no_info
left_floats 1 2 _ _ _ _ 4 5 NaN Inf -Inf
eval range from 0 to 60m step 6m left_floats > 3
expect no_info
left_floats _ _ _ _ _ _ 4 5 _ Inf _
eval range from 0 to 60m step 6m left_floats >= 3
expect no_info
left_floats _ _ _ _ 3 _ 4 5 _ Inf _
eval range from 0 to 60m step 6m left_floats < 3
expect no_info
left_floats 1 2 _ _ _ _ _ _ _ _ -Inf
eval range from 0 to 60m step 6m left_floats <= 3
expect no_info
left_floats 1 2 _ _ 3 _ _ _ _ _ -Inf
eval range from 0 to 60m step 6m left_floats == bool 3
expect no_info
{} 0 0 _ _ 1 _ 0 0 0 0 0
eval range from 0 to 60m step 6m left_floats == Inf
expect no_info
left_floats _ _ _ _ _ _ _ _ _ Inf _
eval range from 0 to 60m step 6m left_floats == bool Inf
expect no_info
{} 0 0 _ _ 0 _ 0 0 0 1 0
eval range from 0 to 60m step 6m left_floats == NaN
expect no_info
# No results.
eval range from 0 to 60m step 6m left_floats == bool NaN
expect no_info
{} 0 0 _ _ 0 _ 0 0 0 0 0
eval range from 0 to 24m step 6m left_histograms == 3
@ -791,30 +819,39 @@ eval range from 0 to 24m step 6m left_histograms <= bool 0
# Vector / scalar combinations with scalar on left side
eval range from 0 to 60m step 6m 3 == left_floats
expect no_info
left_floats _ _ _ _ 3 _ _ _ _ _ _
eval range from 0 to 60m step 6m 3 != left_floats
expect no_info
left_floats 1 2 _ _ _ _ 4 5 NaN Inf -Inf
eval range from 0 to 60m step 6m 3 < left_floats
expect no_info
left_floats _ _ _ _ _ _ 4 5 _ Inf _
eval range from 0 to 60m step 6m 3 <= left_floats
expect no_info
left_floats _ _ _ _ 3 _ 4 5 _ Inf _
eval range from 0 to 60m step 6m 3 > left_floats
expect no_info
left_floats 1 2 _ _ _ _ _ _ _ _ -Inf
eval range from 0 to 60m step 6m 3 >= left_floats
expect no_info
left_floats 1 2 _ _ 3 _ _ _ _ _ -Inf
eval range from 0 to 60m step 6m 3 == bool left_floats
expect no_info
{} 0 0 _ _ 1 _ 0 0 0 0 0
eval range from 0 to 60m step 6m Inf == left_floats
expect no_info
left_floats _ _ _ _ _ _ _ _ _ Inf _
eval range from 0 to 60m step 6m Inf == bool left_floats
expect no_info
{} 0 0 _ _ 0 _ 0 0 0 1 0
eval range from 0 to 60m step 6m NaN == left_floats
@ -823,6 +860,7 @@ eval range from 0 to 60m step 6m NaN == left_floats
# No results.
eval range from 0 to 60m step 6m NaN == bool left_floats
expect no_info
{} 0 0 _ _ 0 _ 0 0 0 0 0
eval range from 0 to 24m step 6m 3 == left_histograms