# All files / src/app/shared/services prometheus-alert.service.ts

100% Statements 41/41
71.43% Branches 5/7
100% Functions 12/12
100% Lines 36/36

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    748x

    8x

    8x

    8x
    8x

    8x
    13x
    13x
    13x

    13x
    13x

    13x
    13x

    13x
    12x

    1x
    1x

    1x
    1x

    8x

    6x

    12x
    12x

    8x
    6x

    6x
    5x

    6x

    8x
    6x
    6x

    8x
    10x

    2x
    2x

    8x
     import { Injectable } from '@angular/core';

    import * as _ from 'lodash';

    import { PrometheusService } from '../api/prometheus.service';
    import { PrometheusAlert, PrometheusCustomAlert } from '../models/prometheus-alerts';
    import { PrometheusAlertFormatter } from './prometheus-alert-formatter';
    import { ServicesModule } from './services.module';

    @Injectable({
      providedIn: ServicesModule
    })
    export class PrometheusAlertService {
      private canAlertsBeNotified = false;
      private connected = true;
      alerts: PrometheusAlert[] = [];

      constructor(
        private alertFormatter: PrometheusAlertFormatter,
        private prometheusService: PrometheusService
      ) {}

      refresh() {
        this.prometheusService.ifAlertmanagerConfigured((url) => {
          if (this.connected) {
            this.prometheusService.list().subscribe(
              (alerts) => this.handleAlerts(alerts),
              (resp) => {
                const errorMsg = `Please check if <a target="_blank" href="${url}">Prometheus Alertmanager</a> is still running`;
                resp['application'] = 'Prometheus';
                if (resp.status === 500) {
                  this.connected = false;
                  resp.error.detail = errorMsg;
                }
              }
            );
          }
        });
      }

      private handleAlerts(alerts: PrometheusAlert[]) {
        if (this.canAlertsBeNotified) {
          this.notifyOnAlertChanges(alerts, this.alerts);
        }
        this.alerts = alerts;
        this.canAlertsBeNotified = true;
      }

      private notifyOnAlertChanges(alerts: PrometheusAlert[], oldAlerts: PrometheusAlert[]) {
        const changedAlerts = this.getChangedAlerts(
          this.alertFormatter.convertToCustomAlerts(alerts),
          this.alertFormatter.convertToCustomAlerts(oldAlerts)
        );
        const notifications = changedAlerts.map((alert) =>
          this.alertFormatter.convertAlertToNotification(alert)
        );
        this.alertFormatter.sendNotifications(notifications);
      }

      private getChangedAlerts(alerts: PrometheusCustomAlert[], oldAlerts: PrometheusCustomAlert[]) {
        const updatedAndNew = _.differenceWith(alerts, oldAlerts, _.isEqual);
        return updatedAndNew.concat(this.getVanishedAlerts(alerts, oldAlerts));
      }

      private getVanishedAlerts(alerts: PrometheusCustomAlert[], oldAlerts: PrometheusCustomAlert[]) {
        return _.differenceWith(oldAlerts, alerts, (a, b) => a.fingerprint === b.fingerprint).map(
          (alert) => {
            alert.status = 'resolved';
            return alert;
          }
        );
      }
    }