Chore: Refactor usage of legacy data contracts (#41218)

Refactor usage of legacy data contracts. Moves legacy data contracts 
to pkg/tsdb/legacydata package.
Refactor pkg/expr to be a proper service/dependency that can be provided 
to wire to remove some unneeded dependencies to SSE in ngalert and other places.
Refactor pkg/expr to not use the legacydata,RequestHandler and use 
backend.QueryDataHandler instead.
This commit is contained in:
Marcus Efraimsson
2021-11-10 11:52:16 +01:00
committed by GitHub
parent d6ed5d295e
commit baab021fec
54 changed files with 732 additions and 951 deletions
+20 -20
View File
@@ -6,8 +6,8 @@ import (
"strings"
"time"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/tsdb/interval"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
"github.com/grafana/grafana/pkg/tsdb/legacydata/interval"
"github.com/grafana/grafana/pkg/tsdb/prometheus"
gocontext "context"
@@ -47,8 +47,8 @@ type AlertQuery struct {
}
// Eval evaluates the `QueryCondition`.
func (c *QueryCondition) Eval(context *alerting.EvalContext, requestHandler plugins.DataRequestHandler) (*alerting.ConditionResult, error) {
timeRange := plugins.NewDataTimeRange(c.Query.From, c.Query.To)
func (c *QueryCondition) Eval(context *alerting.EvalContext, requestHandler legacydata.RequestHandler) (*alerting.ConditionResult, error) {
timeRange := legacydata.NewDataTimeRange(c.Query.From, c.Query.To)
seriesList, err := c.executeQuery(context, timeRange, requestHandler)
if err != nil {
@@ -109,7 +109,7 @@ func (c *QueryCondition) Eval(context *alerting.EvalContext, requestHandler plug
}, nil
}
func calculateInterval(timeRange plugins.DataTimeRange, model *simplejson.Json, dsInfo *models.DataSource) (time.Duration, error) {
func calculateInterval(timeRange legacydata.DataTimeRange, model *simplejson.Json, dsInfo *models.DataSource) (time.Duration, error) {
// if there is no min-interval specified in the datasource or in the dashboard-panel,
// the value of 1ms is used (this is how it is done in the dashboard-interval-calculation too,
// see https://github.com/grafana/grafana/blob/9a0040c0aeaae8357c650cec2ee644a571dddf3d/packages/grafana-data/src/datetime/rangeutil.ts#L264)
@@ -133,8 +133,8 @@ func calculateInterval(timeRange plugins.DataTimeRange, model *simplejson.Json,
return interval.Value, nil
}
func (c *QueryCondition) executeQuery(context *alerting.EvalContext, timeRange plugins.DataTimeRange,
requestHandler plugins.DataRequestHandler) (plugins.DataTimeSeriesSlice, error) {
func (c *QueryCondition) executeQuery(context *alerting.EvalContext, timeRange legacydata.DataTimeRange,
requestHandler legacydata.RequestHandler) (legacydata.DataTimeSeriesSlice, error) {
getDsInfo := &models.GetDataSourceQuery{
Id: c.Query.DatasourceID,
OrgId: context.Rule.OrgID,
@@ -153,7 +153,7 @@ func (c *QueryCondition) executeQuery(context *alerting.EvalContext, timeRange p
if err != nil {
return nil, fmt.Errorf("interval calculation failed: %w", err)
}
result := make(plugins.DataTimeSeriesSlice, 0)
result := make(legacydata.DataTimeSeriesSlice, 0)
if context.IsDebug {
data := simplejson.New()
@@ -247,18 +247,18 @@ func (c *QueryCondition) executeQuery(context *alerting.EvalContext, timeRange p
return result, nil
}
func (c *QueryCondition) getRequestForAlertRule(datasource *models.DataSource, timeRange plugins.DataTimeRange,
debug bool) (plugins.DataQuery, error) {
func (c *QueryCondition) getRequestForAlertRule(datasource *models.DataSource, timeRange legacydata.DataTimeRange,
debug bool) (legacydata.DataQuery, error) {
queryModel := c.Query.Model
calculatedInterval, err := calculateInterval(timeRange, queryModel, datasource)
if err != nil {
return plugins.DataQuery{}, err
return legacydata.DataQuery{}, err
}
req := plugins.DataQuery{
req := legacydata.DataQuery{
TimeRange: &timeRange,
Queries: []plugins.DataSubQuery{
Queries: []legacydata.DataSubQuery{
{
RefID: "A",
Model: queryModel,
@@ -340,21 +340,21 @@ func validateToValue(to string) error {
// FrameToSeriesSlice converts a frame that is a valid time series as per data.TimeSeriesSchema()
// to a DataTimeSeriesSlice.
func FrameToSeriesSlice(frame *data.Frame) (plugins.DataTimeSeriesSlice, error) {
func FrameToSeriesSlice(frame *data.Frame) (legacydata.DataTimeSeriesSlice, error) {
tsSchema := frame.TimeSeriesSchema()
if tsSchema.Type == data.TimeSeriesTypeNot {
// If no fields, or only a time field, create an empty plugins.DataTimeSeriesSlice with a single
// time series in order to trigger "no data" in alerting.
if frame.Rows() == 0 || (len(frame.Fields) == 1 && frame.Fields[0].Type().Time()) {
return plugins.DataTimeSeriesSlice{{
return legacydata.DataTimeSeriesSlice{{
Name: frame.Name,
Points: make(plugins.DataTimeSeriesPoints, 0),
Points: make(legacydata.DataTimeSeriesPoints, 0),
}}, nil
}
return nil, fmt.Errorf("input frame is not recognized as a time series")
}
seriesCount := len(tsSchema.ValueIndices)
seriesSlice := make(plugins.DataTimeSeriesSlice, 0, seriesCount)
seriesSlice := make(legacydata.DataTimeSeriesSlice, 0, seriesCount)
timeField := frame.Fields[tsSchema.TimeIndex]
timeNullFloatSlice := make([]null.Float, timeField.Len())
@@ -368,8 +368,8 @@ func FrameToSeriesSlice(frame *data.Frame) (plugins.DataTimeSeriesSlice, error)
for _, fieldIdx := range tsSchema.ValueIndices { // create a TimeSeries for each value Field
field := frame.Fields[fieldIdx]
ts := plugins.DataTimeSeries{
Points: make(plugins.DataTimeSeriesPoints, field.Len()),
ts := legacydata.DataTimeSeries{
Points: make(legacydata.DataTimeSeriesPoints, field.Len()),
}
if len(field.Labels) > 0 {
@@ -395,7 +395,7 @@ func FrameToSeriesSlice(frame *data.Frame) (plugins.DataTimeSeriesSlice, error)
return nil, errutil.Wrapf(err,
"failed to convert frame to DataTimeSeriesSlice, can not convert value %v to float", field.At(rowIdx))
}
ts.Points[rowIdx] = plugins.DataTimePoint{
ts.Points[rowIdx] = legacydata.DataTimePoint{
null.FloatFrom(val),
timeNullFloatSlice[rowIdx],
}
@@ -4,14 +4,13 @@ import (
"context"
"testing"
"github.com/grafana/grafana/pkg/services/validations"
"github.com/grafana/grafana/pkg/tsdb/interval"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/validations"
"github.com/grafana/grafana/pkg/tsdb/intervalv2"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
"github.com/stretchr/testify/require"
)
@@ -27,11 +26,11 @@ func TestQueryInterval(t *testing.T) {
timeRange := "5m"
verifier := func(query plugins.DataSubQuery) {
verifier := func(query legacydata.DataSubQuery) {
// 5minutes timerange = 300000milliseconds; default-resolution is 1500pixels,
// so we should have 300000/1500 = 200milliseconds here
require.Equal(t, int64(200), query.IntervalMS)
require.Equal(t, interval.DefaultRes, query.MaxDataPoints)
require.Equal(t, intervalv2.DefaultRes, query.MaxDataPoints)
}
applyScenario(t, timeRange, dataSourceJson, queryModel, verifier)
@@ -45,9 +44,9 @@ func TestQueryInterval(t *testing.T) {
timeRange := "5m"
verifier := func(query plugins.DataSubQuery) {
verifier := func(query legacydata.DataSubQuery) {
require.Equal(t, int64(123000), query.IntervalMS)
require.Equal(t, interval.DefaultRes, query.MaxDataPoints)
require.Equal(t, intervalv2.DefaultRes, query.MaxDataPoints)
}
applyScenario(t, timeRange, dataSourceJson, queryModel, verifier)
@@ -64,9 +63,9 @@ func TestQueryInterval(t *testing.T) {
timeRange := "5m"
verifier := func(query plugins.DataSubQuery) {
verifier := func(query legacydata.DataSubQuery) {
require.Equal(t, int64(71000), query.IntervalMS)
require.Equal(t, interval.DefaultRes, query.MaxDataPoints)
require.Equal(t, intervalv2.DefaultRes, query.MaxDataPoints)
}
applyScenario(t, timeRange, dataSourceJson, queryModel, verifier)
@@ -83,11 +82,11 @@ func TestQueryInterval(t *testing.T) {
timeRange := "5m"
verifier := func(query plugins.DataSubQuery) {
verifier := func(query legacydata.DataSubQuery) {
// when both panel-min-interval and datasource-min-interval exists,
// panel-min-interval is used
require.Equal(t, int64(19000), query.IntervalMS)
require.Equal(t, interval.DefaultRes, query.MaxDataPoints)
require.Equal(t, intervalv2.DefaultRes, query.MaxDataPoints)
}
applyScenario(t, timeRange, dataSourceJson, queryModel, verifier)
@@ -102,11 +101,11 @@ func TestQueryInterval(t *testing.T) {
timeRange := "1s"
verifier := func(query plugins.DataSubQuery) {
verifier := func(query legacydata.DataSubQuery) {
// no min-interval exists, the default-min-interval will be used,
// and for such a short time-range this will cause the value to be 1millisecond.
require.Equal(t, int64(1), query.IntervalMS)
require.Equal(t, interval.DefaultRes, query.MaxDataPoints)
require.Equal(t, intervalv2.DefaultRes, query.MaxDataPoints)
}
applyScenario(t, timeRange, dataSourceJson, queryModel, verifier)
@@ -119,24 +118,24 @@ type queryIntervalTestContext struct {
condition *QueryCondition
}
type queryIntervalVerifier func(query plugins.DataSubQuery)
type queryIntervalVerifier func(query legacydata.DataSubQuery)
type fakeIntervalTestReqHandler struct {
//nolint: staticcheck // plugins.DataResponse deprecated
response plugins.DataResponse
//nolint: staticcheck // legacydata.DataResponse deprecated
response legacydata.DataResponse
verifier queryIntervalVerifier
}
//nolint: staticcheck // plugins.DataResponse deprecated
func (rh fakeIntervalTestReqHandler) HandleRequest(ctx context.Context, dsInfo *models.DataSource, query plugins.DataQuery) (
plugins.DataResponse, error) {
//nolint: staticcheck // legacydata.DataResponse deprecated
func (rh fakeIntervalTestReqHandler) HandleRequest(ctx context.Context, dsInfo *models.DataSource, query legacydata.DataQuery) (
legacydata.DataResponse, error) {
q := query.Queries[0]
rh.verifier(q)
return rh.response, nil
}
//nolint: staticcheck // plugins.DataResponse deprecated
func applyScenario(t *testing.T, timeRange string, dataSourceJsonData *simplejson.Json, queryModel string, verifier func(query plugins.DataSubQuery)) {
//nolint: staticcheck // legacydata.DataResponse deprecated
func applyScenario(t *testing.T, timeRange string, dataSourceJsonData *simplejson.Json, queryModel string, verifier func(query legacydata.DataSubQuery)) {
t.Run("desc", func(t *testing.T) {
bus.AddHandlerCtx("test", func(ctx context.Context, query *models.GetDataSourceQuery) error {
query.Result = &models.DataSource{Id: 1, Type: "graphite", JsonData: dataSourceJsonData}
@@ -167,11 +166,11 @@ func applyScenario(t *testing.T, timeRange string, dataSourceJsonData *simplejso
ctx.condition = condition
qr := plugins.DataQueryResult{}
qr := legacydata.DataQueryResult{}
reqHandler := fakeIntervalTestReqHandler{
response: plugins.DataResponse{
Results: map[string]plugins.DataQueryResult{
response: legacydata.DataResponse{
Results: map[string]legacydata.DataQueryResult{
"A": qr,
},
},
+58 -58
View File
@@ -7,6 +7,7 @@ import (
"time"
"github.com/grafana/grafana/pkg/services/validations"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
@@ -15,18 +16,17 @@ import (
"github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/stretchr/testify/require"
"github.com/xorcare/pointer"
)
func newTimeSeriesPointsFromArgs(values ...float64) plugins.DataTimeSeriesPoints {
points := make(plugins.DataTimeSeriesPoints, 0)
func newTimeSeriesPointsFromArgs(values ...float64) legacydata.DataTimeSeriesPoints {
points := make(legacydata.DataTimeSeriesPoints, 0)
for i := 0; i < len(values); i += 2 {
points = append(points, plugins.DataTimePoint{null.FloatFrom(values[i]), null.FloatFrom(values[i+1])})
points = append(points, legacydata.DataTimePoint{null.FloatFrom(values[i]), null.FloatFrom(values[i+1])})
}
return points
@@ -74,7 +74,7 @@ func TestQueryCondition(t *testing.T) {
t.Run("should fire when avg is above 100", func(t *testing.T) {
ctx := setup()
points := newTimeSeriesPointsFromArgs(120, 0)
ctx.series = plugins.DataTimeSeriesSlice{plugins.DataTimeSeries{Name: "test1", Points: points}}
ctx.series = legacydata.DataTimeSeriesSlice{legacydata.DataTimeSeries{Name: "test1", Points: points}}
cr, err := ctx.exec(t)
require.Nil(t, err)
@@ -96,7 +96,7 @@ func TestQueryCondition(t *testing.T) {
t.Run("Should not fire when avg is below 100", func(t *testing.T) {
ctx := setup()
points := newTimeSeriesPointsFromArgs(90, 0)
ctx.series = plugins.DataTimeSeriesSlice{plugins.DataTimeSeries{Name: "test1", Points: points}}
ctx.series = legacydata.DataTimeSeriesSlice{legacydata.DataTimeSeries{Name: "test1", Points: points}}
cr, err := ctx.exec(t)
require.Nil(t, err)
@@ -117,9 +117,9 @@ func TestQueryCondition(t *testing.T) {
t.Run("Should fire if only first series matches", func(t *testing.T) {
ctx := setup()
ctx.series = plugins.DataTimeSeriesSlice{
plugins.DataTimeSeries{Name: "test1", Points: newTimeSeriesPointsFromArgs(120, 0)},
plugins.DataTimeSeries{Name: "test2", Points: newTimeSeriesPointsFromArgs(0, 0)},
ctx.series = legacydata.DataTimeSeriesSlice{
legacydata.DataTimeSeries{Name: "test1", Points: newTimeSeriesPointsFromArgs(120, 0)},
legacydata.DataTimeSeries{Name: "test2", Points: newTimeSeriesPointsFromArgs(0, 0)},
}
cr, err := ctx.exec(t)
@@ -130,7 +130,7 @@ func TestQueryCondition(t *testing.T) {
t.Run("No series", func(t *testing.T) {
ctx := setup()
t.Run("Should set NoDataFound when condition is gt", func(t *testing.T) {
ctx.series = plugins.DataTimeSeriesSlice{}
ctx.series = legacydata.DataTimeSeriesSlice{}
cr, err := ctx.exec(t)
require.Nil(t, err)
@@ -140,7 +140,7 @@ func TestQueryCondition(t *testing.T) {
t.Run("Should be firing when condition is no_value", func(t *testing.T) {
ctx.evaluator = `{"type": "no_value", "params": []}`
ctx.series = plugins.DataTimeSeriesSlice{}
ctx.series = legacydata.DataTimeSeriesSlice{}
cr, err := ctx.exec(t)
require.Nil(t, err)
@@ -152,8 +152,8 @@ func TestQueryCondition(t *testing.T) {
ctx := setup()
t.Run("Should set Firing if eval match", func(t *testing.T) {
ctx.evaluator = `{"type": "no_value", "params": []}`
ctx.series = plugins.DataTimeSeriesSlice{
plugins.DataTimeSeries{Name: "test1", Points: newTimeSeriesPointsFromArgs()},
ctx.series = legacydata.DataTimeSeriesSlice{
legacydata.DataTimeSeries{Name: "test1", Points: newTimeSeriesPointsFromArgs()},
}
cr, err := ctx.exec(t)
@@ -162,9 +162,9 @@ func TestQueryCondition(t *testing.T) {
})
t.Run("Should set NoDataFound both series are empty", func(t *testing.T) {
ctx.series = plugins.DataTimeSeriesSlice{
plugins.DataTimeSeries{Name: "test1", Points: newTimeSeriesPointsFromArgs()},
plugins.DataTimeSeries{Name: "test2", Points: newTimeSeriesPointsFromArgs()},
ctx.series = legacydata.DataTimeSeriesSlice{
legacydata.DataTimeSeries{Name: "test1", Points: newTimeSeriesPointsFromArgs()},
legacydata.DataTimeSeries{Name: "test2", Points: newTimeSeriesPointsFromArgs()},
}
cr, err := ctx.exec(t)
@@ -173,9 +173,9 @@ func TestQueryCondition(t *testing.T) {
})
t.Run("Should set NoDataFound both series contains null", func(t *testing.T) {
ctx.series = plugins.DataTimeSeriesSlice{
plugins.DataTimeSeries{Name: "test1", Points: plugins.DataTimeSeriesPoints{plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(0)}}},
plugins.DataTimeSeries{Name: "test2", Points: plugins.DataTimeSeriesPoints{plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(0)}}},
ctx.series = legacydata.DataTimeSeriesSlice{
legacydata.DataTimeSeries{Name: "test1", Points: legacydata.DataTimeSeriesPoints{legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(0)}}},
legacydata.DataTimeSeries{Name: "test2", Points: legacydata.DataTimeSeriesPoints{legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(0)}}},
}
cr, err := ctx.exec(t)
@@ -184,9 +184,9 @@ func TestQueryCondition(t *testing.T) {
})
t.Run("Should not set NoDataFound if one series is empty", func(t *testing.T) {
ctx.series = plugins.DataTimeSeriesSlice{
plugins.DataTimeSeries{Name: "test1", Points: newTimeSeriesPointsFromArgs()},
plugins.DataTimeSeries{Name: "test2", Points: newTimeSeriesPointsFromArgs(120, 0)},
ctx.series = legacydata.DataTimeSeriesSlice{
legacydata.DataTimeSeries{Name: "test1", Points: newTimeSeriesPointsFromArgs()},
legacydata.DataTimeSeries{Name: "test2", Points: newTimeSeriesPointsFromArgs(120, 0)},
}
cr, err := ctx.exec(t)
@@ -199,13 +199,13 @@ func TestQueryCondition(t *testing.T) {
type queryConditionTestContext struct {
reducer string
evaluator string
series plugins.DataTimeSeriesSlice
series legacydata.DataTimeSeriesSlice
frame *data.Frame
result *alerting.EvalContext
condition *QueryCondition
}
//nolint: staticcheck // plugins.DataPlugin deprecated
//nolint: staticcheck // legacydata.DataPlugin deprecated
func (ctx *queryConditionTestContext) exec(t *testing.T) (*alerting.ConditionResult, error) {
jsonModel, err := simplejson.NewJson([]byte(`{
"type": "query",
@@ -224,18 +224,18 @@ func (ctx *queryConditionTestContext) exec(t *testing.T) (*alerting.ConditionRes
ctx.condition = condition
qr := plugins.DataQueryResult{
qr := legacydata.DataQueryResult{
Series: ctx.series,
}
if ctx.frame != nil {
qr = plugins.DataQueryResult{
Dataframes: plugins.NewDecodedDataFrames(data.Frames{ctx.frame}),
qr = legacydata.DataQueryResult{
Dataframes: legacydata.NewDecodedDataFrames(data.Frames{ctx.frame}),
}
}
reqHandler := fakeReqHandler{
response: plugins.DataResponse{
Results: map[string]plugins.DataQueryResult{
response: legacydata.DataResponse{
Results: map[string]legacydata.DataQueryResult{
"A": qr,
},
},
@@ -245,13 +245,13 @@ func (ctx *queryConditionTestContext) exec(t *testing.T) (*alerting.ConditionRes
}
type fakeReqHandler struct {
//nolint: staticcheck // plugins.DataPlugin deprecated
response plugins.DataResponse
//nolint: staticcheck // legacydata.DataPlugin deprecated
response legacydata.DataResponse
}
//nolint: staticcheck // plugins.DataPlugin deprecated
func (rh fakeReqHandler) HandleRequest(context.Context, *models.DataSource, plugins.DataQuery) (
plugins.DataResponse, error) {
//nolint: staticcheck // legacydata.DataPlugin deprecated
func (rh fakeReqHandler) HandleRequest(context.Context, *models.DataSource, legacydata.DataQuery) (
legacydata.DataResponse, error) {
return rh.response, nil
}
@@ -259,7 +259,7 @@ func TestFrameToSeriesSlice(t *testing.T) {
tests := []struct {
name string
frame *data.Frame
seriesSlice plugins.DataTimeSeriesSlice
seriesSlice legacydata.DataTimeSeriesSlice
Err require.ErrorAssertionFunc
}{
{
@@ -278,21 +278,21 @@ func TestFrameToSeriesSlice(t *testing.T) {
4.0,
})),
seriesSlice: plugins.DataTimeSeriesSlice{
plugins.DataTimeSeries{
seriesSlice: legacydata.DataTimeSeriesSlice{
legacydata.DataTimeSeries{
Name: "Values Int64s {Animal Factor=cat}",
Tags: map[string]string{"Animal Factor": "cat"},
Points: plugins.DataTimeSeriesPoints{
plugins.DataTimePoint{null.FloatFrom(math.NaN()), null.FloatFrom(1577934240000)},
plugins.DataTimePoint{null.FloatFrom(3), null.FloatFrom(1577934270000)},
Points: legacydata.DataTimeSeriesPoints{
legacydata.DataTimePoint{null.FloatFrom(math.NaN()), null.FloatFrom(1577934240000)},
legacydata.DataTimePoint{null.FloatFrom(3), null.FloatFrom(1577934270000)},
},
},
plugins.DataTimeSeries{
legacydata.DataTimeSeries{
Name: "Values Floats {Animal Factor=sloth}",
Tags: map[string]string{"Animal Factor": "sloth"},
Points: plugins.DataTimeSeriesPoints{
plugins.DataTimePoint{null.FloatFrom(2), null.FloatFrom(1577934240000)},
plugins.DataTimePoint{null.FloatFrom(4), null.FloatFrom(1577934270000)},
Points: legacydata.DataTimeSeriesPoints{
legacydata.DataTimePoint{null.FloatFrom(2), null.FloatFrom(1577934240000)},
legacydata.DataTimePoint{null.FloatFrom(4), null.FloatFrom(1577934270000)},
},
},
},
@@ -305,16 +305,16 @@ func TestFrameToSeriesSlice(t *testing.T) {
data.NewField(`Values Int64s`, data.Labels{"Animal Factor": "cat"}, []*int64{}),
data.NewField(`Values Floats`, data.Labels{"Animal Factor": "sloth"}, []float64{})),
seriesSlice: plugins.DataTimeSeriesSlice{
plugins.DataTimeSeries{
seriesSlice: legacydata.DataTimeSeriesSlice{
legacydata.DataTimeSeries{
Name: "Values Int64s {Animal Factor=cat}",
Tags: map[string]string{"Animal Factor": "cat"},
Points: plugins.DataTimeSeriesPoints{},
Points: legacydata.DataTimeSeriesPoints{},
},
plugins.DataTimeSeries{
legacydata.DataTimeSeries{
Name: "Values Floats {Animal Factor=sloth}",
Tags: map[string]string{"Animal Factor": "sloth"},
Points: plugins.DataTimeSeriesPoints{},
Points: legacydata.DataTimeSeriesPoints{},
},
},
Err: require.NoError,
@@ -325,10 +325,10 @@ func TestFrameToSeriesSlice(t *testing.T) {
data.NewField("Time", data.Labels{}, []time.Time{}),
data.NewField(`Values`, data.Labels{}, []float64{})),
seriesSlice: plugins.DataTimeSeriesSlice{
plugins.DataTimeSeries{
seriesSlice: legacydata.DataTimeSeriesSlice{
legacydata.DataTimeSeries{
Name: "Values",
Points: plugins.DataTimeSeriesPoints{},
Points: legacydata.DataTimeSeriesPoints{},
},
},
Err: require.NoError,
@@ -341,10 +341,10 @@ func TestFrameToSeriesSlice(t *testing.T) {
DisplayNameFromDS: "sloth",
})),
seriesSlice: plugins.DataTimeSeriesSlice{
plugins.DataTimeSeries{
seriesSlice: legacydata.DataTimeSeriesSlice{
legacydata.DataTimeSeries{
Name: "sloth",
Points: plugins.DataTimeSeriesPoints{},
Points: legacydata.DataTimeSeriesPoints{},
Tags: map[string]string{"Rating": "10"},
},
},
@@ -359,10 +359,10 @@ func TestFrameToSeriesSlice(t *testing.T) {
DisplayNameFromDS: "sloth #2",
})),
seriesSlice: plugins.DataTimeSeriesSlice{
plugins.DataTimeSeries{
seriesSlice: legacydata.DataTimeSeriesSlice{
legacydata.DataTimeSeries{
Name: "sloth #1",
Points: plugins.DataTimeSeriesPoints{},
Points: legacydata.DataTimeSeriesPoints{},
},
},
Err: require.NoError,
+3 -5
View File
@@ -6,7 +6,7 @@ import (
"sort"
"github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
)
// queryReducer reduces a timeseries to a nullable float
@@ -18,8 +18,7 @@ type queryReducer struct {
}
//nolint: gocyclo
//nolint: staticcheck // plugins.DataTimeSeries deprecated
func (s *queryReducer) Reduce(series plugins.DataTimeSeries) null.Float {
func (s *queryReducer) Reduce(series legacydata.DataTimeSeries) null.Float {
if len(series.Points) == 0 {
return null.FloatFromPtr(nil)
}
@@ -127,8 +126,7 @@ func newSimpleReducer(t string) *queryReducer {
return &queryReducer{Type: t}
}
//nolint: staticcheck // plugins.* deprecated
func calculateDiff(series plugins.DataTimeSeries, allNull bool, value float64, fn func(float64, float64) float64) (bool, float64) {
func calculateDiff(series legacydata.DataTimeSeries, allNull bool, value float64, fn func(float64, float64) float64) (bool, float64) {
var (
points = series.Points
first float64
@@ -5,7 +5,7 @@ import (
"testing"
"github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
"github.com/stretchr/testify/require"
)
@@ -52,16 +52,16 @@ func TestSimpleReducer(t *testing.T) {
t.Run("median should ignore null values", func(t *testing.T) {
reducer := newSimpleReducer("median")
series := plugins.DataTimeSeries{
series := legacydata.DataTimeSeries{
Name: "test time series",
}
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(1)})
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(2)})
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(3)})
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFrom(float64(1)), null.FloatFrom(4)})
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFrom(float64(2)), null.FloatFrom(5)})
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFrom(float64(3)), null.FloatFrom(6)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(1)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(2)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(3)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFrom(float64(1)), null.FloatFrom(4)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFrom(float64(2)), null.FloatFrom(5)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFrom(float64(3)), null.FloatFrom(6)})
result := reducer.Reduce(series)
require.Equal(t, true, result.Valid)
@@ -75,25 +75,25 @@ func TestSimpleReducer(t *testing.T) {
t.Run("avg with only nulls", func(t *testing.T) {
reducer := newSimpleReducer("avg")
series := plugins.DataTimeSeries{
series := legacydata.DataTimeSeries{
Name: "test time series",
}
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(1)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(1)})
require.Equal(t, false, reducer.Reduce(series).Valid)
})
t.Run("count_non_null", func(t *testing.T) {
t.Run("with null values and real values", func(t *testing.T) {
reducer := newSimpleReducer("count_non_null")
series := plugins.DataTimeSeries{
series := legacydata.DataTimeSeries{
Name: "test time series",
}
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(1)})
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(2)})
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFrom(3), null.FloatFrom(3)})
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFrom(3), null.FloatFrom(4)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(1)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(2)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFrom(3), null.FloatFrom(3)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFrom(3), null.FloatFrom(4)})
require.Equal(t, true, reducer.Reduce(series).Valid)
require.Equal(t, 2.0, reducer.Reduce(series).Float64)
@@ -101,12 +101,12 @@ func TestSimpleReducer(t *testing.T) {
t.Run("with null values", func(t *testing.T) {
reducer := newSimpleReducer("count_non_null")
series := plugins.DataTimeSeries{
series := legacydata.DataTimeSeries{
Name: "test time series",
}
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(1)})
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(2)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(1)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(2)})
require.Equal(t, false, reducer.Reduce(series).Valid)
})
@@ -114,14 +114,14 @@ func TestSimpleReducer(t *testing.T) {
t.Run("avg of number values and null values should ignore nulls", func(t *testing.T) {
reducer := newSimpleReducer("avg")
series := plugins.DataTimeSeries{
series := legacydata.DataTimeSeries{
Name: "test time series",
}
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFrom(3), null.FloatFrom(1)})
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(2)})
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(3)})
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFrom(3), null.FloatFrom(4)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFrom(3), null.FloatFrom(1)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(2)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(3)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFrom(3), null.FloatFrom(4)})
require.Equal(t, float64(3), reducer.Reduce(series).Float64)
})
@@ -179,12 +179,12 @@ func TestSimpleReducer(t *testing.T) {
t.Run("diff with only nulls", func(t *testing.T) {
reducer := newSimpleReducer("diff")
series := plugins.DataTimeSeries{
series := legacydata.DataTimeSeries{
Name: "test time series",
}
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(1)})
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(2)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(1)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(2)})
require.Equal(t, false, reducer.Reduce(series).Valid)
})
@@ -242,12 +242,12 @@ func TestSimpleReducer(t *testing.T) {
t.Run("diff_abs with only nulls", func(t *testing.T) {
reducer := newSimpleReducer("diff_abs")
series := plugins.DataTimeSeries{
series := legacydata.DataTimeSeries{
Name: "test time series",
}
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(1)})
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(2)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(1)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(2)})
require.Equal(t, false, reducer.Reduce(series).Valid)
})
@@ -305,12 +305,12 @@ func TestSimpleReducer(t *testing.T) {
t.Run("percent_diff with only nulls", func(t *testing.T) {
reducer := newSimpleReducer("percent_diff")
series := plugins.DataTimeSeries{
series := legacydata.DataTimeSeries{
Name: "test time series",
}
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(1)})
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(2)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(1)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(2)})
require.Equal(t, false, reducer.Reduce(series).Valid)
})
@@ -368,12 +368,12 @@ func TestSimpleReducer(t *testing.T) {
t.Run("percent_diff_abs with only nulls", func(t *testing.T) {
reducer := newSimpleReducer("percent_diff_abs")
series := plugins.DataTimeSeries{
series := legacydata.DataTimeSeries{
Name: "test time series",
}
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(1)})
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(2)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(1)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFromPtr(nil), null.FloatFrom(2)})
require.Equal(t, false, reducer.Reduce(series).Valid)
})
@@ -396,12 +396,12 @@ func TestSimpleReducer(t *testing.T) {
func testReducer(reducerType string, datapoints ...float64) float64 {
reducer := newSimpleReducer(reducerType)
series := plugins.DataTimeSeries{
series := legacydata.DataTimeSeries{
Name: "test time series",
}
for idx := range datapoints {
series.Points = append(series.Points, plugins.DataTimePoint{null.FloatFrom(datapoints[idx]), null.FloatFrom(1234134)})
series.Points = append(series.Points, legacydata.DataTimePoint{null.FloatFrom(datapoints[idx]), null.FloatFrom(1234134)})
}
return reducer.Reduce(series).Float64
+3 -3
View File
@@ -11,10 +11,10 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/encryption"
"github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
tlog "github.com/opentracing/opentracing-go/log"
@@ -28,7 +28,7 @@ type AlertEngine struct {
RenderService rendering.Service
Bus bus.Bus
RequestValidator models.PluginRequestValidator
DataService plugins.DataRequestHandler
DataService legacydata.RequestHandler
Cfg *setting.Cfg
execQueue chan *Job
@@ -48,7 +48,7 @@ func (e *AlertEngine) IsDisabled() bool {
// ProvideAlertEngine returns a new AlertEngine.
func ProvideAlertEngine(renderer rendering.Service, bus bus.Bus, requestValidator models.PluginRequestValidator,
dataService plugins.DataRequestHandler, usageStatsService usagestats.Service, encryptionService encryption.Service,
dataService legacydata.RequestHandler, usageStatsService usagestats.Service, encryptionService encryption.Service,
cfg *setting.Cfg) *AlertEngine {
e := &AlertEngine{
Cfg: cfg,
+3 -3
View File
@@ -7,18 +7,18 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
)
// DefaultEvalHandler is responsible for evaluating the alert rule.
type DefaultEvalHandler struct {
log log.Logger
alertJobTimeout time.Duration
requestHandler plugins.DataRequestHandler
requestHandler legacydata.RequestHandler
}
// NewEvalHandler is the `DefaultEvalHandler` constructor.
func NewEvalHandler(requestHandler plugins.DataRequestHandler) *DefaultEvalHandler {
func NewEvalHandler(requestHandler legacydata.RequestHandler) *DefaultEvalHandler {
return &DefaultEvalHandler{
log: log.New("alerting.evalHandler"),
alertJobTimeout: time.Second * 5,
+2 -2
View File
@@ -4,8 +4,8 @@ import (
"context"
"testing"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/validations"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
"github.com/stretchr/testify/require"
)
@@ -17,7 +17,7 @@ type conditionStub struct {
noData bool
}
func (c *conditionStub) Eval(context *EvalContext, reqHandler plugins.DataRequestHandler) (*ConditionResult, error) {
func (c *conditionStub) Eval(context *EvalContext, reqHandler legacydata.RequestHandler) (*ConditionResult, error) {
return &ConditionResult{Firing: c.firing, EvalMatches: c.matches, Operator: c.operator, NoDataFound: c.noData}, nil
}
+2 -2
View File
@@ -5,7 +5,7 @@ import (
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
)
type evalHandler interface {
@@ -60,5 +60,5 @@ type ConditionResult struct {
// Condition is responsible for evaluating an alert condition.
type Condition interface {
Eval(result *EvalContext, requestHandler plugins.DataRequestHandler) (*ConditionResult, error)
Eval(result *EvalContext, requestHandler legacydata.RequestHandler) (*ConditionResult, error)
}
+2 -2
View File
@@ -8,15 +8,15 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type FakeCondition struct{}
func (f *FakeCondition) Eval(context *EvalContext, reqHandler plugins.DataRequestHandler) (*ConditionResult, error) {
func (f *FakeCondition) Eval(context *EvalContext, reqHandler legacydata.RequestHandler) (*ConditionResult, error) {
return &ConditionResult{}, nil
}
+7 -7
View File
@@ -6,6 +6,7 @@ import (
"time"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/expr"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/datasourceproxy"
"github.com/grafana/grafana/pkg/services/datasources"
@@ -18,7 +19,6 @@ import (
"github.com/grafana/grafana/pkg/services/quota"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb"
)
// timeNow makes it possible to test usage of time
@@ -54,7 +54,7 @@ type API struct {
Cfg *setting.Cfg
DatasourceCache datasources.CacheService
RouteRegister routing.RouteRegister
DataService *tsdb.Service
ExpressionService *expr.Service
QuotaService *quota.QuotaService
Schedule schedule.ScheduleService
RuleStore store.RuleStore
@@ -93,11 +93,11 @@ func (api *API) RegisterAPIEndpoints(m *metrics.API) {
RulerSrv{DatasourceCache: api.DatasourceCache, QuotaService: api.QuotaService, manager: api.StateManager, store: api.RuleStore, log: logger},
), m)
api.RegisterTestingApiEndpoints(TestingApiSrv{
AlertingProxy: proxy,
Cfg: api.Cfg,
DataService: api.DataService,
DatasourceCache: api.DatasourceCache,
log: logger,
AlertingProxy: proxy,
Cfg: api.Cfg,
ExpressionService: api.ExpressionService,
DatasourceCache: api.DatasourceCache,
log: logger,
}, m)
api.RegisterConfigurationApiEndpoints(AdminSrv{
store: api.AdminConfigStore,
+7 -7
View File
@@ -8,22 +8,22 @@ import (
"strconv"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/expr"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/services/ngalert/eval"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb"
"github.com/grafana/grafana/pkg/web"
)
type TestingApiSrv struct {
*AlertingProxy
Cfg *setting.Cfg
DataService *tsdb.Service
DatasourceCache datasources.CacheService
log log.Logger
Cfg *setting.Cfg
ExpressionService *expr.Service
DatasourceCache datasources.CacheService
log log.Logger
}
func (srv TestingApiSrv) RouteTestRuleConfig(c *models.ReqContext, body apimodels.TestRulePayload) response.Response {
@@ -32,7 +32,7 @@ func (srv TestingApiSrv) RouteTestRuleConfig(c *models.ReqContext, body apimodel
if body.Type() != apimodels.GrafanaBackend || body.GrafanaManagedCondition == nil {
return ErrResp(http.StatusBadRequest, errors.New("unexpected payload"), "")
}
return conditionEval(c, *body.GrafanaManagedCondition, srv.DatasourceCache, srv.DataService, srv.Cfg, srv.log)
return conditionEval(c, *body.GrafanaManagedCondition, srv.DatasourceCache, srv.ExpressionService, srv.Cfg, srv.log)
}
if body.Type() != apimodels.LoTexRulerBackend {
@@ -86,7 +86,7 @@ func (srv TestingApiSrv) RouteEvalQueries(c *models.ReqContext, cmd apimodels.Ev
}
evaluator := eval.Evaluator{Cfg: srv.Cfg, Log: srv.log}
evalResults, err := evaluator.QueriesAndExpressionsEval(c.SignedInUser.OrgId, cmd.Data, now, srv.DataService)
evalResults, err := evaluator.QueriesAndExpressionsEval(c.SignedInUser.OrgId, cmd.Data, now, srv.ExpressionService)
if err != nil {
return ErrResp(http.StatusBadRequest, err, "Failed to evaluate queries and expressions")
}
+3 -3
View File
@@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/expr"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasourceproxy"
@@ -21,7 +22,6 @@ import (
"github.com/grafana/grafana/pkg/services/ngalert/eval"
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
"github.com/pkg/errors"
@@ -223,7 +223,7 @@ func validateQueriesAndExpressions(data []ngmodels.AlertQuery, user *models.Sign
return refIDs, nil
}
func conditionEval(c *models.ReqContext, cmd ngmodels.EvalAlertConditionCommand, datasourceCache datasources.CacheService, dataService *tsdb.Service, cfg *setting.Cfg, log log.Logger) response.Response {
func conditionEval(c *models.ReqContext, cmd ngmodels.EvalAlertConditionCommand, datasourceCache datasources.CacheService, expressionService *expr.Service, cfg *setting.Cfg, log log.Logger) response.Response {
evalCond := ngmodels.Condition{
Condition: cmd.Condition,
OrgID: c.SignedInUser.OrgId,
@@ -239,7 +239,7 @@ func conditionEval(c *models.ReqContext, cmd ngmodels.EvalAlertConditionCommand,
}
evaluator := eval.Evaluator{Cfg: cfg, Log: log}
evalResults, err := evaluator.ConditionEval(&evalCond, now, dataService)
evalResults, err := evaluator.ConditionEval(&evalCond, now, expressionService)
if err != nil {
return ErrResp(http.StatusBadRequest, err, "Failed to evaluate conditions")
}
+7 -12
View File
@@ -14,7 +14,6 @@ import (
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/data"
@@ -165,10 +164,10 @@ type NumberValueCapture struct {
Value *float64
}
func executeCondition(ctx AlertExecCtx, c *models.Condition, now time.Time, dataService *tsdb.Service) ExecutionResults {
func executeCondition(ctx AlertExecCtx, c *models.Condition, now time.Time, exprService *expr.Service) ExecutionResults {
result := ExecutionResults{}
execResp, err := executeQueriesAndExpressions(ctx, c.Data, now, dataService)
execResp, err := executeQueriesAndExpressions(ctx, c.Data, now, exprService)
if err != nil {
return ExecutionResults{Error: err}
@@ -232,7 +231,7 @@ func executeCondition(ctx AlertExecCtx, c *models.Condition, now time.Time, data
return result
}
func executeQueriesAndExpressions(ctx AlertExecCtx, data []models.AlertQuery, now time.Time, dataService *tsdb.Service) (resp *backend.QueryDataResponse, err error) {
func executeQueriesAndExpressions(ctx AlertExecCtx, data []models.AlertQuery, now time.Time, exprService *expr.Service) (resp *backend.QueryDataResponse, err error) {
defer func() {
if e := recover(); e != nil {
ctx.Log.Error("alert rule panic", "error", e, "stack", string(debug.Stack()))
@@ -250,10 +249,6 @@ func executeQueriesAndExpressions(ctx AlertExecCtx, data []models.AlertQuery, no
return nil, err
}
exprService := expr.Service{
Cfg: &setting.Cfg{ExpressionsEnabled: ctx.ExpressionsEnabled},
DataService: dataService,
}
return exprService.TransformData(ctx.Ctx, queryDataReq)
}
@@ -431,26 +426,26 @@ func (evalResults Results) AsDataFrame() data.Frame {
}
// ConditionEval executes conditions and evaluates the result.
func (e *Evaluator) ConditionEval(condition *models.Condition, now time.Time, dataService *tsdb.Service) (Results, error) {
func (e *Evaluator) ConditionEval(condition *models.Condition, now time.Time, expressionService *expr.Service) (Results, error) {
alertCtx, cancelFn := context.WithTimeout(context.Background(), e.Cfg.UnifiedAlerting.EvaluationTimeout)
defer cancelFn()
alertExecCtx := AlertExecCtx{OrgID: condition.OrgID, Ctx: alertCtx, ExpressionsEnabled: e.Cfg.ExpressionsEnabled, Log: e.Log}
execResult := executeCondition(alertExecCtx, condition, now, dataService)
execResult := executeCondition(alertExecCtx, condition, now, expressionService)
evalResults := evaluateExecutionResult(execResult, now)
return evalResults, nil
}
// QueriesAndExpressionsEval executes queries and expressions and returns the result.
func (e *Evaluator) QueriesAndExpressionsEval(orgID int64, data []models.AlertQuery, now time.Time, dataService *tsdb.Service) (*backend.QueryDataResponse, error) {
func (e *Evaluator) QueriesAndExpressionsEval(orgID int64, data []models.AlertQuery, now time.Time, expressionService *expr.Service) (*backend.QueryDataResponse, error) {
alertCtx, cancelFn := context.WithTimeout(context.Background(), e.Cfg.UnifiedAlerting.EvaluationTimeout)
defer cancelFn()
alertExecCtx := AlertExecCtx{OrgID: orgID, Ctx: alertCtx, ExpressionsEnabled: e.Cfg.ExpressionsEnabled, Log: e.Log}
execResult, err := executeQueriesAndExpressions(alertExecCtx, data, now, dataService)
execResult, err := executeQueriesAndExpressions(alertExecCtx, data, now, expressionService)
if err != nil {
return nil, fmt.Errorf("failed to execute conditions: %w", err)
}
+28 -28
View File
@@ -7,6 +7,7 @@ import (
"github.com/benbjohnson/clock"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/expr"
"github.com/grafana/grafana/pkg/infra/kvstore"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/datasourceproxy"
@@ -22,7 +23,6 @@ import (
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb"
"golang.org/x/sync/errgroup"
)
@@ -38,20 +38,20 @@ const (
)
func ProvideService(cfg *setting.Cfg, dataSourceCache datasources.CacheService, routeRegister routing.RouteRegister,
sqlStore *sqlstore.SQLStore, kvStore kvstore.KVStore, dataService *tsdb.Service, dataProxy *datasourceproxy.DataSourceProxyService,
sqlStore *sqlstore.SQLStore, kvStore kvstore.KVStore, expressionService *expr.Service, dataProxy *datasourceproxy.DataSourceProxyService,
quotaService *quota.QuotaService, secretsService secrets.Service, m *metrics.NGAlert) (*AlertNG, error) {
ng := &AlertNG{
Cfg: cfg,
DataSourceCache: dataSourceCache,
RouteRegister: routeRegister,
SQLStore: sqlStore,
KVStore: kvStore,
DataService: dataService,
DataProxy: dataProxy,
QuotaService: quotaService,
SecretsService: secretsService,
Metrics: m,
Log: log.New("ngalert"),
Cfg: cfg,
DataSourceCache: dataSourceCache,
RouteRegister: routeRegister,
SQLStore: sqlStore,
KVStore: kvStore,
ExpressionService: expressionService,
DataProxy: dataProxy,
QuotaService: quotaService,
SecretsService: secretsService,
Metrics: m,
Log: log.New("ngalert"),
}
if ng.IsDisabled() {
@@ -67,19 +67,19 @@ func ProvideService(cfg *setting.Cfg, dataSourceCache datasources.CacheService,
// AlertNG is the service for evaluating the condition of an alert definition.
type AlertNG struct {
Cfg *setting.Cfg
DataSourceCache datasources.CacheService
RouteRegister routing.RouteRegister
SQLStore *sqlstore.SQLStore
KVStore kvstore.KVStore
DataService *tsdb.Service
DataProxy *datasourceproxy.DataSourceProxyService
QuotaService *quota.QuotaService
SecretsService secrets.Service
Metrics *metrics.NGAlert
Log log.Logger
schedule schedule.ScheduleService
stateManager *state.Manager
Cfg *setting.Cfg
DataSourceCache datasources.CacheService
RouteRegister routing.RouteRegister
SQLStore *sqlstore.SQLStore
KVStore kvstore.KVStore
ExpressionService *expr.Service
DataProxy *datasourceproxy.DataSourceProxyService
QuotaService *quota.QuotaService
SecretsService secrets.Service
Metrics *metrics.NGAlert
Log log.Logger
schedule schedule.ScheduleService
stateManager *state.Manager
// Alerting notification services
MultiOrgAlertmanager *notifier.MultiOrgAlertmanager
@@ -136,7 +136,7 @@ func (ng *AlertNG) init() error {
appUrl = nil
}
stateManager := state.NewManager(ng.Log, ng.Metrics.GetStateMetrics(), appUrl, store, store)
scheduler := schedule.NewScheduler(schedCfg, ng.DataService, appUrl, stateManager)
scheduler := schedule.NewScheduler(schedCfg, ng.ExpressionService, appUrl, stateManager)
ng.stateManager = stateManager
ng.schedule = scheduler
@@ -145,7 +145,7 @@ func (ng *AlertNG) init() error {
Cfg: ng.Cfg,
DatasourceCache: ng.DataSourceCache,
RouteRegister: ng.RouteRegister,
DataService: ng.DataService,
ExpressionService: ng.ExpressionService,
Schedule: ng.schedule,
DataProxy: ng.DataProxy,
QuotaService: ng.QuotaService,
+9 -9
View File
@@ -8,6 +8,7 @@ import (
"sync"
"time"
"github.com/grafana/grafana/pkg/expr"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/ngalert/eval"
@@ -17,7 +18,6 @@ import (
"github.com/grafana/grafana/pkg/services/ngalert/sender"
"github.com/grafana/grafana/pkg/services/ngalert/state"
"github.com/grafana/grafana/pkg/services/ngalert/store"
"github.com/grafana/grafana/pkg/tsdb"
"github.com/benbjohnson/clock"
"golang.org/x/sync/errgroup"
@@ -64,11 +64,11 @@ type schedule struct {
evaluator eval.Evaluator
ruleStore store.RuleStore
instanceStore store.InstanceStore
adminConfigStore store.AdminConfigurationStore
orgStore store.OrgStore
dataService *tsdb.Service
ruleStore store.RuleStore
instanceStore store.InstanceStore
adminConfigStore store.AdminConfigurationStore
orgStore store.OrgStore
expressionService *expr.Service
stateManager *state.Manager
@@ -107,7 +107,7 @@ type SchedulerCfg struct {
}
// NewScheduler returns a new schedule.
func NewScheduler(cfg SchedulerCfg, dataService *tsdb.Service, appURL *url.URL, stateManager *state.Manager) *schedule {
func NewScheduler(cfg SchedulerCfg, expressionService *expr.Service, appURL *url.URL, stateManager *state.Manager) *schedule {
ticker := alerting.NewTicker(cfg.C.Now(), time.Second*0, cfg.C, int64(cfg.BaseInterval.Seconds()))
sch := schedule{
@@ -123,7 +123,7 @@ func NewScheduler(cfg SchedulerCfg, dataService *tsdb.Service, appURL *url.URL,
ruleStore: cfg.RuleStore,
instanceStore: cfg.InstanceStore,
orgStore: cfg.OrgStore,
dataService: dataService,
expressionService: expressionService,
adminConfigStore: cfg.AdminConfigStore,
multiOrgNotifier: cfg.MultiOrgNotifier,
metrics: cfg.Metrics,
@@ -449,7 +449,7 @@ func (sch *schedule) ruleRoutine(grafanaCtx context.Context, key models.AlertRul
OrgID: alertRule.OrgID,
Data: alertRule.Data,
}
results, err := sch.evaluator.ConditionEval(&condition, ctx.now, sch.dataService)
results, err := sch.evaluator.ConditionEval(&condition, ctx.now, sch.expressionService)
dur := sch.clock.Now().Sub(start)
evalTotal.Inc()
evalDuration.Observe(dur.Seconds())
@@ -17,6 +17,7 @@ import (
"github.com/prometheus/common/model"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/expr"
"github.com/grafana/grafana/pkg/infra/log"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/services/ngalert/eval"
@@ -604,7 +605,7 @@ func setupScheduler(t *testing.T, rs store.RuleStore, is store.InstanceStore, ac
Scheme: "http",
Host: "localhost",
}
return NewScheduler(schedCfg, nil, appUrl, st), mockedClock
return NewScheduler(schedCfg, expr.ProvideService(&setting.Cfg{ExpressionsEnabled: true}, nil, nil), appUrl, st), mockedClock
}
// createTestAlertRule creates a dummy alert definition to be used by the tests.