Alerting: Update alerting module to 77a1e2f35be87bebc41a0bf634f336282f0b9b53 (#115498)
* [create-pull-request] automated change * Remove IsProtectedField and temp structure * Fix alerting historian * make update-workspace --------- Co-authored-by: yuri-tceretian <25988953+yuri-tceretian@users.noreply.github.com> Co-authored-by: Yuri Tseretyan <yuriy.tseretyan@grafana.com> Co-authored-by: Alexander Akhmetov <me@alx.cx>
This commit is contained in:
committed by
GitHub
parent
0a0f92e85e
commit
a1389bc173
@@ -4,7 +4,7 @@ go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/go-kit/log v0.2.1
|
||||
github.com/grafana/alerting v0.0.0-20251212143239-491433b332b7
|
||||
github.com/grafana/alerting v0.0.0-20251217141753-77a1e2f35be8
|
||||
github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4
|
||||
github.com/grafana/grafana-app-sdk v0.48.7
|
||||
github.com/grafana/grafana-app-sdk/logging v0.48.7
|
||||
|
||||
@@ -243,8 +243,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/grafana/alerting v0.0.0-20251212143239-491433b332b7 h1:ZzG/gCclEit9w0QUfQt9GURcOycAIGcsQAhY1u0AEX0=
|
||||
github.com/grafana/alerting v0.0.0-20251212143239-491433b332b7/go.mod h1:l7v67cgP7x72ajB9UPZlumdrHqNztpKoqQ52cU8T3LU=
|
||||
github.com/grafana/alerting v0.0.0-20251217141753-77a1e2f35be8 h1:m5VqerdocNDh1vTi8itJmX9DwonGqj+SfkO0JxPHt0E=
|
||||
github.com/grafana/alerting v0.0.0-20251217141753-77a1e2f35be8/go.mod h1:l7v67cgP7x72ajB9UPZlumdrHqNztpKoqQ52cU8T3LU=
|
||||
github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 h1:jSojuc7njleS3UOz223WDlXOinmuLAIPI0z2vtq8EgI=
|
||||
github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4/go.mod h1:VahT+GtfQIM+o8ht2StR6J9g+Ef+C2Vokh5uuSmOD/4=
|
||||
github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo=
|
||||
|
||||
@@ -31,6 +31,10 @@ const (
|
||||
maxLimit = 1000
|
||||
Namespace = "grafana"
|
||||
Subsystem = "alerting"
|
||||
|
||||
// LogQL field path for alert rule UID after JSON parsing.
|
||||
// Loki flattens nested JSON fields with underscores: alert.labels.__alert_rule_uid__ -> alert_labels___alert_rule_uid__
|
||||
lokiAlertRuleUIDField = "alert_labels___alert_rule_uid__"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -111,13 +115,13 @@ func buildQuery(query Query) (string, error) {
|
||||
fmt.Sprintf(`%s=%q`, historian.LabelFrom, historian.LabelFromValue),
|
||||
}
|
||||
|
||||
if query.RuleUID != nil {
|
||||
selectors = append(selectors,
|
||||
fmt.Sprintf(`%s=%q`, historian.LabelRuleUID, *query.RuleUID))
|
||||
}
|
||||
|
||||
logql := fmt.Sprintf(`{%s} | json`, strings.Join(selectors, `,`))
|
||||
|
||||
// Add ruleUID filter as JSON line filter if specified.
|
||||
if query.RuleUID != nil && *query.RuleUID != "" {
|
||||
logql += fmt.Sprintf(` | %s = %q`, lokiAlertRuleUIDField, *query.RuleUID)
|
||||
}
|
||||
|
||||
// Add receiver filter if specified.
|
||||
if query.Receiver != nil && *query.Receiver != "" {
|
||||
logql += fmt.Sprintf(` | receiver = %q`, *query.Receiver)
|
||||
@@ -211,16 +215,13 @@ func parseLokiEntry(s lokiclient.Sample) (Entry, error) {
|
||||
groupLabels = make(map[string]string)
|
||||
}
|
||||
|
||||
alerts := make([]EntryAlert, len(lokiEntry.Alerts))
|
||||
for i, a := range lokiEntry.Alerts {
|
||||
alerts[i] = EntryAlert{
|
||||
Status: a.Status,
|
||||
Labels: a.Labels,
|
||||
Annotations: a.Annotations,
|
||||
StartsAt: a.StartsAt,
|
||||
EndsAt: a.EndsAt,
|
||||
}
|
||||
}
|
||||
alerts := []EntryAlert{{
|
||||
Status: lokiEntry.Alert.Status,
|
||||
Labels: lokiEntry.Alert.Labels,
|
||||
Annotations: lokiEntry.Alert.Annotations,
|
||||
StartsAt: lokiEntry.Alert.StartsAt,
|
||||
EndsAt: lokiEntry.Alert.EndsAt,
|
||||
}}
|
||||
|
||||
return Entry{
|
||||
Timestamp: s.T,
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/alerting/models"
|
||||
"github.com/grafana/alerting/notify/historian"
|
||||
"github.com/grafana/alerting/notify/historian/lokiclient"
|
||||
"github.com/grafana/grafana-app-sdk/logging"
|
||||
@@ -133,9 +134,8 @@ func TestBuildQuery(t *testing.T) {
|
||||
query: Query{
|
||||
RuleUID: stringPtr("test-rule-uid"),
|
||||
},
|
||||
expected: fmt.Sprintf(`{%s=%q,%s=%q} | json`,
|
||||
historian.LabelFrom, historian.LabelFromValue,
|
||||
historian.LabelRuleUID, "test-rule-uid"),
|
||||
expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid"`,
|
||||
historian.LabelFrom, historian.LabelFromValue),
|
||||
},
|
||||
{
|
||||
name: "query with receiver filter",
|
||||
@@ -143,9 +143,8 @@ func TestBuildQuery(t *testing.T) {
|
||||
RuleUID: stringPtr("test-rule-uid"),
|
||||
Receiver: stringPtr("email-receiver"),
|
||||
},
|
||||
expected: fmt.Sprintf(`{%s=%q,%s=%q} | json | receiver = "email-receiver"`,
|
||||
historian.LabelFrom, historian.LabelFromValue,
|
||||
historian.LabelRuleUID, "test-rule-uid"),
|
||||
expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid" | receiver = "email-receiver"`,
|
||||
historian.LabelFrom, historian.LabelFromValue),
|
||||
},
|
||||
{
|
||||
name: "query with status filter",
|
||||
@@ -153,9 +152,8 @@ func TestBuildQuery(t *testing.T) {
|
||||
RuleUID: stringPtr("test-rule-uid"),
|
||||
Status: createStatusPtr(v0alpha1.CreateNotificationqueryRequestNotificationStatusFiring),
|
||||
},
|
||||
expected: fmt.Sprintf(`{%s=%q,%s=%q} | json | status = "firing"`,
|
||||
historian.LabelFrom, historian.LabelFromValue,
|
||||
historian.LabelRuleUID, "test-rule-uid"),
|
||||
expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid" | status = "firing"`,
|
||||
historian.LabelFrom, historian.LabelFromValue),
|
||||
},
|
||||
{
|
||||
name: "query with success outcome filter",
|
||||
@@ -163,9 +161,8 @@ func TestBuildQuery(t *testing.T) {
|
||||
RuleUID: stringPtr("test-rule-uid"),
|
||||
Outcome: outcomePtr(v0alpha1.CreateNotificationqueryRequestNotificationOutcomeSuccess),
|
||||
},
|
||||
expected: fmt.Sprintf(`{%s=%q,%s=%q} | json | error = ""`,
|
||||
historian.LabelFrom, historian.LabelFromValue,
|
||||
historian.LabelRuleUID, "test-rule-uid"),
|
||||
expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid" | error = ""`,
|
||||
historian.LabelFrom, historian.LabelFromValue),
|
||||
},
|
||||
{
|
||||
name: "query with error outcome filter",
|
||||
@@ -173,9 +170,8 @@ func TestBuildQuery(t *testing.T) {
|
||||
RuleUID: stringPtr("test-rule-uid"),
|
||||
Outcome: outcomePtr(v0alpha1.CreateNotificationqueryRequestNotificationOutcomeError),
|
||||
},
|
||||
expected: fmt.Sprintf(`{%s=%q,%s=%q} | json | error != ""`,
|
||||
historian.LabelFrom, historian.LabelFromValue,
|
||||
historian.LabelRuleUID, "test-rule-uid"),
|
||||
expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid" | error != ""`,
|
||||
historian.LabelFrom, historian.LabelFromValue),
|
||||
},
|
||||
{
|
||||
name: "query with many filters",
|
||||
@@ -185,9 +181,8 @@ func TestBuildQuery(t *testing.T) {
|
||||
Status: createStatusPtr(v0alpha1.CreateNotificationqueryRequestNotificationStatusResolved),
|
||||
Outcome: outcomePtr(v0alpha1.CreateNotificationqueryRequestNotificationOutcomeSuccess),
|
||||
},
|
||||
expected: fmt.Sprintf(`{%s=%q,%s=%q} | json | receiver = "email-receiver" | status = "resolved" | error = ""`,
|
||||
historian.LabelFrom, historian.LabelFromValue,
|
||||
historian.LabelRuleUID, "test-rule-uid"),
|
||||
expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid" | receiver = "email-receiver" | status = "resolved" | error = ""`,
|
||||
historian.LabelFrom, historian.LabelFromValue),
|
||||
},
|
||||
{
|
||||
name: "query with group label matcher",
|
||||
@@ -277,19 +272,19 @@ func TestParseLokiEntry(t *testing.T) {
|
||||
GroupLabels: map[string]string{
|
||||
"alertname": "test-alert",
|
||||
},
|
||||
Alerts: []historian.NotificationHistoryLokiEntryAlert{
|
||||
{
|
||||
Status: "firing",
|
||||
Labels: map[string]string{
|
||||
"severity": "critical",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
"summary": "Test alert",
|
||||
},
|
||||
StartsAt: now,
|
||||
EndsAt: now.Add(1 * time.Hour),
|
||||
Alert: historian.NotificationHistoryLokiEntryAlert{
|
||||
Status: "firing",
|
||||
Labels: map[string]string{
|
||||
"severity": "critical",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
"summary": "Test alert",
|
||||
},
|
||||
StartsAt: now,
|
||||
EndsAt: now.Add(1 * time.Hour),
|
||||
},
|
||||
AlertIndex: 0,
|
||||
AlertCount: 1,
|
||||
Retry: false,
|
||||
Duration: 100,
|
||||
PipelineTime: now,
|
||||
@@ -335,7 +330,9 @@ func TestParseLokiEntry(t *testing.T) {
|
||||
Error: "notification failed",
|
||||
GroupKey: "key:thing",
|
||||
GroupLabels: map[string]string{},
|
||||
Alerts: []historian.NotificationHistoryLokiEntryAlert{},
|
||||
Alert: historian.NotificationHistoryLokiEntryAlert{},
|
||||
AlertIndex: 0,
|
||||
AlertCount: 1,
|
||||
PipelineTime: now,
|
||||
}),
|
||||
},
|
||||
@@ -347,7 +344,7 @@ func TestParseLokiEntry(t *testing.T) {
|
||||
Outcome: OutcomeError,
|
||||
GroupKey: "key:thing",
|
||||
GroupLabels: map[string]string{},
|
||||
Alerts: []EntryAlert{},
|
||||
Alerts: []EntryAlert{{}},
|
||||
Error: stringPtr("notification failed"),
|
||||
PipelineTime: now,
|
||||
},
|
||||
@@ -365,7 +362,7 @@ func TestParseLokiEntry(t *testing.T) {
|
||||
Status: Status("firing"),
|
||||
Outcome: OutcomeSuccess,
|
||||
GroupLabels: map[string]string{},
|
||||
Alerts: []EntryAlert{},
|
||||
Alerts: []EntryAlert{{}},
|
||||
PipelineTime: now,
|
||||
},
|
||||
},
|
||||
@@ -448,7 +445,9 @@ func TestLokiReader_RunQuery(t *testing.T) {
|
||||
Receiver: "receiver-1",
|
||||
Status: "firing",
|
||||
GroupLabels: map[string]string{},
|
||||
Alerts: []historian.NotificationHistoryLokiEntryAlert{},
|
||||
Alert: historian.NotificationHistoryLokiEntryAlert{},
|
||||
AlertIndex: 0,
|
||||
AlertCount: 1,
|
||||
PipelineTime: now,
|
||||
}),
|
||||
},
|
||||
@@ -459,7 +458,9 @@ func TestLokiReader_RunQuery(t *testing.T) {
|
||||
Receiver: "receiver-3",
|
||||
Status: "firing",
|
||||
GroupLabels: map[string]string{},
|
||||
Alerts: []historian.NotificationHistoryLokiEntryAlert{},
|
||||
Alert: historian.NotificationHistoryLokiEntryAlert{},
|
||||
AlertIndex: 0,
|
||||
AlertCount: 1,
|
||||
PipelineTime: now,
|
||||
}),
|
||||
},
|
||||
@@ -474,7 +475,9 @@ func TestLokiReader_RunQuery(t *testing.T) {
|
||||
Receiver: "receiver-2",
|
||||
Status: "firing",
|
||||
GroupLabels: map[string]string{},
|
||||
Alerts: []historian.NotificationHistoryLokiEntryAlert{},
|
||||
Alert: historian.NotificationHistoryLokiEntryAlert{},
|
||||
AlertIndex: 0,
|
||||
AlertCount: 1,
|
||||
PipelineTime: now,
|
||||
}),
|
||||
},
|
||||
@@ -546,19 +549,19 @@ func createMockLokiResponse(timestamp time.Time) lokiclient.QueryRes {
|
||||
GroupLabels: map[string]string{
|
||||
"alertname": "test-alert",
|
||||
},
|
||||
Alerts: []historian.NotificationHistoryLokiEntryAlert{
|
||||
{
|
||||
Status: "firing",
|
||||
Labels: map[string]string{
|
||||
"severity": "critical",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
"summary": "Test alert",
|
||||
},
|
||||
StartsAt: timestamp,
|
||||
EndsAt: timestamp.Add(1 * time.Hour),
|
||||
Alert: historian.NotificationHistoryLokiEntryAlert{
|
||||
Status: "firing",
|
||||
Labels: map[string]string{
|
||||
"severity": "critical",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
"summary": "Test alert",
|
||||
},
|
||||
StartsAt: timestamp,
|
||||
EndsAt: timestamp.Add(1 * time.Hour),
|
||||
},
|
||||
AlertIndex: 0,
|
||||
AlertCount: 1,
|
||||
Retry: false,
|
||||
Duration: 100,
|
||||
PipelineTime: timestamp,
|
||||
@@ -587,10 +590,19 @@ func createLokiEntryJSONWithNilLabels(t *testing.T, timestamp time.Time) string
|
||||
"status": "firing",
|
||||
"error": "",
|
||||
"groupLabels": null,
|
||||
"alerts": [],
|
||||
"alert": {},
|
||||
"alertIndex": 0,
|
||||
"alertCount": 1,
|
||||
"retry": false,
|
||||
"duration": 0,
|
||||
"pipelineTime": "%s"
|
||||
}`, timestamp.Format(time.RFC3339Nano))
|
||||
return jsonStr
|
||||
}
|
||||
|
||||
func TestRuleUIDLabelConstant(t *testing.T) {
|
||||
// Verify that models.RuleUIDLabel has the expected value.
|
||||
// If this changes in the alerting module, our LogQL field path constant will be incorrect
|
||||
// and filtering for a single alert rule by its UID will break.
|
||||
assert.Equal(t, "__alert_rule_uid__", models.RuleUIDLabel)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user