]>
Commit | Line | Data |
---|---|---|
494da23a TL |
1 | import { Injectable } from '@angular/core'; |
2 | ||
3 | import * as _ from 'lodash'; | |
4 | ||
5 | import { I18n } from '@ngx-translate/i18n-polyfill'; | |
6 | import { | |
7 | AlertmanagerSilenceMatcher, | |
8 | AlertmanagerSilenceMatcherMatch | |
9 | } from '../models/alertmanager-silence'; | |
10 | import { PrometheusRule } from '../models/prometheus-alerts'; | |
11 | ||
12 | @Injectable({ | |
13 | providedIn: 'root' | |
14 | }) | |
15 | export class PrometheusSilenceMatcherService { | |
16 | private valueAttributePath = { | |
17 | alertname: 'name', | |
18 | instance: 'alerts.0.labels.instance', | |
19 | job: 'alerts.0.labels.job', | |
20 | severity: 'labels.severity' | |
21 | }; | |
22 | ||
23 | constructor(private i18n: I18n) {} | |
24 | ||
25 | singleMatch( | |
26 | matcher: AlertmanagerSilenceMatcher, | |
27 | rules: PrometheusRule[] | |
28 | ): AlertmanagerSilenceMatcherMatch { | |
29 | return this.multiMatch([matcher], rules); | |
30 | } | |
31 | ||
32 | multiMatch( | |
33 | matchers: AlertmanagerSilenceMatcher[], | |
34 | rules: PrometheusRule[] | |
35 | ): AlertmanagerSilenceMatcherMatch { | |
36 | if (matchers.some((matcher) => matcher.isRegex)) { | |
9f95a23c | 37 | return undefined; |
494da23a TL |
38 | } |
39 | matchers.forEach((matcher) => { | |
40 | rules = this.getMatchedRules(matcher, rules); | |
41 | }); | |
42 | return this.describeMatch(rules); | |
43 | } | |
44 | ||
45 | private getMatchedRules( | |
46 | matcher: AlertmanagerSilenceMatcher, | |
47 | rules: PrometheusRule[] | |
48 | ): PrometheusRule[] { | |
49 | const attributePath = this.getAttributePath(matcher.name); | |
50 | return rules.filter((r) => _.get(r, attributePath) === matcher.value); | |
51 | } | |
52 | ||
53 | private describeMatch(rules: PrometheusRule[]): AlertmanagerSilenceMatcherMatch { | |
54 | let alerts = 0; | |
55 | rules.forEach((r) => (alerts += r.alerts.length)); | |
56 | return { | |
57 | status: this.getMatchText(rules.length, alerts), | |
58 | cssClass: alerts ? 'has-success' : 'has-warning' | |
59 | }; | |
60 | } | |
61 | ||
62 | getAttributePath(name: string): string { | |
63 | return this.valueAttributePath[name]; | |
64 | } | |
65 | ||
66 | private getMatchText(rules: number, alerts: number): string { | |
67 | const msg = { | |
68 | noRule: this.i18n('Your matcher seems to match no currently defined rule or active alert.'), | |
69 | noAlerts: this.i18n('no active alerts'), | |
70 | alert: this.i18n('1 active alert'), | |
71 | alerts: this.i18n('{{n}} active alerts', { n: alerts }), | |
72 | rule: this.i18n('Matches 1 rule'), | |
73 | rules: this.i18n('Matches {{n}} rules', { n: rules }) | |
74 | }; | |
75 | return rules | |
76 | ? this.i18n('{{rules}} with {{alerts}}.', { | |
77 | rules: rules > 1 ? msg.rules : msg.rule, | |
78 | alerts: alerts ? (alerts > 1 ? msg.alerts : msg.alert) : msg.noAlerts | |
79 | }) | |
80 | : msg.noRule; | |
81 | } | |
82 | } |