]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert.service.ts
import 14.2.4 nautilus point release
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / shared / services / prometheus-alert.service.ts
1 import { Injectable } from '@angular/core';
2
3 import * as _ from 'lodash';
4
5 import { PrometheusService } from '../api/prometheus.service';
6 import { AlertmanagerAlert, PrometheusCustomAlert } from '../models/prometheus-alerts';
7 import { PrometheusAlertFormatter } from './prometheus-alert-formatter';
8
9 @Injectable({
10 providedIn: 'root'
11 })
12 export class PrometheusAlertService {
13 private canAlertsBeNotified = false;
14 alerts: AlertmanagerAlert[] = [];
15
16 constructor(
17 private alertFormatter: PrometheusAlertFormatter,
18 private prometheusService: PrometheusService
19 ) {}
20
21 refresh() {
22 this.prometheusService.ifAlertmanagerConfigured(() => {
23 this.prometheusService.getAlerts().subscribe(
24 (alerts) => this.handleAlerts(alerts),
25 (resp) => {
26 if ([404, 504].includes(resp.status)) {
27 this.prometheusService.disableAlertmanagerConfig();
28 }
29 }
30 );
31 });
32 }
33
34 private handleAlerts(alerts: AlertmanagerAlert[]) {
35 if (this.canAlertsBeNotified) {
36 this.notifyOnAlertChanges(alerts, this.alerts);
37 }
38 this.alerts = alerts;
39 this.canAlertsBeNotified = true;
40 }
41
42 private notifyOnAlertChanges(alerts: AlertmanagerAlert[], oldAlerts: AlertmanagerAlert[]) {
43 const changedAlerts = this.getChangedAlerts(
44 this.alertFormatter.convertToCustomAlerts(alerts),
45 this.alertFormatter.convertToCustomAlerts(oldAlerts)
46 );
47 const notifications = changedAlerts.map((alert) =>
48 this.alertFormatter.convertAlertToNotification(alert)
49 );
50 this.alertFormatter.sendNotifications(notifications);
51 }
52
53 private getChangedAlerts(alerts: PrometheusCustomAlert[], oldAlerts: PrometheusCustomAlert[]) {
54 const updatedAndNew = _.differenceWith(alerts, oldAlerts, _.isEqual);
55 return updatedAndNew.concat(this.getVanishedAlerts(alerts, oldAlerts));
56 }
57
58 private getVanishedAlerts(alerts: PrometheusCustomAlert[], oldAlerts: PrometheusCustomAlert[]) {
59 return _.differenceWith(oldAlerts, alerts, (a, b) => a.fingerprint === b.fingerprint).map(
60 (alert) => {
61 alert.status = 'resolved';
62 return alert;
63 }
64 );
65 }
66 }