Merge pull request #1609 from prymitive/silence-group

fix(ui): only use shared labels for group silences
This commit is contained in:
Łukasz Mierzwa
2020-04-08 17:41:40 +01:00
committed by GitHub
2 changed files with 83 additions and 9 deletions

View File

@@ -51,18 +51,41 @@ const MatchersFromGroup = (group, stripLabels, alerts, onlyActive) => {
}
}
// this is the list of alerts we'll use to generate matchers
const filteredAlerts = (alerts ? alerts : group.alerts).filter(
(alert) => !onlyActive || alert.state === "active"
);
// array of arrays with label keys for each alert
const allLabelKeys = filteredAlerts
.map((alert) => Object.keys(alert.labels))
.filter((a) => a.length > 0);
// this is the list of label key that are shared across all alerts in the group
// https://stackoverflow.com/a/34498210/1154047
const sharedLabelKeys = allLabelKeys.length
? allLabelKeys.reduce(function (r, a) {
var last = {};
return r.filter(function (b) {
var p = a.indexOf(b, last[b] || 0);
if (~p) {
last[b] = p + 1;
return true;
}
return false;
});
})
: [];
// add matchers for all unique labels in this group
let labels = {};
const allAlerts = alerts ? alerts : group.alerts;
for (const alert of allAlerts) {
if (!onlyActive || alert.state === "active") {
for (const [key, value] of Object.entries(alert.labels)) {
if (!stripLabels.includes(key)) {
if (!labels[key]) {
labels[key] = new Set();
}
labels[key].add(value);
for (const alert of filteredAlerts) {
for (const [key, value] of Object.entries(alert.labels)) {
if (sharedLabelKeys.includes(key) && !stripLabels.includes(key)) {
if (!labels[key]) {
labels[key] = new Set();
}
labels[key].add(value);
}
}
}

View File

@@ -211,6 +211,57 @@ describe("SilenceFormStore.data", () => {
);
});
it("fillMatchersFromGroup() handles alerts with different label sets", () => {
const group = MockAlertGroup(
{ region: "AF" },
[
MockAlert([], {
alertname: "Alert1",
cluster: "prod",
foo: "bar",
}),
MockAlert([], {
alertname: "Alert2",
instance: "prod2",
cluster: "prod",
}),
MockAlert([], { alertname: "Alert3", instance: "dev1" }),
],
[],
{
job: "mock",
},
{}
);
store.data.fillMatchersFromGroup(group, []);
expect(store.data.matchers).toHaveLength(3);
expect(store.data.matchers).toContainEqual(
expect.objectContaining({
name: "region",
values: [{ label: "AF", value: "AF" }],
isRegex: false,
})
);
expect(store.data.matchers).toContainEqual(
expect.objectContaining({
name: "alertname",
values: [
{ label: "Alert1", value: "Alert1" },
{ label: "Alert2", value: "Alert2" },
{ label: "Alert3", value: "Alert3" },
],
isRegex: true,
})
);
expect(store.data.matchers).toContainEqual(
expect.objectContaining({
name: "job",
values: [{ label: "mock", value: "mock" }],
isRegex: false,
})
);
});
it("fillMatchersFromGroup() resets silenceID if set", () => {
store.data.silenceID = "12345";
const group = MockGroup();