]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: mimic fix: show I/O stats in Pool list 27053/head
authoralfonsomthd <almartin@redhat.com>
Thu, 21 Mar 2019 11:58:55 +0000 (12:58 +0100)
committeralfonsomthd <almartin@redhat.com>
Thu, 21 Mar 2019 11:58:55 +0000 (12:58 +0100)
* 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 <almartin@redhat.com>
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/dimless.pipe.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/services/formatter.service.ts
src/pybind/mgr/dashboard/module.py
src/pybind/mgr/dashboard/services/ceph_service.py

index ca27ddfb51a563dee613149e6abb250cf361c498..3799c4334039aee353d9765115d62734ba314b75 100644 (file)
                 <th i18n>Name</th>
                 <th i18n>PG status</th>
                 <th i18n>Usage</th>
-                <th colspan="2"
-                    i18n>Read</th>
-                <th colspan="2"
-                    i18n>Write</th>
+                <th i18n width="10%">Read Bytes</th>
+                <th i18n width="10%">Read Ops</th>
+                <th i18n width="10%">Write Bytes</th>
+                <th i18n width="10%">Write Ops</th>
               </tr>
             </thead>
             <tbody>
                   <cd-usage-bar [totalBytes]="pool.stats.bytes_used.latest +  pool.stats.max_avail.latest" [usedBytes]="pool.stats.bytes_used.latest"></cd-usage-bar>
                 </td>
                 <td>
-                  {{ pool.stats.rd_bytes.rate | dimless }}
+                  {{ pool.stats.rd_bytes.rate | dimless:1 }}
                 </td>
                 <td>
-                  {{ pool.stats.rd.rate | dimless }} ops
+                  {{ pool.stats.rd.rate | dimless:1 }} ops
                 </td>
                 <td>
-                  {{ pool.stats.wr_bytes.rate | dimless }}
+                  {{ pool.stats.wr_bytes.rate | dimless:1 }}
                 </td>
                 <td>
-                  {{ pool.stats.wr.rate | dimless }} ops
+                  {{ pool.stats.wr.rate | dimless:1 }} ops
                 </td>
               </tr>
             </tbody>
index edc7fe181baaffbc1628fa2bd155807a518dbeb0..af5943e79e76c0f1298fa4f4695819c99c0d45f4 100644 (file)
@@ -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');
index 89fbe8ac288573c53edb7060100643b94bc972ce..a85a9f83041e7d86fb07c77316d20348286a7b70 100644 (file)
@@ -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);
   }
 }
index f04fbdc4abef528221e27ef475bb6d56e627a220..4cbbc041468dca6e73882dc665ac3b31b1c85edb 100644 (file)
@@ -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');
     });
 
index c4c610ad3e85a64f0feccfd29b2404d76fa01466..67ecbaa55ce996d4deb366f7e5484e5e80bfd6c2 100644 (file)
@@ -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;
   }
 
   /**
index 0b53743d7434289235a1446d13d7faa44a93591f..9467fd723521a091cf58a9b4ab81b972785d1a06 100644 (file)
@@ -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):
index 4925f806c945a7331da581a35fd1fe43a7f91a22..9857944ccc9fa499e98f0ff6e84e94774fb677ea 100644 (file)
@@ -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():