diff --git a/pkg/monitor/alerting/conditions/mathreducer.go b/pkg/monitor/alerting/conditions/mathreducer.go index 4579c0d440..524fb5daac 100644 --- a/pkg/monitor/alerting/conditions/mathreducer.go +++ b/pkg/monitor/alerting/conditions/mathreducer.go @@ -13,8 +13,13 @@ import ( type mathReducer struct { // Type is how the timeseries should be reduced. // Ex: avg, sum, max, min, count - Type string - Opt string + Type string + Opt string + Params []float64 +} + +func (s *mathReducer) GetParams() []float64 { + return s.Params } func (s *mathReducer) GetType() string { @@ -169,8 +174,9 @@ func (reducer *mathReducer) mathValue(values []float64) (float64, error) { func newMathReducer(cond *monitor.Condition) (*mathReducer, error) { return &mathReducer{ - Type: cond.Type, - Opt: cond.Operators[0], + Type: cond.Type, + Opt: cond.Operators[0], + Params: cond.Params, }, nil } diff --git a/pkg/monitor/alerting/conditions/reducer.go b/pkg/monitor/alerting/conditions/reducer.go index dd25fa0b34..12441f12cd 100644 --- a/pkg/monitor/alerting/conditions/reducer.go +++ b/pkg/monitor/alerting/conditions/reducer.go @@ -29,13 +29,19 @@ import ( type Reducer interface { Reduce(series *tsdb.TimeSeries) (*float64, []string) GetType() string + GetParams() []float64 } // queryReducer reduces an timeseries to a float type queryReducer struct { // Type is how the timeseries should be reduced. // Ex: avg, sum, max, min, count - Type string + Type string + Params []float64 +} + +func (s *queryReducer) GetParams() []float64 { + return s.Params } func (s *queryReducer) GetType() string { @@ -134,7 +140,7 @@ func (s *queryReducer) Reduce(series *tsdb.TimeSeries) (*float64, []string) { if value > 0 { allNull = false } - case "P95": + case "percentile": var values []float64 for _, v := range series.Points { if v.IsValid() { @@ -142,10 +148,14 @@ func (s *queryReducer) Reduce(series *tsdb.TimeSeries) (*float64, []string) { values = append(values, v.Value()) } } + pNum := float64(95) + if len(s.Params) != 0 { + pNum = s.Params[0] + } if len(values) >= 1 { sort.Float64s(values) length := len(values) - index := math.Floor(float64(length) * 0.95) + index := math.Floor(float64(length) * pNum / float64(100)) value = values[int64(index)] } } @@ -157,8 +167,18 @@ func (s *queryReducer) Reduce(series *tsdb.TimeSeries) (*float64, []string) { return &value, valArr } -func newSimpleReducer(t string) *queryReducer { - return &queryReducer{Type: t} +func newSimpleReducer(cond *monitor.Condition) *queryReducer { + return &queryReducer{ + Type: cond.Type, + Params: cond.Params, + } +} + +func newSimpleReducerByType(typ string) *queryReducer { + return &queryReducer{ + Type: typ, + Params: []float64{}, + } } func calculateDiff(series *tsdb.TimeSeries, allNull bool, value float64, fn func(float64, float64) float64) (bool, float64) { @@ -199,7 +219,7 @@ var percentDiff = func(newest, oldest float64) float64 { func NewAlertReducer(cond *monitor.Condition) (Reducer, error) { if len(cond.Operators) == 0 { - return newSimpleReducer(cond.Type), nil + return newSimpleReducer(cond), nil } if utils.IsInStringArray(cond.Operators[0], validators.CommonAlertReducerFieldOpts) { diff --git a/pkg/monitor/alerting/conditions/reducer_test.go b/pkg/monitor/alerting/conditions/reducer_test.go index 32640a8a60..b7c480a069 100644 --- a/pkg/monitor/alerting/conditions/reducer_test.go +++ b/pkg/monitor/alerting/conditions/reducer_test.go @@ -66,7 +66,7 @@ func TestSimpleReducer(t *testing.T) { }) Convey("median should ignore null values", func() { - reducer := newSimpleReducer("median") + reducer := newSimpleReducerByType("median") series := &tsdb.TimeSeries{ Name: "test time series", } @@ -90,7 +90,7 @@ func TestSimpleReducer(t *testing.T) { Convey("count_non_null", func() { Convey("with null values and real values", func() { - reducer := newSimpleReducer("count_non_null") + reducer := newSimpleReducerByType("count_non_null") series := &tsdb.TimeSeries{ Name: "test time series", } @@ -105,7 +105,7 @@ func TestSimpleReducer(t *testing.T) { }) Convey("with null values", func() { - reducer := newSimpleReducer("count_non_null") + reducer := newSimpleReducerByType("count_non_null") series := &tsdb.TimeSeries{ Name: "test time series", } @@ -118,7 +118,7 @@ func TestSimpleReducer(t *testing.T) { }) Convey("avg of number values and null values should ignore nulls", func() { - reduer := newSimpleReducer("avg") + reduer := newSimpleReducerByType("avg") series := &tsdb.TimeSeries{ Name: "test time series", } @@ -147,7 +147,7 @@ func TestSimpleReducer(t *testing.T) { }) Convey("diff with only nulls", func() { - reducer := newSimpleReducer("diff") + reducer := newSimpleReducerByType("diff") series := &tsdb.TimeSeries{ Name: "test time serie", } @@ -174,7 +174,7 @@ func TestSimpleReducer(t *testing.T) { }) Convey("percent_diff with only nulls", func() { - reducer := newSimpleReducer("percent_diff") + reducer := newSimpleReducerByType("percent_diff") series := &tsdb.TimeSeries{ Name: "test time serie", } @@ -188,7 +188,7 @@ func TestSimpleReducer(t *testing.T) { } func testReducer(reducerType string, datapoints ...float64) float64 { - reducer := newSimpleReducer(reducerType) + reducer := newSimpleReducerByType(reducerType) serires := &tsdb.TimeSeries{ Name: "test time series", }