From b5536d8b8d41451484ec8585c07910a4d5ad0f3e Mon Sep 17 00:00:00 2001 From: Aashish Sharma Date: Wed, 31 Jul 2024 14:50:17 +0530 Subject: [PATCH] mgr/dashboard: Add Performance Details grafana charts for individual clusters in Manage-clusters page Fixes: https://tracker.ceph.com/issues/67192 Signed-off-by: Aashish Sharma --- .../dashboards/multi-cluster.libsonnet | 44 +----------- .../dashboards_out/ceph-cluster.json | 4 +- .../multi-cluster-overview.json | 68 ++----------------- .../frontend/src/app/app-routing.module.ts | 9 ++- .../src/app/ceph/cluster/cluster.module.ts | 4 +- .../multi-cluster-details.component.html | 24 +++++++ .../multi-cluster-details.component.scss | 0 .../multi-cluster-details.component.spec.ts | 22 ++++++ .../multi-cluster-details.component.ts | 18 +++++ .../multi-cluster-list.component.html | 6 ++ .../multi-cluster-list.component.spec.ts | 3 +- .../multi-cluster-list.component.ts | 22 ++++-- 12 files changed, 108 insertions(+), 116 deletions(-) create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.ts diff --git a/monitoring/ceph-mixin/dashboards/multi-cluster.libsonnet b/monitoring/ceph-mixin/dashboards/multi-cluster.libsonnet index 94d32b49771..8185ebb253b 100644 --- a/monitoring/ceph-mixin/dashboards/multi-cluster.libsonnet +++ b/monitoring/ceph-mixin/dashboards/multi-cluster.libsonnet @@ -136,18 +136,6 @@ local g = import 'grafonnet/grafana.libsonnet'; { id: 'mappings', value: [{ options: { '0': { color: 'semi-dark-green', index: 2, text: 'Healthy' }, '1': { color: 'semi-dark-yellow', index: 0, text: 'Warning' }, '2': { color: 'semi-dark-red', index: 1, text: 'Error' } }, type: 'value' }] }, ], }, - { - matcher: { id: 'byName', options: 'IOPS' }, - properties: [ - { id: 'unit', value: 'ops' }, - ], - }, - { - matcher: { id: 'byName', options: 'Value #E' }, - properties: [ - { id: 'unit', value: 'bytes' }, - ], - }, { matcher: { id: 'byName', options: 'Capacity Used' }, properties: [ @@ -157,7 +145,7 @@ local g = import 'grafonnet/grafana.libsonnet'; { matcher: { id: 'byName', options: 'Cluster' }, properties: [ - { id: 'links', value: [{ title: '', url: '/d/GQ3MHvnIz/ceph-cluster-new?var-cluster=${__data.fields.Cluster}&${DS_PROMETHEUS:queryparam}' }] }, + { id: 'links', value: [{ title: '', url: '/d/edtb0oxdq/ceph-cluster?var-cluster=${__data.fields.Cluster}&${DS_PROMETHEUS:queryparam}' }] }, ], }, { @@ -211,9 +199,7 @@ local g = import 'grafonnet/grafana.libsonnet'; 'Value #A': 1, 'Value #B': 20, 'Value #C': 3, - 'Value #D': 4, - 'Value #E': 5, - 'Value #F': 6, + 'Value #D': 6, '__name__ 1': 9, '__name__ 2': 14, '__name__ 3': 24, @@ -235,9 +221,7 @@ local g = import 'grafonnet/grafana.libsonnet'; renameByName: { 'Value #A': 'Status', 'Value #C': 'Alerts', - 'Value #D': 'IOPS', - 'Value #E': 'Throughput', - 'Value #F': 'Capacity Used', + 'Value #D': 'Capacity Used', ceph_version: 'Version', cluster: 'Cluster', }, @@ -277,28 +261,6 @@ local g = import 'grafonnet/grafana.libsonnet'; legendFormat='__auto', range=false, ), - $.addTargetSchema( - expr='sum by (cluster) (irate(ceph_pool_wr[$__interval])) \n+ sum by (cluster) (irate(ceph_pool_rd[$__interval])) ', - datasource={ type: 'prometheus', uid: '$datasource' }, - format='table', - hide=false, - exemplar=false, - instant=true, - interval='', - legendFormat='__auto', - range=false, - ), - $.addTargetSchema( - expr='sum by (cluster) (irate(ceph_pool_rd_bytes[$__interval]))\n+ sum by (cluster) (irate(ceph_pool_wr_bytes[$__interval])) ', - datasource={ type: 'prometheus', uid: '$datasource' }, - format='table', - hide=false, - exemplar=false, - instant=true, - interval='', - legendFormat='__auto', - range=false, - ), $.addTargetSchema( expr='ceph_cluster_by_class_total_used_bytes', datasource={ type: 'prometheus', uid: '$datasource' }, diff --git a/monitoring/ceph-mixin/dashboards_out/ceph-cluster.json b/monitoring/ceph-mixin/dashboards_out/ceph-cluster.json index 3bd150e9ae2..1fd7821a6b6 100644 --- a/monitoring/ceph-mixin/dashboards_out/ceph-cluster.json +++ b/monitoring/ceph-mixin/dashboards_out/ceph-cluster.json @@ -32,6 +32,7 @@ "editable": false, "gnetId": null, "graphTooltip": 0, + "hideControls": false, "id": null, "iteration": 1525415495309, "links": [], @@ -1428,5 +1429,6 @@ }, "timezone": "", "title": "Ceph - Cluster", - "version": 13 + "uid": "edtb0oxdq", + "version": 0 } diff --git a/monitoring/ceph-mixin/dashboards_out/multi-cluster-overview.json b/monitoring/ceph-mixin/dashboards_out/multi-cluster-overview.json index 7442aa45e8a..25648cc0abb 100644 --- a/monitoring/ceph-mixin/dashboards_out/multi-cluster-overview.json +++ b/monitoring/ceph-mixin/dashboards_out/multi-cluster-overview.json @@ -247,30 +247,6 @@ } ] }, - { - "matcher": { - "id": "byName", - "options": "IOPS" - }, - "properties": [ - { - "id": "unit", - "value": "ops" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Value #E" - }, - "properties": [ - { - "id": "unit", - "value": "bytes" - } - ] - }, { "matcher": { "id": "byName", @@ -294,7 +270,7 @@ "value": [ { "title": "", - "url": "/d/GQ3MHvnIz/ceph-cluster-new?var-cluster=${__data.fields.Cluster}&${DS_PROMETHEUS:queryparam}" + "url": "/d/edtb0oxdq/ceph-cluster?var-cluster=${__data.fields.Cluster}&${DS_PROMETHEUS:queryparam}" } ] } @@ -397,38 +373,6 @@ "range": false, "refId": "C" }, - { - "datasource": { - "type": "prometheus", - "uid": "$datasource" - }, - "exemplar": false, - "expr": "sum by (cluster) (irate(ceph_pool_wr[$__interval])) \n+ sum by (cluster) (irate(ceph_pool_rd[$__interval])) ", - "format": "table", - "hide": false, - "instant": true, - "interval": "", - "intervalFactor": 1, - "legendFormat": "__auto", - "range": false, - "refId": "D" - }, - { - "datasource": { - "type": "prometheus", - "uid": "$datasource" - }, - "exemplar": false, - "expr": "sum by (cluster) (irate(ceph_pool_rd_bytes[$__interval]))\n+ sum by (cluster) (irate(ceph_pool_wr_bytes[$__interval])) ", - "format": "table", - "hide": false, - "instant": true, - "interval": "", - "intervalFactor": 1, - "legendFormat": "__auto", - "range": false, - "refId": "E" - }, { "datasource": { "type": "prometheus", @@ -443,7 +387,7 @@ "intervalFactor": 1, "legendFormat": "__auto", "range": false, - "refId": "F" + "refId": "D" } ], "timeFrom": null, @@ -494,9 +438,7 @@ "Value #A": 1, "Value #B": 20, "Value #C": 3, - "Value #D": 4, - "Value #E": 5, - "Value #F": 6, + "Value #D": 6, "__name__ 1": 9, "__name__ 2": 14, "__name__ 3": 24, @@ -518,9 +460,7 @@ "renameByName": { "Value #A": "Status", "Value #C": "Alerts", - "Value #D": "IOPS", - "Value #E": "Throughput", - "Value #F": "Capacity Used", + "Value #D": "Capacity Used", "ceph_version": "Version", "cluster": "Cluster" } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/app-routing.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/app-routing.module.ts index 935be11e98b..0d859bbf8a6 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/app-routing.module.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/app-routing.module.ts @@ -50,6 +50,7 @@ import { CephfsVolumeFormComponent } from './ceph/cephfs/cephfs-form/cephfs-form import { UpgradeProgressComponent } from './ceph/cluster/upgrade/upgrade-progress/upgrade-progress.component'; import { MultiClusterComponent } from './ceph/cluster/multi-cluster/multi-cluster.component'; import { MultiClusterListComponent } from './ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component'; +import { MultiClusterDetailsComponent } from './ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component'; @Injectable() export class PerformanceCounterBreadcrumbsResolver extends BreadcrumbsResolver { @@ -203,7 +204,13 @@ const routes: Routes = [ component: MultiClusterListComponent, data: { breadcrumbs: 'Multi-Cluster/Manage Clusters' - } + }, + children: [ + { + path: 'performance-details', + component: MultiClusterDetailsComponent + } + ] } ] }, diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/cluster.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/cluster.module.ts index b76189612b8..394337ec09c 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/cluster.module.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/cluster.module.ts @@ -65,6 +65,7 @@ import { MultiClusterComponent } from './multi-cluster/multi-cluster.component'; import { MultiClusterFormComponent } from './multi-cluster/multi-cluster-form/multi-cluster-form.component'; import { MultiClusterListComponent } from './multi-cluster/multi-cluster-list/multi-cluster-list.component'; import { DashboardV3Module } from '../dashboard-v3/dashboard-v3.module'; +import { MultiClusterDetailsComponent } from './multi-cluster/multi-cluster-details/multi-cluster-details.component'; @NgModule({ imports: [ @@ -132,7 +133,8 @@ import { DashboardV3Module } from '../dashboard-v3/dashboard-v3.module'; UpgradeProgressComponent, MultiClusterComponent, MultiClusterFormComponent, - MultiClusterListComponent + MultiClusterListComponent, + MultiClusterDetailsComponent ], providers: [NgbActiveModal] }) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.html new file mode 100644 index 00000000000..00632724a10 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.html @@ -0,0 +1,24 @@ + + +
+
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.spec.ts new file mode 100644 index 00000000000..0c554f696ec --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MultiClusterDetailsComponent } from './multi-cluster-details.component'; + +describe('MultiClusterDetailsComponent', () => { + let component: MultiClusterDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [MultiClusterDetailsComponent] + }).compileComponents(); + + fixture = TestBed.createComponent(MultiClusterDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.ts new file mode 100644 index 00000000000..b5c591a7039 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'cd-multi-cluster-details', + templateUrl: './multi-cluster-details.component.html', + styleUrls: ['./multi-cluster-details.component.scss'] +}) +export class MultiClusterDetailsComponent { + @Input() + permissions: Permissions; + + @Input() + selection: any; + + get selectedClusterFsid(): string { + return this.selection !== undefined ? this.selection['name'] : null; + } +} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.html index ce54299833f..c73cb4e05bc 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.html @@ -34,6 +34,8 @@ [columns]="columns" columnMode="flex" selectionType="single" + [hasDetails]="true" + (setExpandedRow)="setExpandedRow($event)" [maxLimit]="25" (updateSelection)="updateSelection($event)">
@@ -44,6 +46,10 @@ [tableActions]="tableActions">
+ + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.spec.ts index d69b3a4bb8c..0a4c33eaecd 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.spec.ts @@ -7,6 +7,7 @@ import { MultiClusterListComponent } from './multi-cluster-list.component'; import { CdDatePipe } from '~/app/shared/pipes/cd-date.pipe'; import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component'; import { SharedModule } from '~/app/shared/shared.module'; +import { ActivatedRoute } from '@angular/router'; describe('MultiClusterListComponent', () => { let component: MultiClusterListComponent; @@ -16,7 +17,7 @@ describe('MultiClusterListComponent', () => { await TestBed.configureTestingModule({ imports: [HttpClientTestingModule, ToastrModule.forRoot(), NgbNavModule, SharedModule], declarations: [MultiClusterListComponent], - providers: [CdDatePipe, TableActionsComponent] + providers: [CdDatePipe, TableActionsComponent, { provide: ActivatedRoute, useValue: {} }] }).compileComponents(); fixture = TestBed.createComponent(MultiClusterListComponent); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.ts index 7ecf73fcc89..cfb34354254 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.ts @@ -16,18 +16,19 @@ import { NotificationService } from '~/app/shared/services/notification.service' import { NotificationType } from '~/app/shared/enum/notification-type.enum'; import { CellTemplate } from '~/app/shared/enum/cell-template.enum'; import { MultiCluster } from '~/app/shared/models/multi-cluster'; -import { Router } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { CookiesService } from '~/app/shared/services/cookie.service'; import { Observable, Subscription } from 'rxjs'; import { SettingsService } from '~/app/shared/api/settings.service'; import { ModalCdsService } from '~/app/shared/services/modal-cds.service'; +import { ListWithDetails } from '~/app/shared/classes/list-with-details.class'; @Component({ selector: 'cd-multi-cluster-list', templateUrl: './multi-cluster-list.component.html', styleUrls: ['./multi-cluster-list.component.scss'] }) -export class MultiClusterListComponent implements OnInit, OnDestroy { +export class MultiClusterListComponent extends ListWithDetails implements OnInit, OnDestroy { @ViewChild(TableComponent) table: TableComponent; @ViewChild('urlTpl', { static: true }) @@ -59,8 +60,10 @@ export class MultiClusterListComponent implements OnInit, OnDestroy { private modalService: ModalService, private cookieService: CookiesService, private settingsService: SettingsService, - private cdsModalService: ModalCdsService + private cdsModalService: ModalCdsService, + private route: ActivatedRoute ) { + super(); this.tableActions = [ { permission: 'create', @@ -223,10 +226,6 @@ export class MultiClusterListComponent implements OnInit, OnDestroy { }); } - updateSelection(selection: CdTableSelection) { - this.selection = selection; - } - openDeleteClusterModal() { const cluster = this.selection.first(); this.modalRef = this.cdsModalService.show(CriticalConfirmationModalComponent, { @@ -264,4 +263,13 @@ export class MultiClusterListComponent implements OnInit, OnDestroy { } return false; } + + updateSelection(selection: CdTableSelection) { + this.selection = selection; + } + + setExpandedRow(expandedRow: any) { + super.setExpandedRow(expandedRow); + this.router.navigate(['performance-details'], { relativeTo: this.route }); + } } -- 2.39.5