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:
@@ -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,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user