Commit ec14fa58 by bergquist

alerting: add count_non_null reducer

makes it possible to have a second condition requering
at least X points of data.
parent 8e4a7060
...@@ -141,6 +141,16 @@ func (s *SimpleReducer) Reduce(series *tsdb.TimeSeries) null.Float { ...@@ -141,6 +141,16 @@ func (s *SimpleReducer) Reduce(series *tsdb.TimeSeries) null.Float {
break break
} }
} }
case "count_non_null":
for _, v := range series.Points {
if v[0].Valid {
value++
}
}
if value > 0 {
allNull = false
}
} }
if allNull { if allNull {
......
...@@ -67,6 +67,35 @@ func TestSimpleReducer(t *testing.T) { ...@@ -67,6 +67,35 @@ func TestSimpleReducer(t *testing.T) {
So(reducer.Reduce(series).Valid, ShouldEqual, false) So(reducer.Reduce(series).Valid, ShouldEqual, false)
}) })
Convey("count_non_null", func() {
Convey("with null values and real values", func() {
reducer := NewSimpleReducer("count_non_null")
series := &tsdb.TimeSeries{
Name: "test time serie",
}
series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 1))
series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFromPtr(nil), 2))
series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFrom(3), 3))
series.Points = append(series.Points, tsdb.NewTimePoint(null.FloatFrom(3), 4))
So(reducer.Reduce(series).Valid, ShouldEqual, true)
So(reducer.Reduce(series).Float64, ShouldEqual, 2)
})
Convey("with null values", func() {
reducer := NewSimpleReducer("count_non_null")
series := &tsdb.TimeSeries{
Name: "test time serie",
}
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)
})
})
Convey("avg of number values and null values should ignore nulls", func() { Convey("avg of number values and null values should ignore nulls", func() {
reducer := NewSimpleReducer("avg") reducer := NewSimpleReducer("avg")
series := &tsdb.TimeSeries{ series := &tsdb.TimeSeries{
......
...@@ -51,6 +51,7 @@ var reducerTypes = [ ...@@ -51,6 +51,7 @@ var reducerTypes = [
{text: 'median()', value: 'median'}, {text: 'median()', value: 'median'},
{text: 'diff()', value: 'diff'}, {text: 'diff()', value: 'diff'},
{text: 'percent_diff()', value: 'percent_diff'}, {text: 'percent_diff()', value: 'percent_diff'},
{text: 'count_non_null()', value: 'count_non_null'},
]; ];
var noDataModes = [ var noDataModes = [
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
<span class="gf-form-label query-keyword width-5" ng-if="$index===0">WHEN</span> <span class="gf-form-label query-keyword width-5" ng-if="$index===0">WHEN</span>
</div> </div>
<div class="gf-form"> <div class="gf-form">
<query-part-editor class="gf-form-label query-part width-6" part="conditionModel.reducerPart" handle-event="ctrl.handleReducerPartEvent(conditionModel, $event)"> <query-part-editor class="gf-form-label query-part width-9" part="conditionModel.reducerPart" handle-event="ctrl.handleReducerPartEvent(conditionModel, $event)">
</query-part-editor> </query-part-editor>
<span class="gf-form-label query-keyword">OF</span> <span class="gf-form-label query-keyword">OF</span>
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment