Merge pull request #15527 from NeerajGartia21/promql/funcResets

[BUGFIX] PromQL: Fix `resets` function for histograms
pull/14960/merge
Björn Rabenstein 2024-12-03 22:43:07 +01:00 committed by GitHub
commit 6a6630d2a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 53 additions and 37 deletions

View File

@ -1400,27 +1400,41 @@ func funcResets(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelpe
floats := vals[0].(Matrix)[0].Floats
histograms := vals[0].(Matrix)[0].Histograms
resets := 0
if len(floats) > 1 {
prev := floats[0].F
for _, sample := range floats[1:] {
current := sample.F
if current < prev {
resets++
}
prev = current
}
if len(floats) == 0 && len(histograms) == 0 {
return enh.Out, nil
}
if len(histograms) > 1 {
prev := histograms[0].H
for _, sample := range histograms[1:] {
current := sample.H
if current.DetectReset(prev) {
var prevSample, curSample Sample
for iFloat, iHistogram := 0, 0; iFloat < len(floats) || iHistogram < len(histograms); {
switch {
// Process a float sample if no histogram sample remains or its timestamp is earlier.
// Process a histogram sample if no float sample remains or its timestamp is earlier.
case iHistogram >= len(histograms) || iFloat < len(floats) && floats[iFloat].T < histograms[iHistogram].T:
curSample.F = floats[iFloat].F
curSample.H = nil
iFloat++
case iFloat >= len(floats) || iHistogram < len(histograms) && floats[iFloat].T > histograms[iHistogram].T:
curSample.H = histograms[iHistogram].H
iHistogram++
}
// Skip the comparison for the first sample, just initialize prevSample.
if iFloat+iHistogram == 1 {
prevSample = curSample
continue
}
switch {
case prevSample.H == nil && curSample.H == nil:
if curSample.F < prevSample.F {
resets++
}
case prevSample.H != nil && curSample.H == nil, prevSample.H == nil && curSample.H != nil:
resets++
case prevSample.H != nil && curSample.H != nil:
if curSample.H.DetectReset(prevSample.H) {
resets++
}
prev = current
}
prevSample = curSample
}
return append(enh.Out, Sample{F: float64(resets)}), nil
@ -1441,16 +1455,12 @@ func funcChanges(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelp
// Process a float sample if no histogram sample remains or its timestamp is earlier.
// Process a histogram sample if no float sample remains or its timestamp is earlier.
case iHistogram >= len(histograms) || iFloat < len(floats) && floats[iFloat].T < histograms[iHistogram].T:
{
curSample.F = floats[iFloat].F
curSample.H = nil
iFloat++
}
curSample.F = floats[iFloat].F
curSample.H = nil
iFloat++
case iFloat >= len(floats) || iHistogram < len(histograms) && floats[iFloat].T > histograms[iHistogram].T:
{
curSample.H = histograms[iHistogram].H
iHistogram++
}
curSample.H = histograms[iHistogram].H
iHistogram++
}
// Skip the comparison for the first sample, just initialize prevSample.
if iFloat+iHistogram == 1 {
@ -1459,20 +1469,14 @@ func funcChanges(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelp
}
switch {
case prevSample.H == nil && curSample.H == nil:
{
if curSample.F != prevSample.F && !(math.IsNaN(curSample.F) && math.IsNaN(prevSample.F)) {
changes++
}
}
case prevSample.H != nil && curSample.H == nil, prevSample.H == nil && curSample.H != nil:
{
if curSample.F != prevSample.F && !(math.IsNaN(curSample.F) && math.IsNaN(prevSample.F)) {
changes++
}
case prevSample.H != nil && curSample.H == nil, prevSample.H == nil && curSample.H != nil:
changes++
case prevSample.H != nil && curSample.H != nil:
{
if !curSample.H.Equals(prevSample.H) {
changes++
}
if !curSample.H.Equals(prevSample.H) {
changes++
}
}
prevSample = curSample

View File

@ -5,7 +5,7 @@ load 5m
http_requests{path="/biz"} 0 0 0 0 0 1 1 1 1 1
http_requests_histogram{path="/foo"} {{schema:0 sum:1 count:1}}x9
http_requests_histogram{path="/bar"} 0 0 0 0 0 0 0 0 {{schema:0 sum:1 count:1}} {{schema:0 sum:1 count:1}}
http_requests_histogram{path="/biz"} 0 1 0 2 0 3 0 {{schema:0 sum:1 count:1}} {{schema:0 sum:2 count:2}} {{schema:0 sum:1 count:1}}
http_requests_histogram{path="/biz"} 0 1 0 2 0 3 0 {{schema:0 sum:1 count:1 z_bucket_w:0.001 z_bucket:2}} {{schema:0 sum:2 count:2 z_bucket_w:0.001 z_bucket:1}} {{schema:0 sum:1 count:1 z_bucket_w:0.001 z_bucket:2}}
# Tests for resets().
eval instant at 50m resets(http_requests[5m])
@ -42,6 +42,18 @@ eval instant at 50m resets(http_requests[50m])
eval instant at 50m resets(nonexistent_metric[50m])
# Test for mix of floats and histograms.
eval instant at 50m resets(http_requests_histogram[6m])
{path="/foo"} 0
{path="/bar"} 0
{path="/biz"} 0
eval instant at 50m resets(http_requests_histogram[60m])
{path="/foo"} 0
{path="/bar"} 1
{path="/biz"} 6
# Tests for changes().
eval instant at 50m changes(http_requests[5m])