[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r22952: {arm} added: config option for graph height fix: graph panel wasn' (in arm/trunk: . interface interface/graphing)
Author: atagar
Date: 2010-08-18 16:43:36 +0000 (Wed, 18 Aug 2010)
New Revision: 22952
Modified:
arm/trunk/TODO
arm/trunk/armrc.sample
arm/trunk/interface/controller.py
arm/trunk/interface/graphing/bandwidthStats.py
arm/trunk/interface/graphing/graphPanel.py
arm/trunk/interface/graphing/psStats.py
Log:
added: config option for graph height
fix: graph panel wasn't restricting bounds for sane config options
fix: off-by-one error with graphing bounds
Modified: arm/trunk/TODO
===================================================================
--- arm/trunk/TODO 2010-08-18 16:32:14 UTC (rev 22951)
+++ arm/trunk/TODO 2010-08-18 16:43:36 UTC (rev 22952)
@@ -144,6 +144,7 @@
circuits at the exit
* look at vidalia for ideas
* need to solicit for ideas on what would be most helpful to clients
+ * interface option to change graph height
* check if batch getInfo/getOption calls provide much performance benefit
* layout (css) bugs with site
Revise to use 'em' for measurements and somehow stretch image's y-margin?
Modified: arm/trunk/armrc.sample
===================================================================
--- arm/trunk/armrc.sample 2010-08-18 16:32:14 UTC (rev 22951)
+++ arm/trunk/armrc.sample 2010-08-18 16:43:36 UTC (rev 22952)
@@ -22,16 +22,19 @@
features.log.prepopulateReadLimit 5000
# general graph parameters
+# height: height of graphed stats
+# maxWidth: maximum number of graphed entries
# interval: 0 -> each second, 1 -> 5 seconds, 2 -> 30 seconds,
# 3 -> minutely, 4 -> half hour, 5 -> hourly, 6 -> daily
# bound: 0 -> global maxima, 1 -> local maxima, 2 -> tight
# type: 0 -> None, 1 -> Bandwidth, 2 -> Connections, 3 -> System Resources
# frequentRefrsh: updates stats each second if true, otherwise matches interval
+features.graph.height 5
+features.graph.maxWidth 150
features.graph.interval 0
features.graph.bound 1
features.graph.type 1
-features.graph.maxSize 150
features.graph.frequentRefresh true
# ps graph parameters
Modified: arm/trunk/interface/controller.py
===================================================================
--- arm/trunk/interface/controller.py 2010-08-18 16:32:14 UTC (rev 22951)
+++ arm/trunk/interface/controller.py 2010-08-18 16:43:36 UTC (rev 22952)
@@ -307,7 +307,7 @@
# loads config for various interface components
config = conf.getConfig("arm")
config.update(CONFIG)
- config.update(graphing.graphPanel.CONFIG)
+ graphing.graphPanel.loadConfig(config)
# adds events needed for arm functionality to the torTools REQ_EVENTS mapping
# (they're then included with any setControllerEvents call, and log a more
Modified: arm/trunk/interface/graphing/bandwidthStats.py
===================================================================
--- arm/trunk/interface/graphing/bandwidthStats.py 2010-08-18 16:32:14 UTC (rev 22951)
+++ arm/trunk/interface/graphing/bandwidthStats.py 2010-08-18 16:43:36 UTC (rev 22952)
@@ -181,15 +181,18 @@
def draw(self, panel, width, height):
# if display is narrow, overwrites x-axis labels with avg / total stats
if width <= COLLAPSE_WIDTH:
+ # line of the graph's x-axis labeling
+ labelingLine = self.getContentHeight() + panel.graphHeight - 5
+
# clears line
- panel.addstr(8, 0, " " * width)
+ panel.addstr(labelingLine, 0, " " * width)
graphCol = min((width - 10) / 2, self.maxCol)
primaryFooter = "%s, %s" % (self._getAvgLabel(True), self._getTotalLabel(True))
secondaryFooter = "%s, %s" % (self._getAvgLabel(False), self._getTotalLabel(False))
- panel.addstr(8, 1, primaryFooter, uiTools.getColor(self.getColor(True)))
- panel.addstr(8, graphCol + 6, secondaryFooter, uiTools.getColor(self.getColor(False)))
+ panel.addstr(labelingLine, 1, primaryFooter, uiTools.getColor(self.getColor(True)))
+ panel.addstr(labelingLine, graphCol + 6, secondaryFooter, uiTools.getColor(self.getColor(False)))
# provides accounting stats if enabled
if self.isAccounting:
@@ -203,21 +206,21 @@
# failed to be queried
status, hibernateColor = "unknown", "red"
- panel.addfstr(10, 0, "<b>Accounting (<%s>%s</%s>)</b>" % (hibernateColor, status, hibernateColor))
+ panel.addfstr(labelingLine + 2, 0, "<b>Accounting (<%s>%s</%s>)</b>" % (hibernateColor, status, hibernateColor))
resetTime = self.accountingInfo["resetTime"]
if not resetTime: resetTime = "unknown"
- panel.addstr(10, 35, "Time to reset: %s" % resetTime)
+ panel.addstr(labelingLine + 2, 35, "Time to reset: %s" % resetTime)
used, total = self.accountingInfo["read"], self.accountingInfo["readLimit"]
if used and total:
- panel.addstr(11, 2, "%s / %s" % (used, total), uiTools.getColor(self.getColor(True)))
+ panel.addstr(labelingLine + 3, 2, "%s / %s" % (used, total), uiTools.getColor(self.getColor(True)))
used, total = self.accountingInfo["written"], self.accountingInfo["writtenLimit"]
if used and total:
- panel.addstr(11, 37, "%s / %s" % (used, total), uiTools.getColor(self.getColor(False)))
+ panel.addstr(labelingLine + 3, 37, "%s / %s" % (used, total), uiTools.getColor(self.getColor(False)))
else:
- panel.addfstr(10, 0, "<b>Accounting:</b> Connection Closed...")
+ panel.addfstr(labelingLine + 2, 0, "<b>Accounting:</b> Connection Closed...")
def getTitle(self, width):
stats = list(self._titleStats)
@@ -258,8 +261,9 @@
def getColor(self, isPrimary):
return DL_COLOR if isPrimary else UL_COLOR
- def getPreferredHeight(self):
- return 13 if self.isAccounting else 10
+ def getContentHeight(self):
+ baseHeight = graphPanel.GraphStats.getContentHeight(self)
+ return baseHeight + 3 if self.isAccounting else baseHeight
def new_desc_event(self, event):
# updates self._titleStats with updated values
Modified: arm/trunk/interface/graphing/graphPanel.py
===================================================================
--- arm/trunk/interface/graphing/graphPanel.py 2010-08-18 16:32:14 UTC (rev 22951)
+++ arm/trunk/interface/graphing/graphPanel.py 2010-08-18 16:43:36 UTC (rev 22952)
@@ -27,7 +27,7 @@
("minutely", 60), ("15 minute", 900), ("30 minute", 1800),
("hourly", 3600), ("daily", 86400)]
-DEFAULT_HEIGHT = 10 # space needed for graph and content
+DEFAULT_CONTENT_HEIGHT = 4 # space needed for labeling above and below the graph
DEFAULT_COLOR_PRIMARY, DEFAULT_COLOR_SECONDARY = "green", "cyan"
# enums for graph bounds:
@@ -40,13 +40,14 @@
WIDE_LABELING_GRAPH_COL = 50 # minimum graph columns to use wide spacing for x-axis labels
# used for setting defaults when initializing GraphStats and GraphPanel instances
-CONFIG = {"features.graph.interval": 0, "features.graph.bound": 1, "features.graph.maxSize": 150, "features.graph.frequentRefresh": True}
+CONFIG = {"features.graph.height": 5, "features.graph.interval": 0, "features.graph.bound": 1, "features.graph.maxWidth": 150, "features.graph.frequentRefresh": True}
def loadConfig(config):
config.update(CONFIG)
- CONFIG["features.graph.interval"] = max(len(UPDATE_INTERVALS) - 1, min(0, CONFIG["features.graph.interval"]))
- CONFIG["features.graph.bound"] = max(2, min(0, CONFIG["features.graph.bound"]))
- CONFIG["features.graph.maxSize"] = max(CONFIG["features.graph.maxSize"], 1)
+ CONFIG["features.graph.height"] = max(3, CONFIG["features.graph.height"])
+ CONFIG["features.graph.maxWidth"] = max(1, CONFIG["features.graph.maxWidth"])
+ CONFIG["features.graph.interval"] = min(len(UPDATE_INTERVALS) - 1, max(0, CONFIG["features.graph.interval"]))
+ CONFIG["features.graph.bound"] = min(2, max(0, CONFIG["features.graph.bound"]))
class GraphStats(TorCtl.PostEventListener):
"""
@@ -76,7 +77,7 @@
self.primaryTotal, self.secondaryTotal = 0, 0 # sum of all stats seen
# timescale dependent stats
- self.maxCol = CONFIG["features.graph.maxSize"]
+ self.maxCol = CONFIG["features.graph.maxWidth"]
self.maxPrimary, self.maxSecondary = {}, {}
self.primaryCounts, self.secondaryCounts = {}, {}
@@ -133,14 +134,20 @@
return DEFAULT_COLOR_PRIMARY if isPrimary else DEFAULT_COLOR_SECONDARY
- def getPreferredHeight(self):
+ def getContentHeight(self):
"""
- Provides the height content should take up. By default this provides the
- space needed for the default graph and content.
+ Provides the height content should take up (not including the graph).
"""
- return DEFAULT_HEIGHT
+ return DEFAULT_CONTENT_HEIGHT
+ def isVisible(self):
+ """
+ True if the stat has content to present, false if it should be hidden.
+ """
+
+ return True
+
def draw(self, panel, width, height):
"""
Allows for any custom drawing monitor wishes to append.
@@ -231,6 +238,7 @@
panel.Panel.__init__(self, stdscr, "graph", 0)
self.updateInterval = CONFIG["features.graph.interval"]
self.bounds = CONFIG["features.graph.bound"]
+ self.graphHeight = CONFIG["features.graph.height"]
self.currentDisplay = None # label of the stats currently being displayed
self.stats = {} # available stats (mappings of label -> instance)
self.showLabel = True # shows top label if true, hides otherwise
@@ -242,8 +250,8 @@
if hidden).
"""
- if self.currentDisplay:
- return self.stats[self.currentDisplay].getPreferredHeight()
+ if self.currentDisplay and self.stats[self.currentDisplay].isVisible():
+ return self.stats[self.currentDisplay].getContentHeight() + self.graphHeight
else: return 0
def draw(self, subwindow, width, height):
@@ -288,20 +296,20 @@
# displays bound
self.addstr(2, 0, "%4i" % primaryMaxBound, primaryColor)
- self.addstr(7, 0, "%4i" % primaryMinBound, primaryColor)
+ self.addstr(self.graphHeight + 1, 0, "%4i" % primaryMinBound, primaryColor)
self.addstr(2, graphCol + 5, "%4i" % secondaryMaxBound, secondaryColor)
- self.addstr(7, graphCol + 5, "%4i" % secondaryMinBound, secondaryColor)
+ self.addstr(self.graphHeight + 1, graphCol + 5, "%4i" % secondaryMinBound, secondaryColor)
# creates bar graph (both primary and secondary)
for col in range(graphCol):
colCount = param.primaryCounts[self.updateInterval][col + 1] - primaryMinBound
- colHeight = min(5, 5 * colCount / (max(1, primaryMaxBound) - primaryMinBound))
- for row in range(colHeight): self.addstr(7 - row, col + 5, " ", curses.A_STANDOUT | primaryColor)
+ colHeight = min(self.graphHeight, self.graphHeight * colCount / (max(1, primaryMaxBound) - primaryMinBound))
+ for row in range(colHeight): self.addstr(self.graphHeight + 1 - row, col + 5, " ", curses.A_STANDOUT | primaryColor)
colCount = param.secondaryCounts[self.updateInterval][col + 1] - secondaryMinBound
- colHeight = min(5, 5 * colCount / (max(1, secondaryMaxBound) - secondaryMinBound))
- for row in range(colHeight): self.addstr(7 - row, col + graphCol + 10, " ", curses.A_STANDOUT | secondaryColor)
+ colHeight = min(self.graphHeight, self.graphHeight * colCount / (max(1, secondaryMaxBound) - secondaryMinBound))
+ for row in range(colHeight): self.addstr(self.graphHeight + 1 - row, col + graphCol + 10, " ", curses.A_STANDOUT | secondaryColor)
# bottom labeling of x-axis
intervalSec = 1 # seconds per labeling
@@ -323,8 +331,8 @@
# if constrained on space then strips labeling since already provided
timeLabel = timeLabel[:-1]
- self.addstr(8, 4 + loc, timeLabel, primaryColor)
- self.addstr(8, graphCol + 10 + loc, timeLabel, secondaryColor)
+ self.addstr(self.graphHeight + 2, 4 + loc, timeLabel, primaryColor)
+ self.addstr(self.graphHeight + 2, graphCol + 10 + loc, timeLabel, secondaryColor)
param.draw(self, width, height) # allows current stats to modify the display
Modified: arm/trunk/interface/graphing/psStats.py
===================================================================
--- arm/trunk/interface/graphing/psStats.py 2010-08-18 16:32:14 UTC (rev 22951)
+++ arm/trunk/interface/graphing/psStats.py 2010-08-18 16:43:36 UTC (rev 22952)
@@ -66,12 +66,14 @@
statLabel = statName[0].upper() + statName[1:]
return "%s (%s, avg: %s):" % (statLabel, lastAmount, avg)
- def getPreferredHeight(self):
- # hides graph if there's nothing to display (provides default otherwise)
- # provides default height unless there's nothing to
+ def isVisible(self):
+ """
+ Hides graph if unable to fetch stats.
+ """
+
if self.queryPid and self.queryParam and self.failedCount < FAILURE_THRESHOLD:
- return graphPanel.DEFAULT_HEIGHT
- else: return 0
+ return graphPanel.GraphStats.isVisible(self)
+ else: return False
def eventTick(self):
"""