mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Fixed the issue/bug of diff and percent_diff functions *Breaking change* (#21338)
fixes #16270 #10129
This commit is contained in:
parent
0606555ba1
commit
066d5cf4da
@ -96,8 +96,12 @@ func (s *queryReducer) Reduce(series *tsdb.TimeSeries) null.Float {
|
||||
}
|
||||
case "diff":
|
||||
allNull, value = calculateDiff(series, allNull, value, diff)
|
||||
case "diff_abs":
|
||||
allNull, value = calculateDiff(series, allNull, value, diffAbs)
|
||||
case "percent_diff":
|
||||
allNull, value = calculateDiff(series, allNull, value, percentDiff)
|
||||
case "percent_diff_abs":
|
||||
allNull, value = calculateDiff(series, allNull, value, percentDiffAbs)
|
||||
case "count_non_null":
|
||||
for _, v := range series.Points {
|
||||
if isValid(v[0]) {
|
||||
@ -141,8 +145,7 @@ func calculateDiff(series *tsdb.TimeSeries, allNull bool, value float64, fn func
|
||||
for i := 0; i < len(points); i++ {
|
||||
if isValid(points[i][0]) {
|
||||
allNull = false
|
||||
val := fn(first, points[i][0].Float64)
|
||||
value = math.Abs(val)
|
||||
value = fn(first, points[i][0].Float64)
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -158,6 +161,14 @@ var diff = func(newest, oldest float64) float64 {
|
||||
return newest - oldest
|
||||
}
|
||||
|
||||
var percentDiff = func(newest, oldest float64) float64 {
|
||||
return (newest - oldest) / oldest * 100
|
||||
var diffAbs = func(newest, oldest float64) float64 {
|
||||
return math.Abs(newest - oldest)
|
||||
}
|
||||
|
||||
var percentDiff = func(newest, oldest float64) float64 {
|
||||
return (newest - oldest) / math.Abs(oldest) * 100
|
||||
}
|
||||
|
||||
var percentDiffAbs = func(newest, oldest float64) float64 {
|
||||
return math.Abs((newest - oldest) / oldest * 100)
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ func TestSimpleReducer(t *testing.T) {
|
||||
Convey("median should ignore null values", func() {
|
||||
reducer := newSimpleReducer("median")
|
||||
series := &tsdb.TimeSeries{
|
||||
Name: "test time serie",
|
||||
Name: "test time series",
|
||||
}
|
||||
|
||||
series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 1))
|
||||
@ -79,7 +79,7 @@ func TestSimpleReducer(t *testing.T) {
|
||||
Convey("avg with only nulls", func() {
|
||||
reducer := newSimpleReducer("avg")
|
||||
series := &tsdb.TimeSeries{
|
||||
Name: "test time serie",
|
||||
Name: "test time series",
|
||||
}
|
||||
|
||||
series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 1))
|
||||
@ -90,7 +90,7 @@ func TestSimpleReducer(t *testing.T) {
|
||||
Convey("with null values and real values", func() {
|
||||
reducer := newSimpleReducer("count_non_null")
|
||||
series := &tsdb.TimeSeries{
|
||||
Name: "test time serie",
|
||||
Name: "test time series",
|
||||
}
|
||||
|
||||
series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 1))
|
||||
@ -105,7 +105,7 @@ func TestSimpleReducer(t *testing.T) {
|
||||
Convey("with null values", func() {
|
||||
reducer := newSimpleReducer("count_non_null")
|
||||
series := &tsdb.TimeSeries{
|
||||
Name: "test time serie",
|
||||
Name: "test time series",
|
||||
}
|
||||
|
||||
series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 1))
|
||||
@ -118,7 +118,7 @@ func TestSimpleReducer(t *testing.T) {
|
||||
Convey("avg of number values and null values should ignore nulls", func() {
|
||||
reducer := newSimpleReducer("avg")
|
||||
series := &tsdb.TimeSeries{
|
||||
Name: "test time serie",
|
||||
Name: "test time series",
|
||||
}
|
||||
|
||||
series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFrom(3), 1))
|
||||
@ -129,25 +129,61 @@ func TestSimpleReducer(t *testing.T) {
|
||||
So(reducer.Reduce(series).Float64, ShouldEqual, float64(3))
|
||||
})
|
||||
|
||||
Convey("diff one point", func() {
|
||||
// diff function Test Suite
|
||||
Convey("diff of one positive point", func() {
|
||||
result := testReducer("diff", 30)
|
||||
So(result, ShouldEqual, float64(0))
|
||||
})
|
||||
|
||||
Convey("diff two points", func() {
|
||||
Convey("diff of one negative point", func() {
|
||||
result := testReducer("diff", -30)
|
||||
So(result, ShouldEqual, float64(0))
|
||||
})
|
||||
|
||||
Convey("diff of two positive points[1]", func() {
|
||||
result := testReducer("diff", 30, 40)
|
||||
So(result, ShouldEqual, float64(10))
|
||||
})
|
||||
|
||||
Convey("diff three points", func() {
|
||||
result := testReducer("diff", 30, 40, 40)
|
||||
So(result, ShouldEqual, float64(10))
|
||||
Convey("diff of two positive points[2]", func() {
|
||||
result := testReducer("diff", 30, 20)
|
||||
So(result, ShouldEqual, float64(-10))
|
||||
})
|
||||
|
||||
Convey("diff of two negative points[1]", func() {
|
||||
result := testReducer("diff", -30, -40)
|
||||
So(result, ShouldEqual, float64(-10))
|
||||
})
|
||||
|
||||
Convey("diff of two negative points[2]", func() {
|
||||
result := testReducer("diff", -30, -10)
|
||||
So(result, ShouldEqual, float64(20))
|
||||
})
|
||||
|
||||
Convey("diff of one positive and one negative point", func() {
|
||||
result := testReducer("diff", 30, -40)
|
||||
So(result, ShouldEqual, float64(-70))
|
||||
})
|
||||
|
||||
Convey("diff of one negative and one positive point", func() {
|
||||
result := testReducer("diff", -30, 40)
|
||||
So(result, ShouldEqual, float64(70))
|
||||
})
|
||||
|
||||
Convey("diff of three positive points", func() {
|
||||
result := testReducer("diff", 30, 40, 50)
|
||||
So(result, ShouldEqual, float64(20))
|
||||
})
|
||||
|
||||
Convey("diff of three negative points", func() {
|
||||
result := testReducer("diff", -30, -40, -50)
|
||||
So(result, ShouldEqual, float64(-20))
|
||||
})
|
||||
|
||||
Convey("diff with only nulls", func() {
|
||||
reducer := newSimpleReducer("diff")
|
||||
series := &tsdb.TimeSeries{
|
||||
Name: "test time serie",
|
||||
Name: "test time series",
|
||||
}
|
||||
|
||||
series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 1))
|
||||
@ -156,25 +192,187 @@ func TestSimpleReducer(t *testing.T) {
|
||||
So(reducer.Reduce(series).Valid, ShouldEqual, false)
|
||||
})
|
||||
|
||||
Convey("percent_diff one point", func() {
|
||||
result := testReducer("percent_diff", 40)
|
||||
// diff_abs function Test Suite
|
||||
Convey("diff_abs of one positive point", func() {
|
||||
result := testReducer("diff_abs", 30)
|
||||
So(result, ShouldEqual, float64(0))
|
||||
})
|
||||
|
||||
Convey("percent_diff two points", func() {
|
||||
Convey("diff_abs of one negative point", func() {
|
||||
result := testReducer("diff_abs", -30)
|
||||
So(result, ShouldEqual, float64(0))
|
||||
})
|
||||
|
||||
Convey("diff_abs of two positive points[1]", func() {
|
||||
result := testReducer("diff_abs", 30, 40)
|
||||
So(result, ShouldEqual, float64(10))
|
||||
})
|
||||
|
||||
Convey("diff_abs of two positive points[2]", func() {
|
||||
result := testReducer("diff_abs", 30, 20)
|
||||
So(result, ShouldEqual, float64(10))
|
||||
})
|
||||
|
||||
Convey("diff_abs of two negative points[1]", func() {
|
||||
result := testReducer("diff_abs", -30, -40)
|
||||
So(result, ShouldEqual, float64(10))
|
||||
})
|
||||
|
||||
Convey("diff_abs of two negative points[2]", func() {
|
||||
result := testReducer("diff_abs", -30, -10)
|
||||
So(result, ShouldEqual, float64(20))
|
||||
})
|
||||
|
||||
Convey("diff_abs of one positive and one negative point", func() {
|
||||
result := testReducer("diff_abs", 30, -40)
|
||||
So(result, ShouldEqual, float64(70))
|
||||
})
|
||||
|
||||
Convey("diff_abs of one negative and one positive point", func() {
|
||||
result := testReducer("diff_abs", -30, 40)
|
||||
So(result, ShouldEqual, float64(70))
|
||||
})
|
||||
|
||||
Convey("diff_abs of three positive points", func() {
|
||||
result := testReducer("diff_abs", 30, 40, 50)
|
||||
So(result, ShouldEqual, float64(20))
|
||||
})
|
||||
|
||||
Convey("diff_abs of three negative points", func() {
|
||||
result := testReducer("diff_abs", -30, -40, -50)
|
||||
So(result, ShouldEqual, float64(20))
|
||||
})
|
||||
|
||||
Convey("diff_abs with only nulls", func() {
|
||||
reducer := newSimpleReducer("diff_abs")
|
||||
series := &tsdb.TimeSeries{
|
||||
Name: "test time series",
|
||||
}
|
||||
|
||||
series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 1))
|
||||
series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 2))
|
||||
|
||||
So(reducer.Reduce(series).Valid, ShouldEqual, false)
|
||||
})
|
||||
|
||||
// percent_diff function Test Suite
|
||||
Convey("percent_diff of one positive point", func() {
|
||||
result := testReducer("percent_diff", 30)
|
||||
So(result, ShouldEqual, float64(0))
|
||||
})
|
||||
|
||||
Convey("percent_diff of one negative point", func() {
|
||||
result := testReducer("percent_diff", -30)
|
||||
So(result, ShouldEqual, float64(0))
|
||||
})
|
||||
|
||||
Convey("percent_diff of two positive points[1]", func() {
|
||||
result := testReducer("percent_diff", 30, 40)
|
||||
So(result, ShouldEqual, float64(33.33333333333333))
|
||||
})
|
||||
|
||||
Convey("percent_diff three points", func() {
|
||||
result := testReducer("percent_diff", 30, 40, 40)
|
||||
So(result, ShouldEqual, float64(33.33333333333333))
|
||||
Convey("percent_diff of two positive points[2]", func() {
|
||||
result := testReducer("percent_diff", 30, 20)
|
||||
So(result, ShouldEqual, float64(-33.33333333333333))
|
||||
})
|
||||
|
||||
Convey("percent_diff of two negative points[1]", func() {
|
||||
result := testReducer("percent_diff", -30, -40)
|
||||
So(result, ShouldEqual, float64(-33.33333333333333))
|
||||
})
|
||||
|
||||
Convey("percent_diff of two negative points[2]", func() {
|
||||
result := testReducer("percent_diff", -30, -10)
|
||||
So(result, ShouldEqual, float64(66.66666666666666))
|
||||
})
|
||||
|
||||
Convey("percent_diff of one positive and one negative point", func() {
|
||||
result := testReducer("percent_diff", 30, -40)
|
||||
So(result, ShouldEqual, float64(-233.33333333333334))
|
||||
})
|
||||
|
||||
Convey("percent_diff of one negative and one positive point", func() {
|
||||
result := testReducer("percent_diff", -30, 40)
|
||||
So(result, ShouldEqual, float64(233.33333333333334))
|
||||
})
|
||||
|
||||
Convey("percent_diff of three positive points", func() {
|
||||
result := testReducer("percent_diff", 30, 40, 50)
|
||||
So(result, ShouldEqual, float64(66.66666666666666))
|
||||
})
|
||||
|
||||
Convey("percent_diff of three negative points", func() {
|
||||
result := testReducer("percent_diff", -30, -40, -50)
|
||||
So(result, ShouldEqual, float64(-66.66666666666666))
|
||||
})
|
||||
|
||||
Convey("percent_diff with only nulls", func() {
|
||||
reducer := newSimpleReducer("percent_diff")
|
||||
series := &tsdb.TimeSeries{
|
||||
Name: "test time serie",
|
||||
Name: "test time series",
|
||||
}
|
||||
|
||||
series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 1))
|
||||
series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 2))
|
||||
|
||||
So(reducer.Reduce(series).Valid, ShouldEqual, false)
|
||||
})
|
||||
|
||||
// percent_diff_abs function Test Suite
|
||||
Convey("percent_diff_abs_abs of one positive point", func() {
|
||||
result := testReducer("percent_diff_abs", 30)
|
||||
So(result, ShouldEqual, float64(0))
|
||||
})
|
||||
|
||||
Convey("percent_diff_abs of one negative point", func() {
|
||||
result := testReducer("percent_diff_abs", -30)
|
||||
So(result, ShouldEqual, float64(0))
|
||||
})
|
||||
|
||||
Convey("percent_diff_abs of two positive points[1]", func() {
|
||||
result := testReducer("percent_diff_abs", 30, 40)
|
||||
So(result, ShouldEqual, float64(33.33333333333333))
|
||||
})
|
||||
|
||||
Convey("percent_diff_abs of two positive points[2]", func() {
|
||||
result := testReducer("percent_diff_abs", 30, 20)
|
||||
So(result, ShouldEqual, float64(33.33333333333333))
|
||||
})
|
||||
|
||||
Convey("percent_diff_abs of two negative points[1]", func() {
|
||||
result := testReducer("percent_diff_abs", -30, -40)
|
||||
So(result, ShouldEqual, float64(33.33333333333333))
|
||||
})
|
||||
|
||||
Convey("percent_diff_abs of two negative points[2]", func() {
|
||||
result := testReducer("percent_diff_abs", -30, -10)
|
||||
So(result, ShouldEqual, float64(66.66666666666666))
|
||||
})
|
||||
|
||||
Convey("percent_diff_abs of one positive and one negative point", func() {
|
||||
result := testReducer("percent_diff_abs", 30, -40)
|
||||
So(result, ShouldEqual, float64(233.33333333333334))
|
||||
})
|
||||
|
||||
Convey("percent_diff_abs of one negative and one positive point", func() {
|
||||
result := testReducer("percent_diff_abs", -30, 40)
|
||||
So(result, ShouldEqual, float64(233.33333333333334))
|
||||
})
|
||||
|
||||
Convey("percent_diff_abs of three positive points", func() {
|
||||
result := testReducer("percent_diff_abs", 30, 40, 50)
|
||||
So(result, ShouldEqual, float64(66.66666666666666))
|
||||
})
|
||||
|
||||
Convey("percent_diff_abs of three negative points", func() {
|
||||
result := testReducer("percent_diff_abs", -30, -40, -50)
|
||||
So(result, ShouldEqual, float64(66.66666666666666))
|
||||
})
|
||||
|
||||
Convey("percent_diff_abs with only nulls", func() {
|
||||
reducer := newSimpleReducer("percent_diff_abs")
|
||||
series := &tsdb.TimeSeries{
|
||||
Name: "test time series",
|
||||
}
|
||||
|
||||
series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 1))
|
||||
@ -203,7 +401,7 @@ func TestSimpleReducer(t *testing.T) {
|
||||
func testReducer(reducerType string, datapoints ...float64) float64 {
|
||||
reducer := newSimpleReducer(reducerType)
|
||||
series := &tsdb.TimeSeries{
|
||||
Name: "test time serie",
|
||||
Name: "test time series",
|
||||
}
|
||||
|
||||
for idx := range datapoints {
|
||||
|
@ -47,7 +47,9 @@ const reducerTypes = [
|
||||
{ text: 'last()', value: 'last' },
|
||||
{ text: 'median()', value: 'median' },
|
||||
{ text: 'diff()', value: 'diff' },
|
||||
{ text: 'diff_abs()', value: 'diff_abs' },
|
||||
{ text: 'percent_diff()', value: 'percent_diff' },
|
||||
{ text: 'percent_diff_abs()', value: 'percent_diff_abs' },
|
||||
{ text: 'count_non_null()', value: 'count_non_null' },
|
||||
];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user