From 6f33ed9e5923562cd8056dcc40084eb24b45a4e4 Mon Sep 17 00:00:00 2001 From: Julius Volz Date: Tue, 26 May 2015 17:47:52 +0200 Subject: [PATCH] Add resets() function to count counter resets. resets() returns for every range vector element how many counter resets there have been in the specified range. --- promql/functions.go | 33 +++++++++++++++++++++++++++++++++ promql/testdata/functions.test | 21 +++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 promql/testdata/functions.test diff --git a/promql/functions.go b/promql/functions.go index f1b9c0fd7..6103dbd38 100644 --- a/promql/functions.go +++ b/promql/functions.go @@ -505,6 +505,33 @@ func funcHistogramQuantile(ev *evaluator, args Expressions) Value { return outVec } +// === resets(matrix ExprMatrix) Vector === +func funcResets(ev *evaluator, args Expressions) Value { + in := ev.evalMatrix(args[0]) + out := make(Vector, 0, len(in)) + + for _, samples := range in { + resets := 0 + prev := clientmodel.SampleValue(samples.Values[0].Value) + for _, sample := range samples.Values[1:] { + current := sample.Value + if current < prev { + resets++ + } + prev = current + } + + rs := &Sample{ + Metric: samples.Metric, + Value: clientmodel.SampleValue(resets), + Timestamp: ev.Timestamp, + } + rs.Metric.Delete(clientmodel.MetricNameLabel) + out = append(out, rs) + } + return out +} + var functions = map[string]*Function{ "abs": { Name: "abs", @@ -621,6 +648,12 @@ var functions = map[string]*Function{ ReturnType: ExprVector, Call: funcRate, }, + "resets": { + Name: "resets", + ArgTypes: []ExprType{ExprMatrix}, + ReturnType: ExprVector, + Call: funcResets, + }, "round": { Name: "round", ArgTypes: []ExprType{ExprVector, ExprScalar}, diff --git a/promql/testdata/functions.test b/promql/testdata/functions.test new file mode 100644 index 000000000..e3c5687f9 --- /dev/null +++ b/promql/testdata/functions.test @@ -0,0 +1,21 @@ +load 5m + http_requests{path="/foo"} 1 2 3 0 1 0 0 1 2 0 + http_requests{path="/bar"} 1 2 3 4 5 1 2 3 4 5 + +eval instant at 50m resets(http_requests[5m]) + {path="/foo"} 0 + {path="/bar"} 0 + +eval instant at 50m resets(http_requests[20m]) + {path="/foo"} 1 + {path="/bar"} 0 + +eval instant at 50m resets(http_requests[30m]) + {path="/foo"} 2 + {path="/bar"} 1 + +eval instant at 50m resets(http_requests[50m]) + {path="/foo"} 3 + {path="/bar"} 1 + +eval instant at 50m resets(nonexistent_metric[50m])