From: Aashish Sharma Date: Fri, 6 May 2022 07:09:02 +0000 (+0530) Subject: mgr/dashboard: Add daemon logs tab to Logs component X-Git-Tag: v17.2.6~130^2~61^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=3374c905b278f37425790a3cc81650f1f7c9376e;p=ceph.git mgr/dashboard: Add daemon logs tab to Logs component Add Daemon logs to the logs component Signed-off-by: Aashish Sharma (cherry picked from commit a581660f47d85da0e985c5bcba6e9a6cd6b47dae) --- diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/logs.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/logs.e2e-spec.ts index 9868b89aedbc5..ecc3cc1cd9126 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/logs.e2e-spec.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/logs.e2e-spec.ts @@ -27,8 +27,8 @@ describe('Logs page', () => { logs.expectBreadcrumbText('Logs'); }); - it('should show two tabs', () => { - logs.getTabsCount().should('eq', 2); + it('should show three tabs', () => { + logs.getTabsCount().should('eq', 3); }); it('should show cluster logs tab at first', () => { @@ -38,6 +38,10 @@ describe('Logs page', () => { it('should show audit logs as a second tab', () => { logs.getTabText(1).should('eq', 'Audit Logs'); }); + + it('should show daemon logs as a third tab', () => { + logs.getTabText(2).should('eq', 'Daemon Logs'); + }); }); describe('audit logs respond to pool creation and deletion test', () => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html index 7503863e0fb2c..349fba7b0f967 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html @@ -149,6 +149,7 @@ i18n>Performance diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.html index 002c8e57c0203..e8116ea2a86d2 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-performance/rbd-performance.component.html @@ -1,6 +1,7 @@ diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html index 7a222a1000e32..830645d2b6fca 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-tabs/cephfs-tabs.component.html @@ -36,6 +36,7 @@ i18n>Performance Details diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.html index a138768c351f4..5803776d0aaef 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-details/host-details.component.html @@ -35,6 +35,7 @@ i18n>Performance Details diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.html index b41ecfa866330..b8a17135af437 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.html @@ -36,6 +36,7 @@ i18n>Overall Performance diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.html index dd55a678fb196..d5c73eb73904a 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.html @@ -67,6 +67,21 @@ +
  • + Daemon Logs + + +
    + + +
    +
    +
    +
  • @@ -157,3 +172,11 @@ (click)="resetFilter()" i18n>Reset filter.
    + + + + Please start the loki and promtail service to see these logs. + + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.ts index 420da49589142..ed8c721eaf3e1 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.ts @@ -2,7 +2,10 @@ import { DatePipe } from '@angular/common'; import { Component, NgZone, OnDestroy, OnInit } from '@angular/core'; import { NgbDateStruct } from '@ng-bootstrap/ng-bootstrap'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { CephServiceService } from '~/app/shared/api/ceph-service.service'; import { LogsService } from '~/app/shared/api/logs.service'; import { Icons } from '~/app/shared/enum/icons.enum'; @@ -18,6 +21,8 @@ export class LogsComponent implements OnInit, OnDestroy { icons = Icons; clogText: string; auditLogText: string; + lokiServiceStatus$: Observable; + promtailServiceStatus$: Observable; interval: number; priorities: Array<{ name: string; value: string }> = [ @@ -40,6 +45,7 @@ export class LogsComponent implements OnInit, OnDestroy { constructor( private logsService: LogsService, + private cephService: CephServiceService, private datePipe: DatePipe, private ngZone: NgZone ) {} @@ -47,6 +53,7 @@ export class LogsComponent implements OnInit, OnDestroy { ngOnInit() { this.getInfo(); this.ngZone.runOutsideAngular(() => { + this.getDaemonDetails(); this.interval = window.setInterval(() => { this.ngZone.run(() => { this.getInfo(); @@ -59,6 +66,19 @@ export class LogsComponent implements OnInit, OnDestroy { clearInterval(this.interval); } + getDaemonDetails() { + this.lokiServiceStatus$ = this.cephService.getDaemons('loki').pipe( + map((data: any) => { + return data.length > 0 && data[0].status === 1; + }) + ); + this.promtailServiceStatus$ = this.cephService.getDaemons('promtail').pipe( + map((data: any) => { + return data.length > 0 && data[0].status === 1; + }) + ); + } + getInfo() { this.logsService.getLogs().subscribe((data: any) => { this.contentData = data; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.html index bd85e2255689b..56eee8c8b9c43 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.html @@ -56,6 +56,7 @@ i18n>Performance Details diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.html index 3e6f1475afff8..afec81d9d1971 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.html @@ -44,6 +44,7 @@ i18n>Overall Performance diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.html index 1b0cd563cc8aa..40d71dd0e3218 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-details/pool-details.component.html @@ -20,6 +20,7 @@ i18n>Performance Details diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.html index 7122f749cfb9e..bd568a9107ea0 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.html @@ -38,6 +38,7 @@ i18n>Overall Performance diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html index e53eaa8f73d3d..f10394342b138 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-details/rgw-daemon-details.component.html @@ -27,6 +27,7 @@ i18n>Performance Details diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html index 38683a6f6d8f7..e5b01305706ae 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-daemon-list/rgw-daemon-list.component.html @@ -24,6 +24,7 @@ i18n>Overall Performance @@ -36,6 +37,7 @@ i18n>Sync Performance diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.spec.ts index 63733fd759ccc..5052ef9ec6e82 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.spec.ts @@ -20,6 +20,8 @@ describe('GrafanaComponent', () => { let fixture: ComponentFixture; const expected_url = 'http:localhost:3000/d/foo/somePath&refresh=2s&var-datasource=Dashboard1&kiosk&from=now-1h&to=now'; + const expected_logs_url = + 'http:localhost:3000/explore?orgId=1&left=["now-1h","now","Loki",{"refId":"A"}]&kiosk'; configureTestBed({ declarations: [GrafanaComponent, AlertPanelComponent, LoadingPanelComponent, DocComponent], @@ -31,6 +33,7 @@ describe('GrafanaComponent', () => { fixture = TestBed.createComponent(GrafanaComponent); component = fixture.componentInstance; component.grafanaPath = 'somePath'; + component.type = 'metrics'; component.uid = 'foo'; }); @@ -50,6 +53,7 @@ describe('GrafanaComponent', () => { describe('with grafana initialized', () => { beforeEach(() => { TestBed.inject(SettingsService)['settings'] = { 'api/grafana/url': 'http:localhost:3000' }; + component.type = 'metrics'; fixture.detectChanges(); }); @@ -78,4 +82,23 @@ describe('GrafanaComponent', () => { expect(component.dashboardExist).toBe(true); }); }); + + describe('with loki datasource', () => { + beforeEach(() => { + TestBed.inject(SettingsService)['settings'] = { 'api/grafana/url': 'http:localhost:3000' }; + component.type = 'logs'; + component.grafanaPath = 'explore?'; + fixture.detectChanges(); + }); + + it('should have found out that Loki Log Search exists', () => { + expect(component.grafanaExist).toBe(true); + expect(component.baseUrl).toBe('http:localhost:3000/d/'); + expect(component.loading).toBe(false); + expect(component.url).toBe(expected_logs_url); + expect(component.grafanaSrc).toEqual({ + changingThisBreaksApplicationSecurity: expected_logs_url + }); + }); + }); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.ts index a687959b747f8..a5c32e6867a20 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/grafana/grafana.component.ts @@ -19,7 +19,7 @@ export class GrafanaComponent implements OnInit, OnChanges { panelStyle: any; grafanaExist = false; mode = '&kiosk'; - datasource = 'Dashboard1'; + datasource: string; loading = true; styles: Record = {}; dashboardExist = true; @@ -28,6 +28,8 @@ export class GrafanaComponent implements OnInit, OnChanges { icons = Icons; readonly DEFAULT_TIME: string = 'from=now-1h&to=now'; + @Input() + type: string; @Input() grafanaPath: string; @Input() @@ -153,6 +155,8 @@ export class GrafanaComponent implements OnInit, OnChanges { four: 'grafana_four' }; + this.datasource = this.type === 'metrics' ? 'Dashboard1' : 'Loki'; + this.settingsService.ifSettingConfigured('api/grafana/url', (url) => { this.grafanaExist = true; this.loading = false; @@ -166,16 +170,13 @@ export class GrafanaComponent implements OnInit, OnChanges { this.settingsService .validateGrafanaDashboardUrl(this.uid) .subscribe((data: any) => (this.dashboardExist = data === 200)); - this.url = - this.baseUrl + - this.uid + - '/' + - this.grafanaPath + - '&refresh=2s' + - `&var-datasource=${this.datasource}` + - this.mode + - '&' + - this.time; + if (this.type === 'metrics') { + this.url = `${this.baseUrl}${this.uid}/${this.grafanaPath}&refresh=2s&var-datasource=${this.datasource}${this.mode}&${this.time}`; + } else { + this.url = `${this.baseUrl.slice(0, -2)}${this.grafanaPath}orgId=1&left=["now-1h","now","${ + this.datasource + }",{"refId":"A"}]${this.mode}`; + } this.grafanaSrc = this.sanitizer.bypassSecurityTrustResourceUrl(this.url); }