diff --git a/promql/functions.go b/promql/functions.go index ff54e24d7a..251838607e 100644 --- a/promql/functions.go +++ b/promql/functions.go @@ -145,8 +145,17 @@ func funcIncrease(ev *evaluator, args Expressions) model.Value { // === irate(node model.ValMatrix) Vector === func funcIrate(ev *evaluator, args Expressions) model.Value { + return instantValue(ev, args[0], true) +} + +// === idelta(node model.ValMatric) Vector === +func funcIdelta(ev *evaluator, args Expressions) model.Value { + return instantValue(ev, args[0], false) +} + +func instantValue(ev *evaluator, arg Expr, isRate bool) model.Value { resultVector := vector{} - for _, samples := range ev.evalMatrix(args[0]) { + for _, samples := range ev.evalMatrix(arg) { // No sense in trying to compute a rate without at least two points. Drop // this vector element. if len(samples.Values) < 2 { @@ -157,7 +166,7 @@ func funcIrate(ev *evaluator, args Expressions) model.Value { previousSample := samples.Values[len(samples.Values)-2] var resultValue model.SampleValue - if lastSample.Value < previousSample.Value { + if isRate && lastSample.Value < previousSample.Value { // Counter reset. resultValue = lastSample.Value } else { @@ -169,8 +178,11 @@ func funcIrate(ev *evaluator, args Expressions) model.Value { // Avoid dividing by 0. continue } - // Convert to per-second. - resultValue /= model.SampleValue(sampledInterval.Seconds()) + + if isRate { + // Convert to per-second. + resultValue /= model.SampleValue(sampledInterval.Seconds()) + } resultSample := &sample{ Metric: samples.Metric, @@ -956,6 +968,12 @@ var functions = map[string]*Function{ ReturnType: model.ValVector, Call: funcIrate, }, + "idelta": { + Name: "idelta", + ArgTypes: []model.ValueType{model.ValMatrix}, + ReturnType: model.ValVector, + Call: funcIdelta, + }, "label_replace": { Name: "label_replace", ArgTypes: []model.ValueType{model.ValVector, model.ValString, model.ValString, model.ValString, model.ValString}, diff --git a/promql/testdata/functions.test b/promql/testdata/functions.test index 58b1ee5720..cbc789fd55 100644 --- a/promql/testdata/functions.test +++ b/promql/testdata/functions.test @@ -85,6 +85,28 @@ eval instant at 30m irate(http_requests[50m]) clear +# Tests for delta(). +load 5m + http_requests{path="/foo"} 0 50 100 150 200 + http_requests{path="/bar"} 200 150 100 50 0 + +eval instant at 20m delta(http_requests[20m]) + {path="/foo"} 200 + {path="/bar"} -200 + +clear + +# Tests for idelta(). +load 5m + http_requests{path="/foo"} 0 50 100 150 + http_requests{path="/bar"} 0 50 100 50 + +eval instant at 20m idelta(http_requests[20m]) + {path="/foo"} 50 + {path="/bar"} -50 + +clear + # Tests for deriv() and predict_linear(). load 5m testcounter_reset_middle 0+10x4 0+10x5 diff --git a/promql/testdata/legacy.test b/promql/testdata/legacy.test index 6da0281a7b..1556485f8c 100644 --- a/promql/testdata/legacy.test +++ b/promql/testdata/legacy.test @@ -91,11 +91,6 @@ eval instant at 50m x{y="testvalue"} x{y="testvalue"} 100 -# Deltas should be adjusted for target interval vs. samples under target interval. -eval instant at 50m delta(http_requests{group="canary", instance="1", job="app-server"}[18m]) - {group="canary", instance="1", job="app-server"} 288 - - # Rates should calculate per-second rates. eval instant at 50m rate(http_requests{group="canary", instance="1", job="app-server"}[50m]) {group="canary", instance="1", job="app-server"} 0.26666666666666666