]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | import { Injectable } from '@angular/core'; |
2 | ||
f67539c2 | 3 | import _ from 'lodash'; |
11fdf7f2 TL |
4 | |
5 | import { PrometheusService } from '../api/prometheus.service'; | |
9f95a23c TL |
6 | import { |
7 | AlertmanagerAlert, | |
8 | PrometheusCustomAlert, | |
9 | PrometheusRule | |
10 | } from '../models/prometheus-alerts'; | |
11fdf7f2 | 11 | import { PrometheusAlertFormatter } from './prometheus-alert-formatter'; |
11fdf7f2 TL |
12 | |
13 | @Injectable({ | |
81eedcae | 14 | providedIn: 'root' |
11fdf7f2 TL |
15 | }) |
16 | export class PrometheusAlertService { | |
17 | private canAlertsBeNotified = false; | |
494da23a | 18 | alerts: AlertmanagerAlert[] = []; |
9f95a23c | 19 | rules: PrometheusRule[] = []; |
cd265ab1 | 20 | activeAlerts: number; |
11fdf7f2 TL |
21 | |
22 | constructor( | |
23 | private alertFormatter: PrometheusAlertFormatter, | |
24 | private prometheusService: PrometheusService | |
25 | ) {} | |
26 | ||
9f95a23c | 27 | getAlerts() { |
494da23a TL |
28 | this.prometheusService.ifAlertmanagerConfigured(() => { |
29 | this.prometheusService.getAlerts().subscribe( | |
30 | (alerts) => this.handleAlerts(alerts), | |
31 | (resp) => { | |
32 | if ([404, 504].includes(resp.status)) { | |
33 | this.prometheusService.disableAlertmanagerConfig(); | |
11fdf7f2 | 34 | } |
494da23a TL |
35 | } |
36 | ); | |
11fdf7f2 TL |
37 | }); |
38 | } | |
39 | ||
9f95a23c TL |
40 | getRules() { |
41 | this.prometheusService.ifPrometheusConfigured(() => { | |
42 | this.prometheusService.getRules('alerting').subscribe((groups) => { | |
43 | this.rules = groups['groups'].reduce((acc, group) => { | |
44 | return acc.concat( | |
45 | group.rules.map((rule) => { | |
46 | rule.group = group.name; | |
47 | return rule; | |
48 | }) | |
49 | ); | |
50 | }, []); | |
51 | }); | |
52 | }); | |
53 | } | |
54 | ||
55 | refresh() { | |
56 | this.getAlerts(); | |
57 | this.getRules(); | |
58 | } | |
59 | ||
494da23a | 60 | private handleAlerts(alerts: AlertmanagerAlert[]) { |
11fdf7f2 TL |
61 | if (this.canAlertsBeNotified) { |
62 | this.notifyOnAlertChanges(alerts, this.alerts); | |
63 | } | |
cd265ab1 TL |
64 | this.activeAlerts = _.reduce<AlertmanagerAlert, number>( |
65 | this.alerts, | |
66 | (result, alert) => (alert.status.state === 'active' ? ++result : result), | |
67 | 0 | |
68 | ); | |
11fdf7f2 TL |
69 | this.alerts = alerts; |
70 | this.canAlertsBeNotified = true; | |
71 | } | |
72 | ||
494da23a | 73 | private notifyOnAlertChanges(alerts: AlertmanagerAlert[], oldAlerts: AlertmanagerAlert[]) { |
11fdf7f2 TL |
74 | const changedAlerts = this.getChangedAlerts( |
75 | this.alertFormatter.convertToCustomAlerts(alerts), | |
76 | this.alertFormatter.convertToCustomAlerts(oldAlerts) | |
77 | ); | |
78 | const notifications = changedAlerts.map((alert) => | |
79 | this.alertFormatter.convertAlertToNotification(alert) | |
80 | ); | |
81 | this.alertFormatter.sendNotifications(notifications); | |
82 | } | |
83 | ||
84 | private getChangedAlerts(alerts: PrometheusCustomAlert[], oldAlerts: PrometheusCustomAlert[]) { | |
85 | const updatedAndNew = _.differenceWith(alerts, oldAlerts, _.isEqual); | |
86 | return updatedAndNew.concat(this.getVanishedAlerts(alerts, oldAlerts)); | |
87 | } | |
88 | ||
89 | private getVanishedAlerts(alerts: PrometheusCustomAlert[], oldAlerts: PrometheusCustomAlert[]) { | |
90 | return _.differenceWith(oldAlerts, alerts, (a, b) => a.fingerprint === b.fingerprint).map( | |
91 | (alert) => { | |
92 | alert.status = 'resolved'; | |
93 | return alert; | |
94 | } | |
95 | ); | |
96 | } | |
97 | } |