mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
refactor(alerting): remove transformation that is now done by the querier (#93660)
This commit is contained in:
parent
314f770a71
commit
bfc6c032c4
@ -22,7 +22,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/datasources"
|
"github.com/grafana/grafana/pkg/services/datasources"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var logger = log.New("ngalert.eval")
|
var logger = log.New("ngalert.eval")
|
||||||
@ -705,13 +704,6 @@ func evaluateExecutionResult(execResults ExecutionResults, ts time.Time) Results
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// The query service returns instant vectors from prometheus as scalars. We need to handle them accordingly.
|
|
||||||
if val, ok := scalarInstantVector(f); ok {
|
|
||||||
r := buildResult(f, val, ts)
|
|
||||||
evalResults = append(evalResults, r)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(f.TypeIndices(data.FieldTypeTime, data.FieldTypeNullableTime)) > 0 {
|
if len(f.TypeIndices(data.FieldTypeTime, data.FieldTypeNullableTime)) > 0 {
|
||||||
appendErrRes(&invalidEvalResultFormatError{refID: f.RefID, reason: "looks like time series data, only reduced data can be alerted on."})
|
appendErrRes(&invalidEvalResultFormatError{refID: f.RefID, reason: "looks like time series data, only reduced data can be alerted on."})
|
||||||
continue
|
continue
|
||||||
@ -789,23 +781,6 @@ func buildResult(f *data.Frame, val *float64, ts time.Time) Result {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func scalarInstantVector(f *data.Frame) (*float64, bool) {
|
|
||||||
if len(f.Fields) != 2 {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
if f.Fields[0].Len() > 1 || (f.Fields[0].Type() != data.FieldTypeNullableTime && f.Fields[0].Type() != data.FieldTypeTime) {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
switch f.Fields[1].Type() {
|
|
||||||
case data.FieldTypeFloat64:
|
|
||||||
return util.Pointer(f.Fields[1].At(0).(float64)), true
|
|
||||||
case data.FieldTypeNullableFloat64:
|
|
||||||
return f.Fields[1].At(0).(*float64), true
|
|
||||||
default:
|
|
||||||
return nil, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AsDataFrame forms the EvalResults in Frame suitable for displaying in the table panel of the front end.
|
// AsDataFrame forms the EvalResults in Frame suitable for displaying in the table panel of the front end.
|
||||||
// It displays one row per alert instance, with a column for each label and one for the alerting state.
|
// It displays one row per alert instance, with a column for each label and one for the alerting state.
|
||||||
func (evalResults Results) AsDataFrame() data.Frame {
|
func (evalResults Results) AsDataFrame() data.Frame {
|
||||||
|
@ -2,7 +2,6 @@ package eval
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
@ -63,52 +62,6 @@ func TestEvaluateExecutionResult(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
desc: "query service dataframe works as instant vector",
|
|
||||||
execResults: ExecutionResults{
|
|
||||||
Condition: func() []*data.Frame {
|
|
||||||
f := data.NewFrame("",
|
|
||||||
data.NewField("", nil, []*time.Time{util.Pointer(time.Now())}),
|
|
||||||
data.NewField("", nil, []*float64{util.Pointer(0.0)}),
|
|
||||||
)
|
|
||||||
f.Meta = &data.FrameMeta{
|
|
||||||
Custom: map[string]any{
|
|
||||||
"resultType": "scalar",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return []*data.Frame{f}
|
|
||||||
}(),
|
|
||||||
},
|
|
||||||
expectResultLength: 1,
|
|
||||||
expectResults: Results{
|
|
||||||
{
|
|
||||||
State: Normal,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "query service dataframe works as instant vector when alerting",
|
|
||||||
execResults: ExecutionResults{
|
|
||||||
Condition: func() []*data.Frame {
|
|
||||||
f := data.NewFrame("",
|
|
||||||
data.NewField("", nil, []*time.Time{util.Pointer(time.Now())}),
|
|
||||||
data.NewField("", nil, []*float64{util.Pointer(1.0)}),
|
|
||||||
)
|
|
||||||
f.Meta = &data.FrameMeta{
|
|
||||||
Custom: map[string]any{
|
|
||||||
"resultType": "scalar",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return []*data.Frame{f}
|
|
||||||
}(),
|
|
||||||
},
|
|
||||||
expectResultLength: 1,
|
|
||||||
expectResults: Results{
|
|
||||||
{
|
|
||||||
State: Alerting,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
desc: "nil value single instance is single a NoData state result",
|
desc: "nil value single instance is single a NoData state result",
|
||||||
execResults: ExecutionResults{
|
execResults: ExecutionResults{
|
||||||
@ -1343,76 +1296,6 @@ func TestCreate(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQueryServiceResponse(t *testing.T) {
|
|
||||||
data := `
|
|
||||||
{
|
|
||||||
"results": {
|
|
||||||
"A": {
|
|
||||||
"status": 200,
|
|
||||||
"frames": [
|
|
||||||
{
|
|
||||||
"schema": {
|
|
||||||
"refId": "A",
|
|
||||||
"meta": {
|
|
||||||
"type": "numeric-multi",
|
|
||||||
"typeVersion": [
|
|
||||||
0,
|
|
||||||
1
|
|
||||||
],
|
|
||||||
"custom": {
|
|
||||||
"resultType": "scalar"
|
|
||||||
},
|
|
||||||
"executedQueryString": "Expr: 1\nStep: 15s"
|
|
||||||
},
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "Time",
|
|
||||||
"type": "time",
|
|
||||||
"typeInfo": {
|
|
||||||
"frame": "time.Time"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"interval": 15000
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Value",
|
|
||||||
"type": "number",
|
|
||||||
"typeInfo": {
|
|
||||||
"frame": "float64"
|
|
||||||
},
|
|
||||||
"labels": {},
|
|
||||||
"config": {
|
|
||||||
"displayNameFromDS": "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"data": {
|
|
||||||
"values": [
|
|
||||||
[
|
|
||||||
1719855251019
|
|
||||||
],
|
|
||||||
[
|
|
||||||
1
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
var s backend.QueryDataResponse
|
|
||||||
err := json.Unmarshal([]byte(data), &s)
|
|
||||||
require.NoError(t, err)
|
|
||||||
res := EvaluateAlert(&s, models.Condition{Condition: "A"}, time.Time{})
|
|
||||||
|
|
||||||
require.Equal(t, 1, len(res))
|
|
||||||
require.Equal(t, Alerting, res[0].State)
|
|
||||||
}
|
|
||||||
|
|
||||||
type fakeExpressionService struct {
|
type fakeExpressionService struct {
|
||||||
hook func(ctx context.Context, now time.Time, pipeline expr.DataPipeline) (*backend.QueryDataResponse, error)
|
hook func(ctx context.Context, now time.Time, pipeline expr.DataPipeline) (*backend.QueryDataResponse, error)
|
||||||
buildHook func(req *expr.Request) (expr.DataPipeline, error)
|
buildHook func(req *expr.Request) (expr.DataPipeline, error)
|
||||||
|
Loading…
Reference in New Issue
Block a user