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
<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)
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
###
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
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
self._schema = None
self._statpats = statpats
self._stats_that_fit = dict()
+ self._min_prio = min_prio
self.termsize = Termsize()
def supports_color(self, ostr):
ostr.write("{0}\n".format(val_row))
def _should_include(self, sect, name, prio):
- MIN_PRIO = 5
'''
boolean: should we output this stat?
then yes.
'''
- print sect, name, self._statpats,
if self._statpats:
sectname = '.'.join((sect, name))
if not any([
]):
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):
"""
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()