Author: eallen
Date: 2010-10-20 13:28:20 -0400 (Wed, 20 Oct 2010)
New Revision: 4397
Modified:
mgmt/trunk/cumin/python/cumin/inventory/system.py
mgmt/trunk/cumin/python/cumin/stat.py
Log:
Fix for BZ 633914: Formatted memory and swap number for Sysimage as MB/GB
Added a Percent chart type
Changed the free memory graph to Percent Free Memory to avoid confusion over units
Removed the database id as a parameter for some charts and used _qmf_agent_id instead
Modified: mgmt/trunk/cumin/python/cumin/inventory/system.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/inventory/system.py 2010-10-20 17:24:14 UTC (rev 4396)
+++ mgmt/trunk/cumin/python/cumin/inventory/system.py 2010-10-20 17:28:20 UTC (rev 4397)
@@ -42,6 +42,7 @@
self.view.add_tab(overview)
class SystemGeneralStatSet(StatSet):
+ fmt_as_bytes = ("memFree", "swapFree")
def __init__(self, app, name, object):
super(SystemGeneralStatSet, self).__init__(app, name, object)
@@ -50,13 +51,20 @@
"loadAverage10Min", "procTotal",
"procRunning")
+ def render_item_value(self, session, item):
+ stat, value = item
+ if stat.name in self.fmt_as_bytes:
+ return fmt_bytes(value*1024)
+ return CuminStatistic.fmt_value(value)
+
class SystemStats(Widget):
def __init__(self, app, name, system):
super(SystemStats, self).__init__(app, name)
self.add_child(SystemGeneralStatSet(app, "stats", system))
- chart = StatFlashChart(app, "freemem", system)
+ chart = self.MemoryFlashChart(app, "freemem", system)
+ chart.chart_type = "percent"
chart.stats = ("memFree",)
self.add_child(chart)
@@ -78,6 +86,16 @@
#return self.page.main.grid.pool.job.get_href(session, job, None)
return session.marshal() # XXX
+ class MemoryFlashChart(StatFlashChart):
+ def render_title(self, session, *args):
+ return "Memory Usage"
+
+ def get_href_params(self, session):
+ params = super(SystemStats.MemoryFlashChart, self).get_href_params(session)
+ params.append("tp=memTotal")
+
+ return params
+
class SystemSlotMap(SlotMap):
def __init__(self, app, name, system):
super(SystemSlotMap, self).__init__(app, name)
Modified: mgmt/trunk/cumin/python/cumin/stat.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/stat.py 2010-10-20 17:24:14 UTC (rev 4396)
+++ mgmt/trunk/cumin/python/cumin/stat.py 2010-10-20 17:28:20 UTC (rev 4397)
@@ -111,8 +111,6 @@
# open-flash-chart can't handle the : in the agent id. Net even if
# it's converted to %3A, so we have to change it
params.append("agent=%s" % object._qmf_agent_id.replace(":",
"|"))
-
- params.append("id=%s" % object._id)
params.append("object_id=%s" % object._qmf_object_id)
params.append("chart_id=%s" % self.render_id(session, None))
params.append("duration=%s" % self.duration.get(session))
@@ -229,6 +227,7 @@
return file
class StatChartPage(Page):
+ # handles stats.png request
def __init__(self, app, name):
super(StatChartPage, self).__init__(app, name)
@@ -275,11 +274,29 @@
self.container_height.default = 100
self.add_parameter(self.container_height)
+ self.total_property = Parameter(app, "tp")
+ self.add_parameter(self.total_property)
+
+ self.type = Parameter(app, "type")
+ self.add_parameter(self.type)
+
self.cache = ImageCache()
def get_content_type(self, session):
return self.samples.get(session) and "text/plain" or
"image/png"
+ def get_object_property(self, session, property):
+ agent_id = self.agent_id.get(session)
+
+ rpackage = self.rosemary_package.get(session)
+ rclass = self.rosemary_class.get(session)
+ rosemary_package = self.app.model._packages_by_name[rpackage]
+ cls = rosemary_package._classes_by_name[rclass]
+
+ cursor = self.app.database.get_read_cursor()
+ object = cls.get_object(cursor, _qmf_agent_id=agent_id)
+ return object.get_value(property)
+
def get_adapter_stats(self, session):
rpackage = self.rosemary_package.get(session)
rclass = self.rosemary_class.get(session)
@@ -400,6 +417,17 @@
for stat in stats:
samples[stat] = adapter.samples(stat, duration, interval, method)
+ type = self.type.get(session)
+ if type == "percent":
+ total_property = self.total_property.get(session)
+ total = self.get_object_property(session, total_property)
+ total = total and float(total) or 1.0
+
+ for stat in stats:
+ percents = [(x[0], (float(x[1]) / total) * 100.0, x[2])
+ for x in samples[stat] if x[1] is not None]
+ samples[stat] = percents
+
# take stddev into account for max and min y values
deviated_values = list()
for stat in stats:
@@ -454,7 +482,7 @@
if mode == "rate":
titles = ["%s / sec" % x.title for x in stats]
else:
- titles = [x.title for x in stats]
+ titles = ["%s%s" % ((type == "percent") and "Percent
" or "", x.title) for x in stats]
title_xy = chart.plot_legend(titles, colors)
@@ -480,8 +508,8 @@
self.object_id = StringParameter(app, "object_id")
self.add_parameter(self.object_id)
- self.id = StringParameter(app, "id")
- self.add_parameter(self.id)
+ self.agent_id = ModifiedAgentIdParameter(app, "agent")
+ self.add_parameter(self.agent_id)
self.rosemary_class = Parameter(app, "rcls")
self.add_parameter(self.rosemary_class)
@@ -513,6 +541,9 @@
self.flash_chart = self.GenericChart(app, "chart", self.object)
self.add_child(self.flash_chart)
+ self.total_property = Parameter(app, "tp")
+ self.add_parameter(self.total_property)
+
def render_content(self, session):
self.flash_chart.stats = self.stats.get(session)
self.flash_chart.mode = self.mode.get(session)
@@ -527,11 +558,11 @@
rclass = self.widget.rosemary_class.get(session)
rosemary_package = self.app.model._packages_by_name[rpackage]
rosemary_class = rosemary_package._classes_by_name[rclass]
+ agent_id = self.widget.agent_id.get(session)
- id = self.widget.id.get(session)
cursor = self.app.database.get_read_cursor()
- obj = rosemary_class.get_object(cursor, _id=id)
+ obj = rosemary_class.get_object(cursor, _qmf_agent_id=agent_id)
self.set(session, obj)
@@ -555,6 +586,9 @@
params.append("width=%i" % self.render_width(session))
params.append("height=%i" % self.render_height(session))
params.append("high=1")
+ tp = self.parent.total_property.get(session)
+ if tp:
+ params.append("tp=%s" % tp)
return escape_entity("%s?" % self.get_flash_name(session) +
";".join(params))
class XAxis(object):
@@ -928,12 +962,15 @@
line.colour = color
line.width = line_width
tip_title = stat.title.split(" ")[-1]
- line.text = mode == "rate" and "%s / sec" % tip_title or
stat.title
+ line.text = mode == "rate" and "%s / sec" % tip_title or
self.get_line_title(stat)
vals = self.get_vals(session, samples, stat, line.text, duration, end_secs)
line.values = vals
chart.elements.append(line)
+ def get_line_title(self, stat):
+ return stat.title
+
def get_chart(self, session, adapter, stats, samples, duration, max_value, min_value,
append, end_secs):
mode = self.page.mode.get(session)
@@ -1086,6 +1123,7 @@
return dict()
class StatFlashPage(StatChartPage):
+ # handles chart.json requests
def __init__(self, app, name):
super(StatFlashPage, self).__init__(app, name)
@@ -1136,6 +1174,9 @@
self.control_max.default = None
self.add_parameter(self.control_max)
+ self.percent_property = Parameter(app, "tp")
+ self.add_parameter(self.percent_property)
+
def get_content_type(self, session):
return "text/plain"
@@ -1151,12 +1192,38 @@
elif chart_type == "stacked":
chart_obj = StackedAreaChart(self.app, chart_type, self)
#chart_obj = StackedChart(self.app, chart_type, self)
+ elif chart_type == "percent":
+ chart_obj = PercentAreaChart(self.app, chart_type, self)
elif chart_type == "pie":
chart_obj = FlashPieChart(self.app, chart_type, self)
return chart_obj
+class PercentAreaChart(AreaChart):
+ def get_max_min(self, session, stats, samples):
+ return 100.0, 0.0
+
+ def get_vals(self, session, samples, stat, text, duration, end_secs):
+ tnow = time()
+ vals = list()
+ percent = self.page.percent_property.get(session)
+ total = self.page.get_object_property(session, percent)
+
+ min_dt = tnow - duration - end_secs
+ for dt, value, dev in samples[stat]:
+ if value is not None:
+ vals.append({"dt": secs(dt), "y": (float(value) /
float(total)) * 100.0})
+ if secs(dt) < min_dt:
+ break
+
+ vals.reverse()
+ return vals
+
+ def get_line_title(self, stat):
+ return "Percent %s" % stat.title
+
class StatStackedPage(StatChartPage):
+ # handles stacked.png requests
def do_render(self, session):
adapter, stats = self.get_adapter_stats(session)