mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Optimize external Loki queries (#73014)
This commit is contained in:
parent
8d79d45972
commit
2c6cf66741
@ -3,14 +3,21 @@ package store
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/grafana/grafana/pkg/expr"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
)
|
||||
|
||||
const (
|
||||
grafanaCloudLogs = "grafanacloud-logs"
|
||||
grafanaCloudUsageInsights = "grafanacloud-usage-insights"
|
||||
grafanaCloudStateHistory = "grafanacloud-loki-alert-state-history"
|
||||
)
|
||||
// DSType can be used to check the datasource type if it's set in the model.
|
||||
type dsType struct {
|
||||
DS struct {
|
||||
Type string `json:"type"`
|
||||
} `json:"datasource"`
|
||||
}
|
||||
|
||||
func (t dsType) isLoki() bool {
|
||||
return t.DS.Type == datasources.DS_LOKI
|
||||
}
|
||||
|
||||
func canBeInstant(r *models.AlertRule) bool {
|
||||
if len(r.Data) < 2 {
|
||||
@ -20,20 +27,25 @@ func canBeInstant(r *models.AlertRule) bool {
|
||||
if r.Data[0].QueryType != "range" {
|
||||
return false
|
||||
}
|
||||
// First query part should go to cloud logs or insights.
|
||||
if r.Data[0].DatasourceUID != grafanaCloudLogs &&
|
||||
r.Data[0].DatasourceUID != grafanaCloudUsageInsights &&
|
||||
r.Data[0].DatasourceUID != grafanaCloudStateHistory {
|
||||
return false
|
||||
}
|
||||
// Second query part should be and expression, '-100' is the legacy way to define it.
|
||||
if r.Data[1].DatasourceUID != "__expr__" && r.Data[1].DatasourceUID != "-100" {
|
||||
|
||||
var t dsType
|
||||
// We can ignore the error here, the query just won't be optimized.
|
||||
_ = json.Unmarshal(r.Data[0].Model, &t)
|
||||
|
||||
if !t.isLoki() {
|
||||
return false
|
||||
}
|
||||
|
||||
exprRaw := make(map[string]interface{})
|
||||
if err := json.Unmarshal(r.Data[1].Model, &exprRaw); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// Second query part should be and expression.
|
||||
if !expr.IsDataSource(r.Data[1].DatasourceUID) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Second query part should be "last()"
|
||||
if val, ok := exprRaw["reducer"].(string); !ok || val != "last" {
|
||||
return false
|
||||
|
@ -4,8 +4,9 @@ import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
)
|
||||
|
||||
func TestCanBeInstant(t *testing.T) {
|
||||
@ -19,6 +20,13 @@ func TestCanBeInstant(t *testing.T) {
|
||||
expected: true,
|
||||
rule: createMigrateableLokiRule(t),
|
||||
},
|
||||
{
|
||||
name: "valid rule with external loki datasource",
|
||||
expected: true,
|
||||
rule: createMigrateableLokiRule(t, func(r *models.AlertRule) {
|
||||
r.Data[0].DatasourceUID = "something-external"
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "invalid rule where the data array is too short to be migrateable",
|
||||
expected: false,
|
||||
@ -33,20 +41,6 @@ func TestCanBeInstant(t *testing.T) {
|
||||
r.Data[0].QueryType = "something-else"
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "invalid rule that does not use a cloud datasource",
|
||||
expected: false,
|
||||
rule: createMigrateableLokiRule(t, func(r *models.AlertRule) {
|
||||
r.Data[0].DatasourceUID = "something-else"
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "invalid rule that has no aggregation as second item",
|
||||
expected: false,
|
||||
rule: createMigrateableLokiRule(t, func(r *models.AlertRule) {
|
||||
r.Data[1].DatasourceUID = "something-else"
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "invalid rule that has not last() as aggregation",
|
||||
expected: false,
|
||||
@ -59,6 +53,13 @@ func TestCanBeInstant(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "invalid rule that has no aggregation as second item",
|
||||
expected: false,
|
||||
rule: createMigrateableLokiRule(t, func(r *models.AlertRule) {
|
||||
r.Data[1].DatasourceUID = "something-else"
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "invalid rule that has not last() pointing to range query",
|
||||
expected: false,
|
||||
@ -120,7 +121,7 @@ func createMigrateableLokiRule(t *testing.T, muts ...func(*models.AlertRule)) *m
|
||||
{
|
||||
RefID: "A",
|
||||
QueryType: "range",
|
||||
DatasourceUID: grafanaCloudLogs,
|
||||
DatasourceUID: "grafanacloud-logs",
|
||||
Model: []byte(`{
|
||||
"datasource": {
|
||||
"type": "loki",
|
||||
|
Loading…
Reference in New Issue
Block a user