]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/iostat: implement 'ceph iostat' as a mgr plugin
authorMohamad Gebai <mgebai@suse.com>
Tue, 23 Jan 2018 13:56:36 +0000 (08:56 -0500)
committerMohamad Gebai <mgebai@suse.com>
Thu, 12 Apr 2018 04:26:24 +0000 (00:26 -0400)
Allow a mgr module to fetch 'io_rate' to access pg_sum_delta,
which holds the IO activity recently completed by the OSDs.

Signed-off-by: Mohamad Gebai <mgebai@suse.com>
src/ceph.in
src/mgr/ActivePyModules.cc
src/mon/PGMap.cc
src/pybind/mgr/iostat/__init__.py [new file with mode: 0644]
src/pybind/mgr/iostat/module.py [new file with mode: 0644]
src/pybind/mgr/mgr_module.py

index 0814b0bd1f9707c06f9edf690012d51f2c953761..7484a54dfc8f87fe4e238ba9fee0e3a6f4d3c283 100755 (executable)
@@ -20,6 +20,7 @@ Foundation.  See file COPYING.
 """
 
 from __future__ import print_function
+from time import sleep
 import codecs
 import os
 import sys
@@ -1053,6 +1054,16 @@ def main():
         print('error handling command target: {0}'.format(e), file=sys.stderr)
         return 1
 
+    # ceph iostat
+    if len(childargs) > 0 and childargs[0] == 'iostat':
+        def call_iostat():
+            while 1:
+                subprocess.call([sys.argv[0], 'mgr', 'iostat'])
+                sleep(1)
+
+        run_in_thread(call_iostat)
+        return 1
+
     # Repulsive hack to handle tell: lop off 'tell' and target
     # and validate the rest of the command.  'target' is already
     # determined in our callers, so it's ok to remove it here.
index 08d907ec556ce54fed094749f35f966ff1b95195..215ae3ca1915ef4d401004b3a40c953558fb5ca2 100644 (file)
@@ -282,6 +282,14 @@ PyObject *ActivePyModules::get_python(const std::string &what)
         }
     );
     return f.get();
+  } else if (what == "io_rate") {
+    PyFormatter f;
+    cluster_state.with_pgmap(
+      [&f](const PGMap &pg_map) {
+        pg_map.dump_delta(&f);
+      }
+    );
+    return f.get();
   } else if (what == "df") {
     PyFormatter f;
 
index 353743771492233f0f8f1386d9dc21384328390f..4e1d6541898b95cf0012c24f024d4fad84a9d048 100644 (file)
@@ -1395,6 +1395,7 @@ void PGMap::dump_delta(Formatter *f) const
 {
   f->open_object_section("pg_stats_delta");
   pg_sum_delta.dump(f);
+  f->dump_stream("stamp_delta") << stamp_delta;
   f->close_section();
 }
 
diff --git a/src/pybind/mgr/iostat/__init__.py b/src/pybind/mgr/iostat/__init__.py
new file mode 100644 (file)
index 0000000..8f210ac
--- /dev/null
@@ -0,0 +1 @@
+from .module import Module
diff --git a/src/pybind/mgr/iostat/module.py b/src/pybind/mgr/iostat/module.py
new file mode 100644 (file)
index 0000000..65b6e5c
--- /dev/null
@@ -0,0 +1,35 @@
+
+from mgr_module import MgrModule
+
+
+class Module(MgrModule):
+    COMMANDS = [
+        {
+            "cmd": "mgr iostat",
+            "desc": "Get IO rates",
+            "perm": "r"
+        }
+    ]
+
+
+    def __init__(self, *args, **kwargs):
+        super(Module, self).__init__(*args, **kwargs)
+
+
+    def handle_command(self, command):
+        rd = 0
+        wr = 0
+        ops = 0
+
+        if command['prefix'] == 'mgr iostat':
+            r = self.get('io_rate')
+
+            stamp_delta = float(r['pg_stats_delta']['stamp_delta'])
+            if (stamp_delta > 0):
+                rd = int(r['pg_stats_delta']['stat_sum']['num_read_kb']) / stamp_delta
+                wr = int(r['pg_stats_delta']['stat_sum']['num_write_kb']) / stamp_delta
+                ops = ( int(r['pg_stats_delta']['stat_sum']['num_write']) + int(r['pg_stats_delta']['stat_sum']['num_read']) ) / stamp_delta
+
+        ret = "wr: {0} kB/s, rd: {1} kB/s, iops: {2}".format(str(int(wr)), str(int(rd)), str(int(ops)))
+
+        return 0, '', ret
index 480fc8586d0f73ac469a83178240b12930ee7d5d..b51952ebd18e08b5220284e7a44020c5176476dc 100644 (file)
@@ -314,7 +314,7 @@ class MgrModule(ceph_module.BaseMgrModule):
 
         :param str data_name: Valid things to fetch are osd_crush_map_text, 
                 osd_map, osd_map_tree, osd_map_crush, config, mon_map, fs_map,
-                osd_metadata, pg_summary, df, osd_stats, health, mon_status.
+                osd_metadata, pg_summary, io_rate, pg_dump, df, osd_stats, health, mon_status.
 
         Note:
             All these structures have their own JSON representations: experiment