mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 22:32:24 +08:00
SQL Expressions: Make SQL Expressions work with Alerting (#101820)
Initial support for alerting with SQL expressions - When `format` is set to `alerting`, SQL expressions output in a format suitable for alerting evaluation. - Outstanding TODOs: - Deduplicate output rows - Add more tests - Fix broken alerting UI rendering (likely due to shape change to undocumented full-long format) - Basic usage: - SQL must return one numeric column and one or more string columns. - Each row may become an alert. - The alert fires if the numeric value is non-zero. - String columns are treated as labels. --------- Co-authored-by: Konrad Lalik <konradlalik@gmail.com> Co-authored-by: Tom Ratcliffe <tom.ratcliffe@grafana.com> Co-authored-by: Sam Jewell <sam.jewell@grafana.com>
This commit is contained in:
80
pkg/expr/sql_command_alert_test.go
Normal file
80
pkg/expr/sql_command_alert_test.go
Normal file
@ -0,0 +1,80 @@
|
||||
package expr
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestExtractNumberSetFromSQLForAlerting(t *testing.T) {
|
||||
t.Run("SingleRowNoLabels", func(t *testing.T) {
|
||||
input := data.NewFrame("",
|
||||
data.NewField(SQLMetricFieldName, nil, []string{"cpu"}), // will be treated as a label
|
||||
data.NewField(SQLValueFieldName, nil, []*float64{fp(3.14)}),
|
||||
)
|
||||
|
||||
numbers, err := extractNumberSetFromSQLForAlerting(input)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, numbers, 1)
|
||||
|
||||
got := numbers[0]
|
||||
require.Equal(t, fp(3.14), got.GetFloat64Value())
|
||||
require.Equal(t, data.Labels{
|
||||
SQLMetricFieldName: "cpu",
|
||||
}, got.GetLabels())
|
||||
})
|
||||
|
||||
t.Run("TwoRowsWithLabelsAndDisplay", func(t *testing.T) {
|
||||
input := data.NewFrame("",
|
||||
data.NewField(SQLMetricFieldName, nil, []string{"cpu", "cpu"}),
|
||||
data.NewField(SQLValueFieldName, nil, []*float64{fp(1.0), fp(2.0)}),
|
||||
data.NewField(SQLDisplayFieldName, nil, []*string{sp("CPU A"), sp("CPU A")}),
|
||||
data.NewField("host", nil, []*string{sp("a"), sp("a")}),
|
||||
)
|
||||
|
||||
numbers, err := extractNumberSetFromSQLForAlerting(input)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, numbers, 2)
|
||||
|
||||
require.Equal(t, fp(1.0), numbers[0].GetFloat64Value())
|
||||
require.Equal(t, data.Labels{
|
||||
SQLMetricFieldName: "cpu",
|
||||
SQLDisplayFieldName: "CPU A",
|
||||
"host": "a",
|
||||
}, numbers[0].GetLabels())
|
||||
|
||||
require.Equal(t, fp(2.0), numbers[1].GetFloat64Value())
|
||||
require.Equal(t, data.Labels{
|
||||
SQLMetricFieldName: "cpu",
|
||||
SQLDisplayFieldName: "CPU A",
|
||||
"host": "a",
|
||||
}, numbers[1].GetLabels())
|
||||
})
|
||||
|
||||
t.Run("TwoFieldsWithSparseLabels", func(t *testing.T) {
|
||||
input := data.NewFrame("",
|
||||
data.NewField(SQLMetricFieldName, nil, []string{"cpu", "cpu"}),
|
||||
data.NewField(SQLValueFieldName, nil, []*float64{fp(1.0), fp(2.0)}),
|
||||
data.NewField("env", nil, []*string{nil, sp("prod")}),
|
||||
data.NewField("host", nil, []*string{sp("a"), sp("b")}),
|
||||
)
|
||||
|
||||
numbers, err := extractNumberSetFromSQLForAlerting(input)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, numbers, 2)
|
||||
|
||||
require.Equal(t, fp(1.0), numbers[0].GetFloat64Value())
|
||||
require.Equal(t, data.Labels{
|
||||
SQLMetricFieldName: "cpu",
|
||||
"host": "a",
|
||||
}, numbers[0].GetLabels())
|
||||
|
||||
require.Equal(t, fp(2.0), numbers[1].GetFloat64Value())
|
||||
require.Equal(t, data.Labels{
|
||||
SQLMetricFieldName: "cpu",
|
||||
"host": "b",
|
||||
"env": "prod",
|
||||
}, numbers[1].GetLabels())
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user