diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c27d222bf..0afd8d7026 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ * [CHANGE] TSDB: Fix the predicate checking for blocks which are beyond the retention period to include the ones right at the retention boundary. #9633 +## 2.51.2 / 2024-04-09 + +Bugfix release. + +[BUGFIX] Notifier: could hang when using relabeling on alerts #13861 + ## 2.51.1 / 2024-03-27 Bugfix release. diff --git a/VERSION b/VERSION index 8e00e241f3..587b583f91 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.51.1 +2.51.2 diff --git a/notifier/notifier.go b/notifier/notifier.go index 53d3c04198..4cf376aa05 100644 --- a/notifier/notifier.go +++ b/notifier/notifier.go @@ -471,6 +471,10 @@ func (n *Manager) sendAll(alerts ...*Alert) bool { numSuccess atomic.Uint64 ) for _, ams := range amSets { + if len(ams.ams) == 0 { + continue + } + var ( payload []byte err error @@ -482,6 +486,7 @@ func (n *Manager) sendAll(alerts ...*Alert) bool { if len(ams.cfg.AlertRelabelConfigs) > 0 { amAlerts = relabelAlerts(ams.cfg.AlertRelabelConfigs, labels.Labels{}, alerts) if len(amAlerts) == 0 { + ams.mtx.RUnlock() continue } // We can't use the cached values from previous iteration. diff --git a/notifier/notifier_test.go b/notifier/notifier_test.go index 4f32994587..e7a9243bc2 100644 --- a/notifier/notifier_test.go +++ b/notifier/notifier_test.go @@ -219,17 +219,19 @@ func TestHandlerSendAllRemapPerAm(t *testing.T) { errc = make(chan error, 1) expected1 = make([]*Alert, 0, maxBatchSize) expected2 = make([]*Alert, 0, maxBatchSize) + expected3 = make([]*Alert, 0) - status1, status2 atomic.Int32 + statusOK atomic.Int32 ) - status1.Store(int32(http.StatusOK)) - status2.Store(int32(http.StatusOK)) + statusOK.Store(int32(http.StatusOK)) - server1 := newTestHTTPServerBuilder(&expected1, errc, "", "", &status1) - server2 := newTestHTTPServerBuilder(&expected2, errc, "", "", &status2) + server1 := newTestHTTPServerBuilder(&expected1, errc, "", "", &statusOK) + server2 := newTestHTTPServerBuilder(&expected2, errc, "", "", &statusOK) + server3 := newTestHTTPServerBuilder(&expected3, errc, "", "", &statusOK) defer server1.Close() defer server2.Close() + defer server3.Close() h := NewManager(&Options{}, nil) h.alertmanagers = make(map[string]*alertmanagerSet) @@ -247,38 +249,68 @@ func TestHandlerSendAllRemapPerAm(t *testing.T) { }, } - h.alertmanagers["1"] = &alertmanagerSet{ - ams: []alertmanager{ - alertmanagerMock{ - urlf: func() string { return server1.URL }, - }, + am3Cfg := config.DefaultAlertmanagerConfig + am3Cfg.Timeout = model.Duration(time.Second) + am3Cfg.AlertRelabelConfigs = []*relabel.Config{ + { + SourceLabels: model.LabelNames{"alertname"}, + Action: "drop", + Regex: relabel.MustNewRegexp(".+"), }, - cfg: &am1Cfg, } - h.alertmanagers["2"] = &alertmanagerSet{ - ams: []alertmanager{ - alertmanagerMock{ - urlf: func() string { return server2.URL }, + h.alertmanagers = map[string]*alertmanagerSet{ + // Drop no alerts. + "1": { + ams: []alertmanager{ + alertmanagerMock{ + urlf: func() string { return server1.URL }, + }, }, + cfg: &am1Cfg, + }, + // Drop only alerts with the "alertnamedrop" label. + "2": { + ams: []alertmanager{ + alertmanagerMock{ + urlf: func() string { return server2.URL }, + }, + }, + cfg: &am2Cfg, + }, + // Drop all alerts. + "3": { + ams: []alertmanager{ + alertmanagerMock{ + urlf: func() string { return server3.URL }, + }, + }, + cfg: &am3Cfg, + }, + // Empty list of Alertmanager endpoints. + "4": { + ams: []alertmanager{}, + cfg: &config.DefaultAlertmanagerConfig, }, - cfg: &am2Cfg, } for i := range make([]struct{}, maxBatchSize/2) { - h.queue = append(h.queue, &Alert{ - Labels: labels.FromStrings("alertname", fmt.Sprintf("%d", i)), - }) - h.queue = append(h.queue, &Alert{ - Labels: labels.FromStrings("alertnamedrop", fmt.Sprintf("%d", i)), - }) + h.queue = append(h.queue, + &Alert{ + Labels: labels.FromStrings("alertname", fmt.Sprintf("%d", i)), + }, + &Alert{ + Labels: labels.FromStrings("alertname", "test", "alertnamedrop", fmt.Sprintf("%d", i)), + }, + ) - expected1 = append(expected1, &Alert{ - Labels: labels.FromStrings("alertname", fmt.Sprintf("%d", i)), - }) - expected1 = append(expected1, &Alert{ - Labels: labels.FromStrings("alertnamedrop", fmt.Sprintf("%d", i)), - }) + expected1 = append(expected1, + &Alert{ + Labels: labels.FromStrings("alertname", fmt.Sprintf("%d", i)), + }, &Alert{ + Labels: labels.FromStrings("alertname", "test", "alertnamedrop", fmt.Sprintf("%d", i)), + }, + ) expected2 = append(expected2, &Alert{ Labels: labels.FromStrings("alertname", fmt.Sprintf("%d", i)), @@ -296,6 +328,13 @@ func TestHandlerSendAllRemapPerAm(t *testing.T) { require.True(t, h.sendAll(h.queue...), "all sends failed unexpectedly") checkNoErr() + + // Verify that individual locks are released. + for k := range h.alertmanagers { + h.alertmanagers[k].mtx.Lock() + h.alertmanagers[k].ams = nil + h.alertmanagers[k].mtx.Unlock() + } } func TestCustomDo(t *testing.T) { diff --git a/web/ui/module/codemirror-promql/package.json b/web/ui/module/codemirror-promql/package.json index c364e05584..1e50b43b53 100644 --- a/web/ui/module/codemirror-promql/package.json +++ b/web/ui/module/codemirror-promql/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/codemirror-promql", - "version": "0.51.1", + "version": "0.51.2", "description": "a CodeMirror mode for the PromQL language", "types": "dist/esm/index.d.ts", "module": "dist/esm/index.js", @@ -29,7 +29,7 @@ }, "homepage": "https://github.com/prometheus/prometheus/blob/main/web/ui/module/codemirror-promql/README.md", "dependencies": { - "@prometheus-io/lezer-promql": "0.51.1", + "@prometheus-io/lezer-promql": "0.51.2", "lru-cache": "^7.18.3" }, "devDependencies": { diff --git a/web/ui/module/lezer-promql/package.json b/web/ui/module/lezer-promql/package.json index f5ea66602f..494458a47a 100644 --- a/web/ui/module/lezer-promql/package.json +++ b/web/ui/module/lezer-promql/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/lezer-promql", - "version": "0.51.1", + "version": "0.51.2", "description": "lezer-based PromQL grammar", "main": "dist/index.cjs", "type": "module", diff --git a/web/ui/package-lock.json b/web/ui/package-lock.json index fdb348d669..ecdbf18a11 100644 --- a/web/ui/package-lock.json +++ b/web/ui/package-lock.json @@ -1,12 +1,12 @@ { "name": "prometheus-io", - "version": "0.51.1", + "version": "0.51.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "prometheus-io", - "version": "0.51.1", + "version": "0.51.2", "workspaces": [ "react-app", "module/*" @@ -30,10 +30,10 @@ }, "module/codemirror-promql": { "name": "@prometheus-io/codemirror-promql", - "version": "0.51.1", + "version": "0.51.2", "license": "Apache-2.0", "dependencies": { - "@prometheus-io/lezer-promql": "0.51.1", + "@prometheus-io/lezer-promql": "0.51.2", "lru-cache": "^7.18.3" }, "devDependencies": { @@ -69,7 +69,7 @@ }, "module/lezer-promql": { "name": "@prometheus-io/lezer-promql", - "version": "0.51.1", + "version": "0.51.2", "license": "Apache-2.0", "devDependencies": { "@lezer/generator": "^1.5.1", @@ -19233,7 +19233,7 @@ }, "react-app": { "name": "@prometheus-io/app", - "version": "0.51.1", + "version": "0.51.2", "dependencies": { "@codemirror/autocomplete": "^6.11.1", "@codemirror/commands": "^6.3.2", @@ -19251,7 +19251,7 @@ "@lezer/lr": "^1.3.14", "@nexucis/fuzzy": "^0.4.1", "@nexucis/kvsearch": "^0.8.1", - "@prometheus-io/codemirror-promql": "0.51.1", + "@prometheus-io/codemirror-promql": "0.51.2", "bootstrap": "^4.6.2", "css.escape": "^1.5.1", "downshift": "^7.6.2", diff --git a/web/ui/package.json b/web/ui/package.json index 0772aad7de..9c58f592c1 100644 --- a/web/ui/package.json +++ b/web/ui/package.json @@ -28,5 +28,5 @@ "ts-jest": "^29.1.1", "typescript": "^4.9.5" }, - "version": "0.51.1" + "version": "0.51.2" } diff --git a/web/ui/react-app/package.json b/web/ui/react-app/package.json index b47c9180a3..bd600720e2 100644 --- a/web/ui/react-app/package.json +++ b/web/ui/react-app/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/app", - "version": "0.51.1", + "version": "0.51.2", "private": true, "dependencies": { "@codemirror/autocomplete": "^6.11.1", @@ -19,7 +19,7 @@ "@lezer/lr": "^1.3.14", "@nexucis/fuzzy": "^0.4.1", "@nexucis/kvsearch": "^0.8.1", - "@prometheus-io/codemirror-promql": "0.51.1", + "@prometheus-io/codemirror-promql": "0.51.2", "bootstrap": "^4.6.2", "css.escape": "^1.5.1", "downshift": "^7.6.2",