diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts index 83888a5550c81..a319aeed6f338 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts @@ -7,7 +7,6 @@ import { CdTableAction } from '~/app/shared/models/cd-table-action'; import { CdTableColumn } from '~/app/shared/models/cd-table-column'; import { CdTableSelection } from '~/app/shared/models/cd-table-selection'; import { Permission } from '~/app/shared/models/permissions'; -import { CdDatePipe } from '~/app/shared/pipes/cd-date.pipe'; import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; import { PrometheusAlertService } from '~/app/shared/services/prometheus-alert.service'; import { URLBuilderService } from '~/app/shared/services/url-builder.service'; @@ -29,18 +28,12 @@ export class ActiveAlertListComponent extends PrometheusListHelper implements On permission: Permission; selection = new CdTableSelection(); icons = Icons; - customCss = { - 'badge badge-danger': 'active', - 'badge badge-warning': 'unprocessed', - 'badge badge-info': 'suppressed' - }; constructor( // NotificationsComponent will refresh all alerts every 5s (No need to do it here as well) private authStorageService: AuthStorageService, public prometheusAlertService: PrometheusAlertService, private urlBuilder: URLBuilderService, - private cdDatePipe: CdDatePipe, @Inject(PrometheusService) prometheusService: PrometheusService ) { super(prometheusService); @@ -65,30 +58,49 @@ export class ActiveAlertListComponent extends PrometheusListHelper implements On { name: $localize`Name`, prop: 'labels.alertname', + cellClass: 'font-weight-bold', flexGrow: 2 }, { - name: $localize`Job`, - prop: 'labels.job', - flexGrow: 2 + name: $localize`Summary`, + prop: 'annotations.summary', + flexGrow: 3 }, { name: $localize`Severity`, - prop: 'labels.severity' + prop: 'labels.severity', + flexGrow: 1, + cellTransformation: CellTemplate.badge, + customTemplateConfig: { + map: { + critical: { class: 'badge-danger' }, + warning: { class: 'badge-warning' } + } + } }, { name: $localize`State`, prop: 'status.state', - cellTransformation: CellTemplate.classAdding + flexGrow: 1, + cellTransformation: CellTemplate.badge, + customTemplateConfig: { + map: { + active: { class: 'badge-info' }, + unprocessed: { class: 'badge-warning' }, + suppressed: { class: 'badge-dark' } + } + } }, { name: $localize`Started`, prop: 'startsAt', - pipe: this.cdDatePipe + cellTransformation: CellTemplate.timeAgo, + flexGrow: 1 }, { name: $localize`URL`, prop: 'generatorURL', + flexGrow: 1, sortable: false, cellTemplate: this.externalLinkTpl } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html index fd3967ce6939c..3be6091a584c3 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.html @@ -5,7 +5,11 @@ class="nav-tabs">
  • Active Alerts + i18n>Active Alerts + {{ prometheusAlertService.activeCriticalAlerts }} + {{ prometheusAlertService.activeWarningAlerts }}
  • { configureTestBed({ imports: [RouterTestingModule, NgbNavModule], - declarations: [PrometheusTabsComponent] + declarations: [PrometheusTabsComponent], + providers: [{ provide: PrometheusAlertService, useValue: { alerts: [] } }] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.ts index 4011770d4173a..cccce1d92e33c 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/prometheus-tabs/prometheus-tabs.component.ts @@ -1,11 +1,13 @@ import { Component } from '@angular/core'; import { Router } from '@angular/router'; +import { PrometheusAlertService } from '~/app/shared/services/prometheus-alert.service'; + @Component({ selector: 'cd-prometheus-tabs', templateUrl: './prometheus-tabs.component.html', styleUrls: ['./prometheus-tabs.component.scss'] }) export class PrometheusTabsComponent { - constructor(public router: Router) {} + constructor(public router: Router, public prometheusAlertService: PrometheusAlertService) {} } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts index 325520d110ec9..cc4ee511156d6 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/rules-list/rules-list.component.ts @@ -1,7 +1,11 @@ import { Component, Inject, OnInit } from '@angular/core'; +import _ from 'lodash'; + import { PrometheusService } from '~/app/shared/api/prometheus.service'; +import { CellTemplate } from '~/app/shared/enum/cell-template.enum'; import { CdTableColumn } from '~/app/shared/models/cd-table-column'; +import { CdTableSelection } from '~/app/shared/models/cd-table-selection'; import { PrometheusRule } from '~/app/shared/models/prometheus-alerts'; import { DurationPipe } from '~/app/shared/pipes/duration.pipe'; import { PrometheusAlertService } from '~/app/shared/services/prometheus-alert.service'; @@ -15,6 +19,7 @@ import { PrometheusListHelper } from '../prometheus-list-helper'; export class RulesListComponent extends PrometheusListHelper implements OnInit { columns: CdTableColumn[]; expandedRow: PrometheusRule; + selection = new CdTableSelection(); /** * Hide active alerts in details of alerting rules as they are already shown @@ -33,12 +38,32 @@ export class RulesListComponent extends PrometheusListHelper implements OnInit { ngOnInit() { super.ngOnInit(); this.columns = [ - { prop: 'name', name: $localize`Name` }, - { prop: 'labels.severity', name: $localize`Severity` }, - { prop: 'group', name: $localize`Group` }, - { prop: 'duration', name: $localize`Duration`, pipe: new DurationPipe() }, - { prop: 'query', name: $localize`Query`, isHidden: true }, - { prop: 'annotations.description', name: $localize`Description` } + { prop: 'name', name: $localize`Name`, cellClass: 'font-weight-bold', flexGrow: 2 }, + { + prop: 'labels.severity', + name: $localize`Severity`, + flexGrow: 1, + cellTransformation: CellTemplate.badge, + customTemplateConfig: { + map: { + critical: { class: 'badge-danger' }, + warning: { class: 'badge-warning' } + } + } + }, + { + prop: 'group', + name: $localize`Group`, + flexGrow: 1, + cellTransformation: CellTemplate.badge + }, + { prop: 'duration', name: $localize`Duration`, pipe: new DurationPipe(), flexGrow: 1 }, + { prop: 'query', name: $localize`Query`, isHidden: true, flexGrow: 1 }, + { prop: 'annotations.summary', name: $localize`Summary`, flexGrow: 3 } ]; } + + updateSelection(selection: CdTableSelection) { + this.selection = selection; + } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.html index bdb35a610d973..39bcb5b6a0dc3 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.html @@ -160,8 +160,10 @@ *ngIf="permissions.prometheus.read"> Monitoring - {{ prometheusAlertService.activeAlerts }} + {{ prometheusAlertService.activeCriticalAlerts }} + {{ prometheusAlertService.activeWarningAlerts }}
  • diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html index 71ba156cf3f60..b38477c813733 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html @@ -311,3 +311,9 @@ (click)="toggleExpandRow(row, isExpanded, $event)"> + + + {{ value | relativeDate }} + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts index 3f2c6dff7baf6..ddeda9ac44311 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts @@ -65,6 +65,8 @@ export class TableComponent implements AfterContentChecked, OnInit, OnChanges, O mapTpl: TemplateRef; @ViewChild('truncateTpl', { static: true }) truncateTpl: TemplateRef; + @ViewChild('timeAgoTpl', { static: true }) + timeAgoTpl: TemplateRef; @ViewChild('rowDetailsTpl', { static: true }) rowDetailsTpl: TemplateRef; @@ -581,6 +583,7 @@ export class TableComponent implements AfterContentChecked, OnInit, OnChanges, O this.cellTemplates.badge = this.badgeTpl; this.cellTemplates.map = this.mapTpl; this.cellTemplates.truncate = this.truncateTpl; + this.cellTemplates.timeAgo = this.timeAgoTpl; } useCustomClass(value: any): string { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/cell-template.enum.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/cell-template.enum.ts index 73ce1f23919f7..066cc9930adce 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/cell-template.enum.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/enum/cell-template.enum.ts @@ -50,5 +50,10 @@ export enum CellTemplate { // omission?: string; // Defaults to empty string. // } // } - truncate = 'truncate' + truncate = 'truncate', + /* + This templace replaces a time, datetime or timestamp with a user-friendly "X {seconds,minutes,hours,days,...} ago", + but the tooltip still displays the absolute timestamp + */ + timeAgo = 'timeAgo' } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert.service.ts index 6223808fb0122..f26b80629b920 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert.service.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert.service.ts @@ -18,6 +18,8 @@ export class PrometheusAlertService { alerts: AlertmanagerAlert[] = []; rules: PrometheusRule[] = []; activeAlerts: number; + activeCriticalAlerts: number; + activeWarningAlerts: number; constructor( private alertFormatter: PrometheusAlertFormatter, @@ -66,6 +68,18 @@ export class PrometheusAlertService { (result, alert) => (alert.status.state === 'active' ? ++result : result), 0 ); + this.activeCriticalAlerts = _.reduce( + this.alerts, + (result, alert) => + alert.status.state === 'active' && alert.labels.severity === 'critical' ? ++result : result, + 0 + ); + this.activeWarningAlerts = _.reduce( + this.alerts, + (result, alert) => + alert.status.state === 'active' && alert.labels.severity === 'warning' ? ++result : result, + 0 + ); this.alerts = alerts; this.canAlertsBeNotified = true; }