Skip to content

Commit 57e7a84

Browse files
Create alertmanager.js (#808)
* Create alertmanager.js * Add changelog * Rename contrib/alertmanager.js to contrib/jsTransformationFunctions/alertmanager.js * Add docs to alertmanager.js * Update alertmanager.js * Update alertmanager.js with paragraphs * Update alertmanager.js convert `\n` line breaks to html `<br/>` so the upstream formatting is applied --------- Co-authored-by: Will Hunt <[email protected]>
1 parent a64a561 commit 57e7a84

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

changelog.d/808.feature

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add generic webhook transformation JS snippet for Prometheus Alertmanager.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* This is a transformation function for Prometheus Alertmanager webhooks.
3+
* https://prometheus.io/docs/alerting/latest/configuration/#webhook_config
4+
*
5+
* Creates a formatted `m.text` message with plaintext fallback, containing:
6+
* - alert status and severity
7+
* - alert name and description
8+
* - URL to the entity that caused the alert
9+
* The formatted message also contains a clickable link that silences the alert.
10+
*/
11+
12+
/**
13+
* @param status resolved or firing
14+
* @param severity from the labels of the alert
15+
* @returns colored text rendering of the status and severity
16+
*/
17+
function statusBadge(status, severity) {
18+
let statusColor;
19+
if (status === "resolved") {
20+
return `<font color='green'><b>[RESOLVED]</b></font>`;
21+
}
22+
23+
switch(severity) {
24+
case 'resolved':
25+
case 'critical':
26+
return `<font color='red'><b>[FIRING - CRITICAL]</b></font>`;
27+
case 'warning':
28+
return `<font color='orange'><b>[FIRING - WARNING]</b></font>`;
29+
default:
30+
return `<b>[${status.toUpperCase()}]</b>`;
31+
}
32+
}
33+
34+
/**
35+
* @param alert object from the webhook payload
36+
* @param externalURL from the webhook payload
37+
* @returns a formatted link that will silence the alert when clicked
38+
*/
39+
function silenceLink(alert, externalURL) {
40+
filters = []
41+
for (const [label, val] of Object.entries(alert.labels)) {
42+
filters.push(encodeURIComponent(`${label}="${val}"`));
43+
}
44+
return `<a href="${externalURL}#silences/new?filter={${filters.join(",")}}">silence</a>`;
45+
}
46+
47+
if (!data.alerts) {
48+
result = {
49+
version: 'v2',
50+
empty: true,
51+
};
52+
return;
53+
}
54+
55+
const plainErrors = [];
56+
const htmlErrors = [];
57+
const { externalURL, alerts } = data;
58+
59+
for (const alert of data.alerts) {
60+
plainErrors.push(`**[${alert.status.toUpperCase()} - ${alert.labels.severity}]** - ${alert.labels.alertname}: ${alert.annotations.description} [source](${alert.generatorURL})`);
61+
htmlErrors.push(`<p>${statusBadge(alert.status, alert.labels.severity)}</p><p><b>${alert.labels.alertname}</b>: ${alert.annotations.description.replaceAll("\n","<br\>")}</p><p><a href="${alert.generatorURL}">source</a> | ${silenceLink(alert, externalURL)}</p>`)
62+
result = {
63+
version: 'v2',
64+
plain: plainErrors.join(`\n\n`),
65+
html: htmlErrors.join(`<br/><br/>`),
66+
msgtype: 'm.text'
67+
};
68+
}

0 commit comments

Comments
 (0)