]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Add Performance Details grafana charts for individual clusters in... 58959/head
authorAashish Sharma <aasharma@li-e74156cc-2f67-11b2-a85c-e98659a63c5c.ibm.com>
Wed, 31 Jul 2024 09:20:17 +0000 (14:50 +0530)
committerAashish Sharma <aasharma@li-e74156cc-2f67-11b2-a85c-e98659a63c5c.ibm.com>
Thu, 22 Aug 2024 08:45:08 +0000 (14:15 +0530)
Fixes: https://tracker.ceph.com/issues/67192
Signed-off-by: Aashish Sharma <aasharma@redhat.com>
12 files changed:
monitoring/ceph-mixin/dashboards/multi-cluster.libsonnet
monitoring/ceph-mixin/dashboards_out/ceph-cluster.json
monitoring/ceph-mixin/dashboards_out/multi-cluster-overview.json
src/pybind/mgr/dashboard/frontend/src/app/app-routing.module.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/cluster.module.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.html [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.scss [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.spec.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-details/multi-cluster-details.component.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.ts

index 94d32b49771b6b36e5accfb87b3036719466a4f0..8185ebb253b973c48ecd39893d58ee5ade6277d2 100644 (file)
@@ -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' },
index 3bd150e9ae263c4cf9732832a3d8070b5f931e4c..1fd7821a6b6ff7677fbdba6deacebe2db9fa385f 100644 (file)
@@ -32,6 +32,7 @@
   "editable": false,
   "gnetId": null,
   "graphTooltip": 0,
+  "hideControls": false,
   "id": null,
   "iteration": 1525415495309,
   "links": [],
   },
   "timezone": "",
   "title": "Ceph - Cluster",
-  "version": 13
+  "uid": "edtb0oxdq",
+  "version": 0
 }
index 7442aa45e8a9c6533b6d79f6abefbcacbfb9481b..25648cc0abb6866e27ac7afa39f472b261fb4906 100644 (file)
                      }
                   ]
                },
-               {
-                  "matcher": {
-                     "id": "byName",
-                     "options": "IOPS"
-                  },
-                  "properties": [
-                     {
-                        "id": "unit",
-                        "value": "ops"
-                     }
-                  ]
-               },
-               {
-                  "matcher": {
-                     "id": "byName",
-                     "options": "Value #E"
-                  },
-                  "properties": [
-                     {
-                        "id": "unit",
-                        "value": "bytes"
-                     }
-                  ]
-               },
                {
                   "matcher": {
                      "id": "byName",
                         "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}"
                            }
                         ]
                      }
                "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",
                "intervalFactor": 1,
                "legendFormat": "__auto",
                "range": false,
-               "refId": "F"
+               "refId": "D"
             }
          ],
          "timeFrom": null,
                      "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,
                   "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"
                   }
index 935be11e98b062a4b0036b5d0dbdafb0006e635b..0d859bbf8a699f7a8f0929d27ce88b38ad4f4cf1 100644 (file)
@@ -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
+              }
+            ]
           }
         ]
       },
index b76189612b8b3622f8b18a82833b3969b0e59416..394337ec09c4242ec4b76478622091cdc43135ba 100644 (file)
@@ -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 (file)
index 0000000..0063272
--- /dev/null
@@ -0,0 +1,24 @@
+<ng-container *ngIf="selection">
+  <nav ngbNav
+       #nav="ngbNav"
+       id="tabset-multi-cluster-details"
+       class="nav-tabs"
+       cdStatefulTab="multi-cluster-details">
+    <ng-container ngbNavItem="performance-details"
+                  *ngIf="permissions.grafana.read">
+      <a ngbNavLink
+         routerLink="performance-details"
+         i18n>Performance Details</a>
+      <ng-template ngbNavContent>
+        <cd-grafana i18n-title
+                    title="Cluster details"
+                    [grafanaPath]="'ceph-cluster?var-cluster=' + selectedClusterFsid"
+                    [type]="'metrics'"
+                    uid="edtb0oxdq"
+                    grafanaStyle="four">
+        </cd-grafana>
+      </ng-template>
+    </ng-container>
+  </nav>
+  <div [ngbNavOutlet]="nav"></div>
+</ng-container>
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 (file)
index 0000000..e69de29
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 (file)
index 0000000..0c554f6
--- /dev/null
@@ -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<MultiClusterDetailsComponent>;
+
+  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 (file)
index 0000000..b5c591a
--- /dev/null
@@ -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;
+  }
+}
index ce54299833f58dd5a4158f14182c3c89c96243a0..c73cb4e05bc381f5a36f9947e88d6805d1befe67 100644 (file)
@@ -34,6 +34,8 @@
                     [columns]="columns"
                     columnMode="flex"
                     selectionType="single"
+                    [hasDetails]="true"
+                    (setExpandedRow)="setExpandedRow($event)"
                     [maxLimit]="25"
                     (updateSelection)="updateSelection($event)">
             <div class="table-actions btn-toolbar">
                                 [tableActions]="tableActions">
               </cd-table-actions>
             </div>
+            <cd-multi-cluster-details cdTableDetail
+                                      [permissions]="permissions"
+                                      [selection]="expandedRow">
+            </cd-multi-cluster-details>
           </cd-table>
         </ng-template>
       </ng-container>
index d69b3a4bb8ca56c68040a68504e22a463aa5a53b..0a4c33eaecd8652619c91fc9ffb4749ea0498c3e 100644 (file)
@@ -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);
index 7ecf73fcc896fd46c61bac9917a5fafd7b2dec59..cfb343542546372cbbfaf4b27ca9caf518d4774e 100644 (file)
@@ -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 });
+  }
 }