Skip to content

Commit

Permalink
Create alertmanager.js (matrix-org#808)
Browse files Browse the repository at this point in the history
* 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]>
  • Loading branch information
HarHarLinks and Half-Shot authored Aug 16, 2023
1 parent a64a561 commit 57e7a84
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog.d/808.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add generic webhook transformation JS snippet for Prometheus Alertmanager.
68 changes: 68 additions & 0 deletions contrib/jsTransformationFunctions/alertmanager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* This is a transformation function for Prometheus Alertmanager webhooks.
* https://prometheus.io/docs/alerting/latest/configuration/#webhook_config
*
* Creates a formatted `m.text` message with plaintext fallback, containing:
* - alert status and severity
* - alert name and description
* - URL to the entity that caused the alert
* The formatted message also contains a clickable link that silences the alert.
*/

/**
* @param status resolved or firing
* @param severity from the labels of the alert
* @returns colored text rendering of the status and severity
*/
function statusBadge(status, severity) {
let statusColor;
if (status === "resolved") {
return `<font color='green'><b>[RESOLVED]</b></font>`;
}

switch(severity) {
case 'resolved':
case 'critical':
return `<font color='red'><b>[FIRING - CRITICAL]</b></font>`;
case 'warning':
return `<font color='orange'><b>[FIRING - WARNING]</b></font>`;
default:
return `<b>[${status.toUpperCase()}]</b>`;
}
}

/**
* @param alert object from the webhook payload
* @param externalURL from the webhook payload
* @returns a formatted link that will silence the alert when clicked
*/
function silenceLink(alert, externalURL) {
filters = []
for (const [label, val] of Object.entries(alert.labels)) {
filters.push(encodeURIComponent(`${label}="${val}"`));
}
return `<a href="${externalURL}#silences/new?filter={${filters.join(",")}}">silence</a>`;
}

if (!data.alerts) {
result = {
version: 'v2',
empty: true,
};
return;
}

const plainErrors = [];
const htmlErrors = [];
const { externalURL, alerts } = data;

for (const alert of data.alerts) {
plainErrors.push(`**[${alert.status.toUpperCase()} - ${alert.labels.severity}]** - ${alert.labels.alertname}: ${alert.annotations.description} [source](${alert.generatorURL})`);
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>`)
result = {
version: 'v2',
plain: plainErrors.join(`\n\n`),
html: htmlErrors.join(`<br/><br/>`),
msgtype: 'm.text'
};
}

0 comments on commit 57e7a84

Please sign in to comment.