Alerting: Support median in reduce expressions (#91119)

* Alerting: support median in reduce expressions
This commit is contained in:
Alexander Akhmetov
2024-08-01 15:04:17 +02:00
committed by GitHub
parent 66bfb31d8e
commit a32854549c
8 changed files with 248 additions and 22 deletions
+37 -7
View File
@@ -3,6 +3,7 @@ package mathexp
import (
"fmt"
"math"
"sort"
"github.com/grafana/grafana-plugin-sdk-go/data"
)
@@ -14,17 +15,18 @@ type ReducerFunc = func(fv *Float64Field) *float64
type ReducerID string
const (
ReducerSum ReducerID = "sum"
ReducerMean ReducerID = "mean"
ReducerMin ReducerID = "min"
ReducerMax ReducerID = "max"
ReducerCount ReducerID = "count"
ReducerLast ReducerID = "last"
ReducerSum ReducerID = "sum"
ReducerMean ReducerID = "mean"
ReducerMin ReducerID = "min"
ReducerMax ReducerID = "max"
ReducerCount ReducerID = "count"
ReducerLast ReducerID = "last"
ReducerMedian ReducerID = "median"
)
// GetSupportedReduceFuncs returns collection of supported function names
func GetSupportedReduceFuncs() []ReducerID {
return []ReducerID{ReducerSum, ReducerMean, ReducerMin, ReducerMax, ReducerCount, ReducerLast}
return []ReducerID{ReducerSum, ReducerMean, ReducerMin, ReducerMax, ReducerCount, ReducerLast, ReducerMedian}
}
func Sum(fv *Float64Field) *float64 {
@@ -98,6 +100,32 @@ func Last(fv *Float64Field) *float64 {
return fv.GetValue(fv.Len() - 1)
}
func Median(fv *Float64Field) *float64 {
values := make([]float64, 0, fv.Len())
for i := 0; i < fv.Len(); i++ {
v := fv.GetValue(i)
if v == nil || math.IsNaN(*v) {
nan := math.NaN()
return &nan
}
values = append(values, *v)
}
if len(values) == 0 {
nan := math.NaN()
return &nan
}
sort.Float64s(values)
mid := len(values) / 2
if len(values)%2 == 0 {
v := (values[mid-1] + values[mid]) / 2
return &v
} else {
return &values[mid]
}
}
func GetReduceFunc(rFunc ReducerID) (ReducerFunc, error) {
switch rFunc {
case ReducerSum:
@@ -112,6 +140,8 @@ func GetReduceFunc(rFunc ReducerID) (ReducerFunc, error) {
return Count, nil
case ReducerLast:
return Last, nil
case ReducerMedian:
return Median, nil
default:
return nil, fmt.Errorf("reduction %v not implemented", rFunc)
}