From: Dan Mick Date: Wed, 19 Apr 2017 03:47:29 +0000 (-0700) Subject: ceph.in, pybind/ceph_daemon.py: allow stat filter patterns X-Git-Tag: v12.0.3~71^2~12 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=51809cce7233828e312e8d4d1bbddab690266207;p=ceph.git ceph.in, pybind/ceph_daemon.py: allow stat filter patterns optional second argument to ceph Signed-off-by: Dan Mick --- diff --git a/src/ceph.in b/src/ceph.in index 1068167d66bb..4b6684989122 100755 --- a/src/ceph.in +++ b/src/ceph.in @@ -266,8 +266,9 @@ ping Send simple presence/life test to a mon may be 'mon.*' for all mons daemon {type.id|path} Same as --admin-daemon, but auto-find admin socket -daemonperf {type.id | path} [] [] +daemonperf {type.id | path} [stat-pats] [] [] Get selected perf stats from daemon/admin socket + Optional shell-glob comma-delim match string stat-pats Run times (default forever), once per 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 ### diff --git a/src/pybind/ceph_daemon.py b/src/pybind/ceph_daemon.py index f91012568f48..6d5d14c97e6f 100755 --- a/src/pybind/ceph_daemon.py +++ b/src/pybind/ceph_daemon.py @@ -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']