From 9f67de8067106c3d3ceff07bf61cab4b31e6bf01 Mon Sep 17 00:00:00 2001 From: alfonsomthd Date: Thu, 21 Mar 2019 12:58:55 +0100 Subject: [PATCH] mgr/dashboard: mimic fix: show I/O stats in Pool list MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * Applied same fix as in nautilus. * Adapted Pool list columns to avoid constant resizing. * Added 'decimals' argument to dimless pipe in order for stats to fit in Pool list columns. Fixes: https://tracker.ceph.com/issues/38284 Signed-off-by: Alfonso Martínez --- .../dashboard/health/health.component.html | 16 +++++++-------- .../src/app/shared/pipes/dimless.pipe.spec.ts | 20 +++++++++++++++++++ .../src/app/shared/pipes/dimless.pipe.ts | 10 ++++++++-- .../shared/services/formatter.service.spec.ts | 1 + .../app/shared/services/formatter.service.ts | 13 +++++++++--- src/pybind/mgr/dashboard/module.py | 15 ++++++++++++++ .../mgr/dashboard/services/ceph_service.py | 15 ++------------ 7 files changed, 64 insertions(+), 26 deletions(-) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html index ca27ddfb51a56..3799c4334039a 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html @@ -134,10 +134,10 @@ Name PG status Usage - Read - Write + Read Bytes + Read Ops + Write Bytes + Write Ops @@ -150,16 +150,16 @@ - {{ pool.stats.rd_bytes.rate | dimless }} + {{ pool.stats.rd_bytes.rate | dimless:1 }} - {{ pool.stats.rd.rate | dimless }} ops + {{ pool.stats.rd.rate | dimless:1 }} ops - {{ pool.stats.wr_bytes.rate | dimless }} + {{ pool.stats.wr_bytes.rate | dimless:1 }} - {{ pool.stats.wr.rate | dimless }} ops + {{ pool.stats.wr.rate | dimless:1 }} ops diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.spec.ts index edc7fe181baaf..af5943e79e76c 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.spec.ts @@ -9,6 +9,26 @@ describe('DimlessPipe', () => { expect(pipe).toBeTruthy(); }); + it('transforms 1230.4567 with default decimals (4)', () => { + const value = 1234.5678; + expect(pipe.transform(value)).toBe('1.2346k'); + }); + + it('transforms 1230.4567 with 0 decimals', () => { + const value = 1234.5678; + expect(pipe.transform(value, 0)).toBe('1k'); + }); + + it('transforms 1230.4567 with 1 decimal', () => { + const value = 1234.5678; + expect(pipe.transform(value, 1)).toBe('1.2k'); + }); + + it('transforms 55.01 with 1 decimal', () => { + const value = 55.01; + expect(pipe.transform(value, 1)).toBe('55'); + }); + it('transforms 1000^0', () => { const value = Math.pow(1000, 0); expect(pipe.transform(value)).toBe('1'); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.ts index 89fbe8ac28857..a85a9f83041e7 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.ts @@ -1,13 +1,19 @@ import { Pipe, PipeTransform } from '@angular/core'; import { FormatterService } from '../services/formatter.service'; +import * as _ from 'lodash'; + @Pipe({ name: 'dimless' }) export class DimlessPipe implements PipeTransform { constructor(private formatter: FormatterService) {} - transform(value: any, args?: any): any { + transform(value: any, decimals?: number): any { + if (_.isUndefined(decimals)) { + decimals = 4; + } + return this.formatter.format_number(value, 1000, [ '', 'k', @@ -18,6 +24,6 @@ export class DimlessPipe implements PipeTransform { 'E', 'Z', 'Y' - ]); + ], decimals); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.spec.ts index f04fbdc4abef5..4cbbc041468dc 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.spec.ts @@ -61,6 +61,7 @@ describe('FormatterService', () => { expect(service.format_number('1.2', 1024, formats)).toBe('1.2B'); expect(service.format_number('1', 1024, formats)).toBe('1B'); expect(service.format_number('1024', 1024, formats)).toBe('1KiB'); + expect(service.format_number(55.000001, 1000, formats, 1)).toBe('55B'); expect(service.format_number(23.45678 * Math.pow(1024, 3), 1024, formats)).toBe('23.4568GiB'); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.ts index c4c610ad3e85a..67ecbaa55ce99 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.ts @@ -26,9 +26,16 @@ export class FormatterService { if (!_.isNumber(n)) { return '-'; } - const unit = n < 1 ? 0 : Math.floor(Math.log(n) / Math.log(divisor)); - const truncatedFloat = this.truncate(n / Math.pow(divisor, unit), decimals); - return truncatedFloat === '' ? '-' : truncatedFloat + units[unit]; + let unit = n < 1 ? 0 : Math.floor(Math.log(n) / Math.log(divisor)); + unit = unit >= units.length ? units.length - 1 : unit; + let result = _.round(n / Math.pow(divisor, unit), decimals).toString(); + if (result === '') { + return '-'; + } + if (units[unit] !== '') { + result = `${result}${units[unit]}`; + } + return result; } /** diff --git a/src/pybind/mgr/dashboard/module.py b/src/pybind/mgr/dashboard/module.py index 0b53743d74342..9467fd723521a 100644 --- a/src/pybind/mgr/dashboard/module.py +++ b/src/pybind/mgr/dashboard/module.py @@ -4,6 +4,7 @@ openATTIC mgr plugin (based on CherryPy) """ from __future__ import absolute_import +import collections import errno from distutils.version import StrictVersion from distutils.util import strtobool @@ -11,6 +12,7 @@ import os import socket import tempfile import threading +import time from uuid import uuid4 from OpenSSL import crypto @@ -247,6 +249,9 @@ class Module(MgrModule, CherryPyConfig): ] OPTIONS.extend(options_schema_list()) + __pool_stats = collections.defaultdict(lambda: collections.defaultdict( + lambda: collections.deque(maxlen=10))) + def __init__(self, *args, **kwargs): super(Module, self).__init__(*args, **kwargs) CherryPyConfig.__init__(self) @@ -358,6 +363,16 @@ class Module(MgrModule, CherryPyConfig): def notify(self, notify_type, notify_id): NotificationQueue.new_notification(notify_type, notify_id) + def get_updated_pool_stats(self): + df = self.get('df') + pool_stats = dict([(p['id'], p['stats']) for p in df['pools']]) + now = time.time() + for pool_id, stats in pool_stats.items(): + for stat_name, stat_val in stats.items(): + self.__pool_stats[pool_id][stat_name].append((now, stat_val)) + + return self.__pool_stats + class StandbyModule(MgrStandbyModule, CherryPyConfig): def __init__(self, *args, **kwargs): diff --git a/src/pybind/mgr/dashboard/services/ceph_service.py b/src/pybind/mgr/dashboard/services/ceph_service.py index 4925f806c945a..9857944ccc9fa 100644 --- a/src/pybind/mgr/dashboard/services/ceph_service.py +++ b/src/pybind/mgr/dashboard/services/ceph_service.py @@ -1,9 +1,6 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import -import time -import collections -from collections import defaultdict import json from mgr_module import CommandResult @@ -83,15 +80,7 @@ class CephService(object): pools_w_stats = [] pg_summary = mgr.get("pg_summary") - pool_stats = defaultdict(lambda: defaultdict( - lambda: collections.deque(maxlen=10))) - - df = mgr.get("df") - pool_stats_dict = dict([(p['id'], p['stats']) for p in df['pools']]) - now = time.time() - for pool_id, stats in pool_stats_dict.items(): - for stat_name, stat_val in stats.items(): - pool_stats[pool_id][stat_name].appendleft((now, stat_val)) + pool_stats = mgr.get_updated_pool_stats() for pool in pools: pool['pg_status'] = pg_summary['by_pool'][pool['pool'].__str__()] @@ -100,7 +89,7 @@ class CephService(object): def get_rate(series): if len(series) >= 2: - return differentiate(*series[0:1]) + return differentiate(*list(series)[-2:]) return 0 for stat_name, stat_series in stats.items(): -- 2.39.5