Alerting: Add compact model for alert rules
This commit is contained in:
@@ -10,11 +10,38 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// We only care about the data source UIDs.
|
||||||
|
type compactQuery struct {
|
||||||
|
DatasourceUID string `json:"datasourceUid"`
|
||||||
|
}
|
||||||
|
|
||||||
func alertRuleToModelsAlertRule(ar alertRule, l log.Logger) (models.AlertRule, error) {
|
func alertRuleToModelsAlertRule(ar alertRule, l log.Logger) (models.AlertRule, error) {
|
||||||
|
return transformRule(ar, l, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// alertRuleToModelsAlertRuleCompact transforms an alertRule to a models.AlertRule
|
||||||
|
// ignoring alert queries (except for data source UIDs), notification settings, and metadata.
|
||||||
|
func alertRuleToModelsAlertRuleCompact(ar alertRule, l log.Logger) (models.AlertRule, error) {
|
||||||
|
return transformRule(ar, l, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// transformRule creates a models.AlertRule from an alertRule.
|
||||||
|
// When 'compact' is set to 'true', it skips parsing the alert queries (except for the data source UID), notification
|
||||||
|
// settings, and metadata, thus reducing the number of JSON serializations needed.
|
||||||
|
func transformRule(ar alertRule, l log.Logger, compact bool) (models.AlertRule, error) {
|
||||||
var data []models.AlertQuery
|
var data []models.AlertQuery
|
||||||
err := json.Unmarshal([]byte(ar.Data), &data)
|
if compact {
|
||||||
if err != nil {
|
var cqs []compactQuery
|
||||||
return models.AlertRule{}, fmt.Errorf("failed to parse data: %w", err)
|
if err := json.Unmarshal([]byte(ar.Data), &cqs); err != nil {
|
||||||
|
return models.AlertRule{}, fmt.Errorf("failed to parse data: %w", err)
|
||||||
|
}
|
||||||
|
for _, cq := range cqs {
|
||||||
|
data = append(data, models.AlertQuery{DatasourceUID: cq.DatasourceUID})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := json.Unmarshal([]byte(ar.Data), &data); err != nil {
|
||||||
|
return models.AlertRule{}, fmt.Errorf("failed to parse data: %w", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result := models.AlertRule{
|
result := models.AlertRule{
|
||||||
@@ -52,6 +79,7 @@ func alertRuleToModelsAlertRule(ar alertRule, l log.Logger) (models.AlertRule, e
|
|||||||
result.UpdatedBy = util.Pointer(models.UserUID(*ar.UpdatedBy))
|
result.UpdatedBy = util.Pointer(models.UserUID(*ar.UpdatedBy))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
if ar.NoDataState != "" {
|
if ar.NoDataState != "" {
|
||||||
result.NoDataState, err = models.NoDataStateFromString(ar.NoDataState)
|
result.NoDataState, err = models.NoDataStateFromString(ar.NoDataState)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -90,7 +118,7 @@ func alertRuleToModelsAlertRule(ar alertRule, l log.Logger) (models.AlertRule, e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ar.NotificationSettings != "" {
|
if !compact && ar.NotificationSettings != "" {
|
||||||
ns, err := parseNotificationSettings(ar.NotificationSettings)
|
ns, err := parseNotificationSettings(ar.NotificationSettings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return models.AlertRule{}, fmt.Errorf("failed to parse notification settings: %w", err)
|
return models.AlertRule{}, fmt.Errorf("failed to parse notification settings: %w", err)
|
||||||
@@ -98,7 +126,7 @@ func alertRuleToModelsAlertRule(ar alertRule, l log.Logger) (models.AlertRule, e
|
|||||||
result.NotificationSettings = ns
|
result.NotificationSettings = ns
|
||||||
}
|
}
|
||||||
|
|
||||||
if ar.Metadata != "" {
|
if !compact && ar.Metadata != "" {
|
||||||
err = json.Unmarshal([]byte(ar.Metadata), &result.Metadata)
|
err = json.Unmarshal([]byte(ar.Metadata), &result.Metadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return models.AlertRule{}, fmt.Errorf("failed to metadata: %w", err)
|
return models.AlertRule{}, fmt.Errorf("failed to metadata: %w", err)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/infra/log/logtest"
|
"github.com/grafana/grafana/pkg/infra/log/logtest"
|
||||||
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
|
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
@@ -81,3 +82,14 @@ func TestAlertRuleVersionToAlertRule(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkAlertRuleToModelsAlertRule(b *testing.B) {
|
||||||
|
r := ngmodels.RuleGen.Generate()
|
||||||
|
ar, err := alertRuleFromModelsAlertRule(r)
|
||||||
|
require.NoError(b, err)
|
||||||
|
l := log.NewNopLogger()
|
||||||
|
|
||||||
|
for range b.N {
|
||||||
|
alertRuleToModelsAlertRuleCompact(ar, l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user