]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-silence-matcher.service.ts
import 15.2.0 Octopus source
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / shared / services / prometheus-silence-matcher.service.ts
CommitLineData
494da23a
TL
1import { Injectable } from '@angular/core';
2
3import * as _ from 'lodash';
4
5import { I18n } from '@ngx-translate/i18n-polyfill';
6import {
7 AlertmanagerSilenceMatcher,
8 AlertmanagerSilenceMatcherMatch
9} from '../models/alertmanager-silence';
10import { PrometheusRule } from '../models/prometheus-alerts';
11
12@Injectable({
13 providedIn: 'root'
14})
15export 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}