diff --git a/promql/functions.go b/promql/functions.go index 8bd50667e..6505cab47 100644 --- a/promql/functions.go +++ b/promql/functions.go @@ -478,6 +478,34 @@ func funcSumOverTime(ev *evaluator, args Expressions) model.Value { }) } +// === stddev_over_time(matrix model.ValMatrix) Vector === +func funcStddevOverTime(ev *evaluator, args Expressions) model.Value { + return aggrOverTime(ev, args, func(values []model.SamplePair) model.SampleValue { + var sum, squaredSum, count model.SampleValue + for _, v := range values { + sum += v.Value + squaredSum += v.Value * v.Value + count += 1 + } + avg := sum / count + return model.SampleValue(math.Sqrt(float64(squaredSum/count - avg*avg))) + }) +} + +// === stdvar_over_time(matrix model.ValMatrix) Vector === +func funcStdvarOverTime(ev *evaluator, args Expressions) model.Value { + return aggrOverTime(ev, args, func(values []model.SamplePair) model.SampleValue { + var sum, squaredSum, count model.SampleValue + for _, v := range values { + sum += v.Value + squaredSum += v.Value * v.Value + count += 1 + } + avg := sum / count + return squaredSum/count - avg*avg + }) +} + // === abs(vector model.ValVector) Vector === func funcAbs(ev *evaluator, args Expressions) model.Value { vector := ev.evalVector(args[0]) @@ -988,6 +1016,18 @@ var functions = map[string]*Function{ ReturnType: model.ValVector, Call: funcSqrt, }, + "stddev_over_time": { + Name: "stddev_over_time", + ArgTypes: []model.ValueType{model.ValMatrix}, + ReturnType: model.ValVector, + Call: funcStddevOverTime, + }, + "stdvar_over_time": { + Name: "stdvar_over_time", + ArgTypes: []model.ValueType{model.ValMatrix}, + ReturnType: model.ValVector, + Call: funcStdvarOverTime, + }, "sum_over_time": { Name: "sum_over_time", ArgTypes: []model.ValueType{model.ValMatrix}, diff --git a/promql/testdata/functions.test b/promql/testdata/functions.test index 15f1affdb..4b73e2b8c 100644 --- a/promql/testdata/functions.test +++ b/promql/testdata/functions.test @@ -275,3 +275,15 @@ eval instant at 8000s holt_winters(http_requests[1m], 0.01, 0.1) {job="api-server", instance="1", group="production"} -16000 {job="api-server", instance="0", group="canary"} 24000 {job="api-server", instance="1", group="canary"} -32000 + + +# Tests for stddev_over_time and stdvar_over_time. +clear +load 10s + metric 0 8 8 2 3 + +eval instant at 1m stdvar_over_time(metric[1m]) + {} 10.56 + +eval instant at 1m stddev_over_time(metric[1m]) + {} 3.249615