From: Avan Thakkar Date: Thu, 7 Apr 2022 11:01:20 +0000 (+0530) Subject: mgr/dashboard: introduce memory and cpu usage for daemons X-Git-Tag: v16.2.11~564^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=049d84472061b3607b1ae89711297609837db524;p=ceph.git 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) Conflicts: src/pybind/mgr/cephadm/module.py - _process_ls_output() doesn't exist in pacific as agent isn't yet backported. So similar changes needs to be done in serve.py instead. --- diff --git a/src/cephadm/cephadm b/src/cephadm/cephadm index f53813eb5bab..67fbcf73c0a7 100755 --- a/src/cephadm/cephadm +++ b/src/cephadm/cephadm @@ -5495,12 +5495,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): @@ -5671,6 +5679,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( @@ -5680,9 +5689,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 @@ -5703,6 +5714,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/serve.py b/src/pybind/mgr/cephadm/serve.py index 4c6f50a90328..7da98ce8159a 100644 --- a/src/pybind/mgr/cephadm/serve.py +++ b/src/pybind/mgr/cephadm/serve.py @@ -320,6 +320,7 @@ class CephadmServe: 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 3decf45e773d..5337058e3ef0 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'; @@ -84,6 +85,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, @@ -185,6 +187,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 a41e7ad2d743..61ef4f5da808 100644 --- a/src/pybind/mgr/orchestrator/_interface.py +++ b/src/pybind/mgr/orchestrator/_interface.py @@ -841,6 +841,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, @@ -903,6 +904,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 @@ -1026,6 +1029,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 @@ -1063,6 +1067,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