]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph.in, pybind/ceph_daemon.py: allow stat filter patterns
authorDan Mick <dan.mick@redhat.com>
Wed, 19 Apr 2017 03:47:29 +0000 (20:47 -0700)
committerDan Mick <dan.mick@redhat.com>
Tue, 25 Apr 2017 23:19:02 +0000 (16:19 -0700)
optional second argument to ceph

Signed-off-by: Dan Mick <dan.mick@redhat.com>
src/ceph.in
src/pybind/ceph_daemon.py

index 1068167d66bbd5e926a22ea4873c33eb01daceed..4b668498912280b1c4dadf05d5a3bac2ea13a4cd 100755 (executable)
@@ -266,8 +266,9 @@ 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} [<interval>] [<count>]
+daemonperf {type.id | path} [stat-pats] [<interval>] [<count>]
                         Get selected perf stats from daemon/admin socket
+                        Optional shell-glob comma-delim match string stat-pats
                         Run <count> times (default forever),
                         once per <interval> seconds (default 1)
     """, file=sys.stdout)
@@ -612,10 +613,24 @@ def maybe_daemon_command(parsed_args, childargs):
     return False, 0
 
 
+def isnum(object):
+    try:
+        float(object)
+        return True
+    except ValueError:
+        return False
+
 def daemonperf(childargs, sockpath):
     """ Handle daemonperf command; returns errno or 0 """
     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(',')
+
     if len(childargs) > 0:
         try:
             interval = float(childargs[0])
@@ -629,7 +644,7 @@ def daemonperf(childargs, sockpath):
             print('daemonperf: count should be a positive integer', file=sys.stderr)
             return errno.EINVAL
         count = int(childargs[1])
-    DaemonWatcher(sockpath).run(interval, count)
+    DaemonWatcher(sockpath, statpats).run(interval, count)
     return 0
 
 ###
index f91012568f48d95ee8cccce5cb338ca28660efa9..6d5d14c97e6f374a9addcde27af9f4dc6f0cdfa8 100755 (executable)
@@ -17,6 +17,7 @@ import struct
 import time
 from collections import defaultdict, OrderedDict
 from fcntl import ioctl
+from fnmatch import fnmatch
 from signal import signal, SIGWINCH
 from termios import TIOCGWINSZ
 
@@ -134,12 +135,13 @@ class DaemonWatcher(object):
     BOLD_SEQ = "\033[1m"
     UNDERLINE_SEQ = "\033[4m"
 
-    def __init__(self, asok):
+    def __init__(self, asok, statpats=None):
         self.asok_path = asok
         self._colored = False
 
         self._stats = None
         self._schema = None
+        self._statpats = statpats
         self._stats_that_fit = dict()
         self.termsize = Termsize()
 
@@ -290,6 +292,28 @@ class DaemonWatcher(object):
         val_row = val_row[0:-len(self.colorize("|", self.BLUE))]
         ostr.write("{0}\n".format(val_row))
 
+    def _should_include(self, sect, name, prio):
+        MIN_PRIO = 5
+        '''
+        boolean: should we output this stat?
+
+        1) If self._statpats exists and the name filename-glob matches anything in the list,
+           and prio is high enough, or
+        2) If self._statpats doesn't exist and prio is high enough
+
+        then yes.
+        '''
+        print sect, name, self._statpats,
+        if self._statpats:
+            sectname = '.'.join((sect, name))
+            if not any([
+                p for p in self._statpats
+                if fnmatch(name, p) or fnmatch(sectname, p)
+            ]):
+                return False
+
+        return (prio >= MIN_PRIO)
+
     def _load_schema(self):
         """
         Populate our instance-local copy of the daemon's performance counter
@@ -299,12 +323,12 @@ class DaemonWatcher(object):
             admin_socket(self.asok_path, ["perf", "schema"]).decode('utf-8'),
             object_pairs_hook=OrderedDict)
 
-        # Build list of which stats we will display, based on which
-        # stats have a nickname
+        # Build list of which stats we will display
         self._stats = OrderedDict()
         for section_name, section_stats in self._schema.items():
             for name, schema_data in section_stats.items():
-                if schema_data.get('nick'):
+                prio = schema_data.get('priority')
+                if self._should_include(section_name, name, prio):
                     if section_name not in self._stats:
                         self._stats[section_name] = OrderedDict()
                     self._stats[section_name][name] = schema_data['nick']