summaryrefslogtreecommitdiff
path: root/qpid/python
diff options
context:
space:
mode:
authorTed Ross <tross@apache.org>2009-02-26 21:26:47 +0000
committerTed Ross <tross@apache.org>2009-02-26 21:26:47 +0000
commitadbb618fa2ae734cc9f87e57ae15df14c77edf77 (patch)
treea6301e3a66a976d7cb1e6dd1b23fd71f625d0542 /qpid/python
parent7b30a9adbf13432dd8d7bf0abe868ed773d2ad16 (diff)
downloadqpid-python-adbb618fa2ae734cc9f87e57ae15df14c77edf77.tar.gz
Improvements to qpid-stat:
Support for exchanges and queues Sorting and limiting Improved table formatting git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@748315 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/python')
-rwxr-xr-xqpid/python/commands/qpid-stat216
-rw-r--r--qpid/python/qpid/disp.py138
2 files changed, 275 insertions, 79 deletions
diff --git a/qpid/python/commands/qpid-stat b/qpid/python/commands/qpid-stat
index 2ac0cad9af..9d41f4e966 100755
--- a/qpid/python/commands/qpid-stat
+++ b/qpid/python/commands/qpid-stat
@@ -26,11 +26,14 @@ import locale
import socket
import re
from qmf.console import Session, Console
-from qpid.disp import Display
+from qpid.disp import Display, Header, Sorter
_host = "localhost"
_top = False
_types = ""
+_limit = 50
+_increasing = False
+_sortcol = None
pattern = re.compile("^\\d+\\.\\d+\\.\\d+\\.\\d+:\\d+$")
def Usage ():
@@ -48,23 +51,15 @@ def Usage ():
print " -b Show Brokers"
print " -c Show Connections"
# print " -s Show Sessions"
-# print " -e Show Exchanges"
-# print " -q Show Queues"
+ print " -e Show Exchanges"
+ print " -q Show Queues"
+ print
+ print " -S [--sort-by] COLNAME Sort by column name"
+ print " -I [--increasing] Sort by increasing value (default = decreasing)"
+ print " -L [--limit] NUM Limit output to NUM rows (default = 50)"
print
sys.exit (1)
-def num(value):
- if value < 2000:
- return str(value)
- value /= 1000
- if value < 2000:
- return str(value) + "k"
- value /= 1000
- if value < 2000:
- return str(value) + "m"
- value /= 1000
- return str(value) + "g"
-
class IpAddr:
def __init__(self, text):
if text.find("@") != -1:
@@ -93,7 +88,6 @@ class IpAddr:
class Broker(object):
def __init__(self, qmf, broker):
self.broker = broker
- list = qmf.getObjects(_class="connection", _package="org.apache.qpid.broker", _broker=broker)
bobj = qmf.getObjects(_class="broker", _package="org.apache.qpid.broker", _broker=broker)[0]
self.currentTime = bobj.getTimestamps()[0]
try:
@@ -104,17 +98,23 @@ class Broker(object):
self.sessions = {}
self.exchanges = {}
self.queues = {}
+ package = "org.apache.qpid.broker"
+
+ list = qmf.getObjects(_class="connection", _package=package, _broker=broker)
for conn in list:
if pattern.match(conn.address):
self.connections[conn.getObjectId()] = conn
- list = qmf.getObjects(_class="session", _package="org.apache.qpid.broker", _broker=broker)
+
+ list = qmf.getObjects(_class="session", _package=package, _broker=broker)
for sess in list:
if sess.connectionRef in self.connections:
self.sessions[sess.getObjectId()] = sess
- list = qmf.getObjects(_class="exchange", _package="org.apache.qpid.broker", _broker=broker)
+
+ list = qmf.getObjects(_class="exchange", _package=package, _broker=broker)
for exchange in list:
self.exchanges[exchange.getObjectId()] = exchange
- list = qmf.getObjects(_class="queue", _package="org.apache.qpid.broker", _broker=broker)
+
+ list = qmf.getObjects(_class="queue", _package=package, _broker=broker)
for queue in list:
self.queues[queue.getObjectId()] = queue
@@ -209,34 +209,45 @@ class BrokerManager(Console):
def displayBroker(self, subs):
disp = Display(prefix=" ")
- heads = ('Broker', 'cluster', 'uptime', 'conn', 'sess', 'exch', 'queue')
+ heads = []
+ heads.append(Header('broker'))
+ heads.append(Header('cluster'))
+ heads.append(Header('uptime', Header.DURATION))
+ heads.append(Header('conn', Header.KMG))
+ heads.append(Header('sess', Header.KMG))
+ heads.append(Header('exch', Header.KMG))
+ heads.append(Header('queue', Header.KMG))
rows = []
for broker in self.brokers:
if self.cluster:
ctext = "%s(%s)" % (self.cluster.clusterName, self.cluster.status)
else:
ctext = "<standalone>"
- utext = ""
- if broker.getUptime() > 0:
- utext = disp.duration(broker.getUptime())
- row = (broker.getName(), ctext, utext,
- str(len(broker.connections)), str(len(broker.sessions)),
- str(len(broker.exchanges)), str(len(broker.queues)))
+ row = (broker.getName(), ctext, broker.getUptime(),
+ len(broker.connections), len(broker.sessions),
+ len(broker.exchanges), len(broker.queues))
rows.append(row)
- disp.table("Brokers", heads, rows)
+ title = "Brokers"
+ if _sortcol:
+ sorter = Sorter(heads, rows, _sortcol, _limit, _increasing)
+ dispRows = sorter.getSorted()
+ else:
+ dispRows = rows
+ disp.formattedTable(title, heads, dispRows)
def displayConn(self, subs):
disp = Display(prefix=" ")
heads = []
if self.cluster:
- heads.append('broker')
- heads.append('client addr')
- heads.append('client(pid)')
- heads.append('auth')
- heads.append('connected')
- heads.append('idle')
- heads.append('msgIn')
- heads.append('msgOut')
+ heads.append(Header('broker'))
+ heads.append(Header('client-addr'))
+ heads.append(Header('cproc'))
+ heads.append(Header('cpid'))
+ heads.append(Header('auth'))
+ heads.append(Header('connected', Header.DURATION))
+ heads.append(Header('idle', Header.DURATION))
+ heads.append(Header('msgIn', Header.KMG))
+ heads.append(Header('msgOut', Header.KMG))
rows = []
for broker in self.brokers:
for oid in broker.connections:
@@ -245,27 +256,24 @@ class BrokerManager(Console):
if self.cluster:
row.append(broker.getName())
row.append(conn.address)
- procpid = ""
- if conn.remoteProcessName:
- procpid += conn.remoteProcessName
- if conn.remotePid:
- procpid += "(%d)" % conn.remotePid
- row.append(procpid)
+ row.append(conn.remoteProcessName)
+ row.append(conn.remotePid)
row.append(conn.authIdentity)
- row.append(disp.duration(broker.getCurrentTime() - conn.getTimestamps()[1]))
+ row.append(broker.getCurrentTime() - conn.getTimestamps()[1])
idle = broker.getCurrentTime() - conn.getTimestamps()[0]
- if idle < 10000000000:
- itext = ""
- else:
- itext = disp.duration(idle)
- row.append(itext)
- row.append(num(conn.framesFromClient))
- row.append(num(conn.framesToClient))
+ row.append(broker.getCurrentTime() - conn.getTimestamps()[0])
+ row.append(conn.framesFromClient)
+ row.append(conn.framesToClient)
rows.append(row)
title = "Connections"
if self.cluster:
title += " for cluster '%s'" % self.cluster.clusterName
- disp.table(title, heads, rows)
+ if _sortcol:
+ sorter = Sorter(heads, rows, _sortcol, _limit, _increasing)
+ dispRows = sorter.getSorted()
+ else:
+ dispRows = rows
+ disp.formattedTable(title, heads, dispRows)
def displaySession(self, subs):
disp = Display(prefix=" ")
@@ -274,17 +282,17 @@ class BrokerManager(Console):
disp = Display(prefix=" ")
heads = []
if self.cluster:
- heads.append('broker')
- heads.append("exchange")
- heads.append("type")
- heads.append("dur")
- heads.append("bind")
- heads.append("msgIn")
- heads.append("msgOut")
- heads.append("msgDrop")
- heads.append("byteIn")
- heads.append("byteOut")
- heads.append("byteDrop")
+ heads.append(Header('broker'))
+ heads.append(Header("exchange"))
+ heads.append(Header("type"))
+ heads.append(Header("dur", Header.Y))
+ heads.append(Header("bind", Header.KMG))
+ heads.append(Header("msgIn", Header.KMG))
+ heads.append(Header("msgOut", Header.KMG))
+ heads.append(Header("msgDrop", Header.KMG))
+ heads.append(Header("byteIn", Header.KMG))
+ heads.append(Header("byteOut", Header.KMG))
+ heads.append(Header("byteDrop", Header.KMG))
rows = []
for broker in self.brokers:
for oid in broker.exchanges:
@@ -292,31 +300,80 @@ class BrokerManager(Console):
row = []
if self.cluster:
row.append(broker.getName())
- if ex.durable:
- dur = "Y"
- else:
- dur = ""
row.append(ex.name)
row.append(ex.type)
- row.append(dur)
- row.append(num(ex.bindingCount))
- row.append(num(ex.msgReceives))
- row.append(num(ex.msgRoutes))
- row.append(num(ex.msgDrops))
- row.append(num(ex.byteReceives))
- row.append(num(ex.byteRoutes))
- row.append(num(ex.byteDrops))
+ row.append(ex.durable)
+ row.append(ex.bindingCount)
+ row.append(ex.msgReceives)
+ row.append(ex.msgRoutes)
+ row.append(ex.msgDrops)
+ row.append(ex.byteReceives)
+ row.append(ex.byteRoutes)
+ row.append(ex.byteDrops)
rows.append(row)
title = "Exchanges"
if self.cluster:
title += " for cluster '%s'" % self.cluster.clusterName
- disp.table(title, heads, rows)
+ if _sortcol:
+ sorter = Sorter(heads, rows, _sortcol, _limit, _increasing)
+ dispRows = sorter.getSorted()
+ else:
+ dispRows = rows
+ disp.formattedTable(title, heads, dispRows)
+
+ def displayQueue(self, subs):
+ disp = Display(prefix=" ")
+ heads = []
+ if self.cluster:
+ heads.append(Header('broker'))
+ heads.append(Header("queue"))
+ heads.append(Header("dur", Header.Y))
+ heads.append(Header("autoDel", Header.Y))
+ heads.append(Header("excl", Header.Y))
+ heads.append(Header("msg", Header.KMG))
+ heads.append(Header("msgIn", Header.KMG))
+ heads.append(Header("msgOut", Header.KMG))
+ heads.append(Header("bytes", Header.KMG))
+ heads.append(Header("bytesIn", Header.KMG))
+ heads.append(Header("bytesOut", Header.KMG))
+ heads.append(Header("cons", Header.KMG))
+ heads.append(Header("bind", Header.KMG))
+ rows = []
+ for broker in self.brokers:
+ for oid in broker.queues:
+ q = broker.queues[oid]
+ row = []
+ if self.cluster:
+ row.append(broker.getName())
+ row.append(q.name)
+ row.append(q.durable)
+ row.append(q.autoDelete)
+ row.append(q.exclusive)
+ row.append(q.msgDepth)
+ row.append(q.msgTotalEnqueues)
+ row.append(q.msgTotalDequeues)
+ row.append(q.byteDepth)
+ row.append(q.byteTotalEnqueues)
+ row.append(q.byteTotalDequeues)
+ row.append(q.consumerCount)
+ row.append(q.bindingCount)
+ rows.append(row)
+ title = "Queues"
+ if self.cluster:
+ title += " for cluster '%s'" % self.cluster.clusterName
+ if _sortcol:
+ sorter = Sorter(heads, rows, _sortcol, _limit, _increasing)
+ dispRows = sorter.getSorted()
+ else:
+ dispRows = rows
+ disp.formattedTable(title, heads, dispRows)
def displayMain(self, main, subs):
if main == 'b': self.displayBroker(subs)
elif main == 'c': self.displayConn(subs)
elif main == 's': self.displaySession(subs)
elif main == 'e': self.displayExchange(subs)
+ elif main == 'q': self.displayQueue(subs)
def display(self):
self._getCluster()
@@ -339,8 +396,8 @@ class BrokerManager(Console):
##
try:
- longOpts = ("top", "numeric")
- (optlist, encArgs) = getopt.gnu_getopt(sys.argv[1:], "bc", longOpts)
+ longOpts = ("top", "numeric", "sort-by=", "limit=", "increasing")
+ (optlist, encArgs) = getopt.gnu_getopt(sys.argv[1:], "bceqS:L:I", longOpts)
except:
Usage()
@@ -355,6 +412,12 @@ for opt in optlist:
_top = True
elif opt[0] == "-n" or opt[0] == "--numeric":
_numeric = True
+ elif opt[0] == "-S" or opt[0] == "--sort-by":
+ _sortcol = opt[1]
+ elif opt[0] == "-I" or opt[0] == "--increasing":
+ _increasing = True
+ elif opt[0] == "-L" or opt[0] == "--limit":
+ _limit = int(opt[1])
elif len(opt[0]) == 2:
char = opt[0][1]
if "bcseq".find(char) != -1:
@@ -380,6 +443,7 @@ except KeyboardInterrupt:
print
except Exception,e:
print "Failed:", e.args
+ #raise # TODO: Remove before flight
sys.exit(1)
bm.Disconnect()
diff --git a/qpid/python/qpid/disp.py b/qpid/python/qpid/disp.py
index eb55616f32..1b315c9d98 100644
--- a/qpid/python/qpid/disp.py
+++ b/qpid/python/qpid/disp.py
@@ -21,16 +21,108 @@
from time import strftime, gmtime
+class Header:
+ """ """
+ NONE = 1
+ KMG = 2
+ YN = 3
+ Y = 4
+ TIME_LONG = 5
+ TIME_SHORT = 6
+ DURATION = 7
+
+ def __init__(self, text, format=NONE):
+ self.text = text
+ self.format = format
+
+ def __repr__(self):
+ return self.text
+
+ def __str__(self):
+ return self.text
+
+ def formatted(self, value):
+ try:
+ if value == None:
+ return ''
+ if self.format == Header.NONE:
+ return value
+ if self.format == Header.KMG:
+ return self.num(value)
+ if self.format == Header.YN:
+ if value:
+ return 'Y'
+ return 'N'
+ if self.format == Header.Y:
+ if value:
+ return 'Y'
+ return ''
+ if self.format == Header.TIME_LONG:
+ return strftime("%c", gmtime(value / 1000000000))
+ if self.format == Header.TIME_SHORT:
+ return strftime("%X", gmtime(value / 1000000000))
+ if self.format == Header.DURATION:
+ if value < 0: value = 0
+ sec = value / 1000000000
+ min = sec / 60
+ hour = min / 60
+ day = hour / 24
+ result = ""
+ if day > 0:
+ result = "%dd " % day
+ if hour > 0 or result != "":
+ result += "%dh " % (hour % 24)
+ if min > 0 or result != "":
+ result += "%dm " % (min % 60)
+ result += "%ds" % (sec % 60)
+ return result
+ except:
+ return "?"
+
+ def numCell(self, value, tag):
+ fp = float(value) / 1000.
+ if fp < 10.0:
+ return "%1.2f%c" % (fp, tag)
+ if fp < 100.0:
+ return "%2.1f%c" % (fp, tag)
+ return "%4d%c" % (value / 1000, tag)
+
+ def num(self, value):
+ if value < 1000:
+ return "%4d" % value
+ if value < 1000000:
+ return self.numCell(value, 'k')
+ value /= 1000
+ if value < 1000000:
+ return self.numCell(value, 'm')
+ value /= 1000
+ return self.numCell(value, 'g')
+
+
class Display:
""" Display formatting for QPID Management CLI """
- def __init__ (self, spacing=2, prefix=" "):
+ def __init__(self, spacing=2, prefix=" "):
self.tableSpacing = spacing
self.tablePrefix = prefix
self.timestampFormat = "%X"
- def table (self, title, heads, rows):
- """ Print a formatted table with autosized columns """
+ def formattedTable(self, title, heads, rows):
+ fRows = []
+ for row in rows:
+ fRow = []
+ col = 0
+ for cell in row:
+ fRow.append(heads[col].formatted(cell))
+ col += 1
+ fRows.append(fRow)
+ headtext = []
+ for head in heads:
+ headtext.append(head.text)
+ self.table(title, headtext, fRows)
+
+ def table(self, title, heads, rows):
+ """ Print a table with autosized columns """
# Pad the rows to the number of heads
for row in rows:
@@ -100,3 +192,43 @@ class Display:
result += "%dm " % (min % 60)
result += "%ds" % (sec % 60)
return result
+
+class Sortable:
+ """ """
+ def __init__(self, row, sortIndex):
+ self.row = row
+ self.sortIndex = sortIndex
+ if sortIndex >= len(row):
+ raise Exception("sort index exceeds row boundary")
+
+ def __cmp__(self, other):
+ return cmp(self.row[self.sortIndex], other.row[self.sortIndex])
+
+ def getRow(self):
+ return self.row
+
+class Sorter:
+ """ """
+ def __init__(self, heads, rows, sortCol, limit=0, inc=True):
+ col = 0
+ for head in heads:
+ if head.text == sortCol:
+ break
+ col += 1
+ if col == len(heads):
+ raise Exception("sortCol '%s', not found in headers" % sortCol)
+
+ list = []
+ for row in rows:
+ list.append(Sortable(row, col))
+ list.sort(reverse=not inc)
+ count = 0
+ self.sorted = []
+ for row in list:
+ self.sorted.append(row.getRow())
+ count += 1
+ if count == limit:
+ break
+
+ def getSorted(self):
+ return self.sorted