From 4c17b52b1626d7ea5f6d564d70bb91655aae3f10 Mon Sep 17 00:00:00 2001 From: Avan Thakkar Date: Thu, 7 Apr 2022 16:31:20 +0530 Subject: [PATCH] mgr/dashboard: introduce memory and cpu usage for daemons Fixes: https://tracker.ceph.com/issues/55218 Signed-off-by: Avan Thakkar Co-authored-by: Aashish Sharma Introducing 2 new columns in Cluster->Host->Daemons table for Memory and CPU usage. (cherry picked from commit 263940502bdd9858c97923f394cd3d918e86e921) --- src/cephadm/cephadm | 27 ++++++++++++++++++- src/pybind/mgr/cephadm/module.py | 1 + .../service-daemon-list.component.ts | 13 +++++++++ src/pybind/mgr/orchestrator/_interface.py | 5 ++++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/cephadm/cephadm b/src/cephadm/cephadm index 8f4ae73422308..e1d639614845e 100755 --- a/src/cephadm/cephadm +++ b/src/cephadm/cephadm @@ -6188,12 +6188,20 @@ def list_daemons(ctx, detail=True, legacy_dir=None): # keep track of memory usage we've seen seen_memusage = {} # type: Dict[str, int] + seen_cpuperc = {} # type: Dict[str, int] out, err, code = call( ctx, [container_path, 'stats', '--format', '{{.ID}},{{.MemUsage}}', '--no-stream'], verbosity=CallVerbosity.DEBUG ) seen_memusage_cid_len, seen_memusage = _parse_mem_usage(code, out) + + out, err, code = call( + ctx, + [container_path, 'stats', '--format', '{{.ID}},{{.CPUPerc}}', '--no-stream'], + verbosity=CallVerbosity.DEBUG + ) + seen_cpuperc_cid_len, seen_cpuperc = _parse_cpu_perc(code, out) # /var/lib/ceph if os.path.exists(data_dir): @@ -6364,6 +6372,7 @@ def list_daemons(ctx, detail=True, legacy_dir=None): val['container_image_digests'] = image_digests if container_id: val['memory_usage'] = seen_memusage.get(container_id[0:seen_memusage_cid_len]) + val['cpu_percentage'] = seen_cpuperc.get(container_id[0:seen_cpuperc_cid_len]) val['version'] = version val['started'] = start_stamp val['created'] = get_file_timestamp( @@ -6373,9 +6382,11 @@ def list_daemons(ctx, detail=True, legacy_dir=None): os.path.join(data_dir, fsid, j, 'unit.image')) val['configured'] = get_file_timestamp( os.path.join(data_dir, fsid, j, 'unit.configured')) - + + logger.info("helo %s", val) ls.append(val) + logger.info("waah %s", ls) return ls @@ -6396,6 +6407,20 @@ def _parse_mem_usage(code: int, out: str) -> Tuple[int, Dict[str, int]]: pass return seen_memusage_cid_len, seen_memusage +def _parse_cpu_perc(code: int, out: str): + seen_cpuperc = {} + seen_cpuperc_cid_len = 0 + if not code: + for line in out.splitlines(): + (cid, cpuperc) = line.split(',') + try: + seen_cpuperc[cid] = cpuperc + if not seen_cpuperc_cid_len: + seen_cpuperc_cid_len = len(cid) + except ValueError: + logger.info('unable to parse cpu percentage line\n>{}'.format(line)) + pass + return seen_cpuperc_cid_len, seen_cpuperc def get_daemon_description(ctx, fsid, name, detail=False, legacy_dir=None): # type: (CephadmContext, str, str, bool, Optional[str]) -> Dict[str, str] diff --git a/src/pybind/mgr/cephadm/module.py b/src/pybind/mgr/cephadm/module.py index d862d2eecd345..0a3a222e28073 100644 --- a/src/pybind/mgr/cephadm/module.py +++ b/src/pybind/mgr/cephadm/module.py @@ -754,6 +754,7 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule, sd.memory_usage = d.get('memory_usage') sd.memory_request = d.get('memory_request') sd.memory_limit = d.get('memory_limit') + sd.cpu_percentage = d.get('cpu_percentage') sd._service_name = d.get('service_name') sd.deployed_by = d.get('deployed_by') sd.version = d.get('version') diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts index adb2c1871dfa1..1870b14bfb603 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-daemon-list/service-daemon-list.component.ts @@ -31,6 +31,7 @@ import { CdTableSelection } from '~/app/shared/models/cd-table-selection'; import { Daemon } from '~/app/shared/models/daemon.interface'; import { Permissions } from '~/app/shared/models/permissions'; import { CephServiceSpec } from '~/app/shared/models/service.interface'; +import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe'; import { RelativeDatePipe } from '~/app/shared/pipes/relative-date.pipe'; import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; import { NotificationService } from '~/app/shared/services/notification.service'; @@ -81,6 +82,7 @@ export class ServiceDaemonListComponent implements OnInit, OnChanges, AfterViewI private cephServiceService: CephServiceService, private orchService: OrchestratorService, private relativeDatePipe: RelativeDatePipe, + private dimlessBinaryPipe: DimlessBinaryPipe, public actionLabels: ActionLabelsI18n, private authStorageService: AuthStorageService, private daemonService: DaemonService, @@ -188,6 +190,17 @@ export class ServiceDaemonListComponent implements OnInit, OnChanges, AfterViewI prop: 'events', flexGrow: 5, cellTemplate: this.listTpl + }, + { + name: $localize`Memory Usage`, + prop: 'memory_usage', + flexGrow: 1, + pipe: this.dimlessBinaryPipe + }, + { + name: $localize`CPU %`, + prop: 'cpu_percentage', + flexGrow: 1 } ]; diff --git a/src/pybind/mgr/orchestrator/_interface.py b/src/pybind/mgr/orchestrator/_interface.py index b4f11bf1e78f7..214df05ee4bf6 100644 --- a/src/pybind/mgr/orchestrator/_interface.py +++ b/src/pybind/mgr/orchestrator/_interface.py @@ -849,6 +849,7 @@ class DaemonDescription(object): memory_usage: Optional[int] = None, memory_request: Optional[int] = None, memory_limit: Optional[int] = None, + cpu_percentage: Optional[str] = None, service_name: Optional[str] = None, ports: Optional[List[int]] = None, ip: Optional[str] = None, @@ -911,6 +912,8 @@ class DaemonDescription(object): self.memory_request: Optional[int] = memory_request self.memory_limit: Optional[int] = memory_limit + self.cpu_percentage: Optional[str] = cpu_percentage + self.ports: Optional[List[int]] = ports self.ip: Optional[str] = ip @@ -1034,6 +1037,7 @@ class DaemonDescription(object): out['memory_usage'] = self.memory_usage out['memory_request'] = self.memory_request out['memory_limit'] = self.memory_limit + out['cpu_percentage'] = self.cpu_percentage out['version'] = self.version out['status'] = self.status.value if self.status is not None else None out['status_desc'] = self.status_desc @@ -1071,6 +1075,7 @@ class DaemonDescription(object): out['memory_usage'] = self.memory_usage out['memory_request'] = self.memory_request out['memory_limit'] = self.memory_limit + out['cpu_percentage'] = self.cpu_percentage out['version'] = self.version out['status'] = self.status.value if self.status is not None else None out['status_desc'] = self.status_desc -- 2.39.5