]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph.in, pybind/ceph_daemon.py: add priority filtering
authorDan Mick <dan.mick@redhat.com>
Fri, 21 Apr 2017 18:15:34 +0000 (11:15 -0700)
committerDan Mick <dan.mick@redhat.com>
Tue, 25 Apr 2017 23:19:02 +0000 (16:19 -0700)
Signed-off-by: Dan Mick <dan.mick@redhat.com>
src/ceph.in
src/pybind/ceph_daemon.py

index 4b668498912280b1c4dadf05d5a3bac2ea13a4cd..62a8562aed8184b1fdaa4baee04068a89e7a1cae 100755 (executable)
@@ -38,6 +38,15 @@ FLAG_NOFORWARD  = (1 << 0)
 FLAG_OBSOLETE   = (1 << 1)
 FLAG_DEPRECATED = (1 << 2)
 
+# priorities from src/common/perf_counters.h
+PRIO_CRITICAL = 10
+PRIO_INTERESTING = 8
+PRIO_USEFUL = 5
+PRIO_UNINTERESTING = 2
+PRIO_DEBUGONLY = 0
+
+PRIO_DEFAULT = PRIO_USEFUL
+
 # Make life easier on developers:
 # If in src/, and .libs and pybind exist here, assume we're running
 # from a Ceph source dir and tweak PYTHONPATH and LD_LIBRARY_PATH
@@ -266,11 +275,13 @@ ping <mon.id>           Send simple presence/life test to a mon
                         <mon.id> may be 'mon.*' for all mons
 daemon {type.id|path} <cmd>
                         Same as --admin-daemon, but auto-find admin socket
-daemonperf {type.id | path} [stat-pats] [<interval>] [<count>]
+daemonperf {type.id | path} [stat-pats] [priority] [<interval>] [<count>]
                         Get selected perf stats from daemon/admin socket
                         Optional shell-glob comma-delim match string stat-pats
+                        Optional selection priority (can abbreviate name):
+                         critical, interesting, useful, noninteresting, debug
                         Run <count> times (default forever),
-                        once per <interval> seconds (default 1)
+                         once per <interval> seconds (default 1)
     """, file=sys.stdout)
 
 
@@ -613,38 +624,74 @@ def maybe_daemon_command(parsed_args, childargs):
     return False, 0
 
 
-def isnum(object):
+def isnum(s):
     try:
-        float(object)
+        float(s)
         return True
     except ValueError:
         return False
 
 def daemonperf(childargs, sockpath):
-    """ Handle daemonperf command; returns errno or 0 """
+    """
+    Handle daemonperf command; returns errno or 0
+
+    daemonperf <daemon> [priority string] [statpats] [interval] [count]
+    """
+
     interval = 1
     count = None
     statpats = None
-
-    if len(childargs) > 0:
-        # optional leading comma-separated list arg
-        if not isnum(childargs[0]):
-            statpats = childargs.pop(0).split(',')
+    priority = None
+
+    def prio_from_name(arg):
+
+        PRIOMAP = {
+            'critical': PRIO_CRITICAL,
+            'interesting': PRIO_INTERESTING,
+            'useful': PRIO_USEFUL,
+            'uninteresting': PRIO_UNINTERESTING,
+            'debugonly': PRIO_DEBUGONLY,
+        }
+
+        if arg in PRIOMAP:
+            return PRIOMAP[arg]
+        # allow abbreviation
+        for name, val in PRIOMAP.items():
+            if name.startswith(arg):
+                return val
+        return None
+
+    # consume and analyze non-numeric args
+    while len(childargs) and not isnum(childargs[0]):
+        arg = childargs.pop(0)
+        # prio?
+        priority = prio_from_name(arg)
+        if priority is not None:
+            continue;
+        # statpats
+        statpats = arg.split(',')
+
+    if priority is None:
+        priority = PRIO_DEFAULT
 
     if len(childargs) > 0:
         try:
-            interval = float(childargs[0])
+            interval = float(childargs.pop(0))
             if interval < 0:
                 raise ValueError
         except ValueError:
             print('daemonperf: interval should be a positive number', file=sys.stderr)
             return errno.EINVAL
-    if len(childargs) > 1:
-        if not childargs[1].isdigit():
+
+    if len(childargs) > 0:
+        arg = childargs.pop(0)
+        if (not isnum(arg)) or (int(arg) < 0):
             print('daemonperf: count should be a positive integer', file=sys.stderr)
             return errno.EINVAL
-        count = int(childargs[1])
-    DaemonWatcher(sockpath, statpats).run(interval, count)
+        count = int(arg)
+
+    DaemonWatcher(sockpath, statpats, priority).run(interval, count)
+
     return 0
 
 ###
index 605872b1bc2118779eb28403cc538ce19dba2ad6..827f7abf22a28eb5b661d73b86a9e618684d9130 100755 (executable)
@@ -15,7 +15,7 @@ import json
 import socket
 import struct
 import time
-from collections import defaultdict, OrderedDict
+from collections import OrderedDict
 from fcntl import ioctl
 from fnmatch import fnmatch
 from signal import signal, SIGWINCH
@@ -135,7 +135,7 @@ class DaemonWatcher(object):
     BOLD_SEQ = "\033[1m"
     UNDERLINE_SEQ = "\033[4m"
 
-    def __init__(self, asok, statpats=None):
+    def __init__(self, asok, statpats=None, min_prio=0):
         self.asok_path = asok
         self._colored = False
 
@@ -143,6 +143,7 @@ class DaemonWatcher(object):
         self._schema = None
         self._statpats = statpats
         self._stats_that_fit = dict()
+        self._min_prio = min_prio
         self.termsize = Termsize()
 
     def supports_color(self, ostr):
@@ -297,7 +298,6 @@ class DaemonWatcher(object):
         ostr.write("{0}\n".format(val_row))
 
     def _should_include(self, sect, name, prio):
-        MIN_PRIO = 5
         '''
         boolean: should we output this stat?
 
@@ -307,7 +307,6 @@ class DaemonWatcher(object):
 
         then yes.
         '''
-        print sect, name, self._statpats,
         if self._statpats:
             sectname = '.'.join((sect, name))
             if not any([
@@ -316,7 +315,10 @@ class DaemonWatcher(object):
             ]):
                 return False
 
-        return (prio >= MIN_PRIO)
+        if self._min_prio is not None and prio is not None:
+            return (prio >= self._min_prio)
+
+        return True
 
     def _load_schema(self):
         """
@@ -336,6 +338,8 @@ class DaemonWatcher(object):
                     if section_name not in self._stats:
                         self._stats[section_name] = OrderedDict()
                     self._stats[section_name][name] = schema_data['nick']
+        if not len(self._stats):
+            raise RuntimeError("no stats selected by filters")
 
     def _handle_sigwinch(self, signo, frame):
         self.termsize.update()