import unicodedata
from .. import locales
+from .. import util
from ..constants import *
from ..i18n import _
def __repr__(self):
return "<%s>" % self.__class__.__name__
+ def __lt__(self, other):
+ return self.id < other.id
+
@property
def collecty(self):
return self.plugin.collecty
return schema
- def make_rrd_defs(self, prefix=None):
- defs = []
+ @property
+ def rrd_schema_names(self):
+ ret = []
for line in self.rrd_schema:
- (def_type, name, type, lower_limit, upper_limit) = line.split(":")
+ (prefix, name, type, lower_limit, upper_limit) = line.split(":")
+ ret.append(name)
+
+ return ret
+
+ def make_rrd_defs(self, prefix=None):
+ defs = []
+ for name in self.rrd_schema_names:
if prefix:
p = "%s_%s" % (prefix, name)
else:
return defs
+ def get_stddev(self, interval=None):
+ args = self.make_rrd_defs()
+
+ # Add the correct interval
+ args += ["--start", util.make_interval(interval)]
+
+ for name in self.rrd_schema_names:
+ args += [
+ "VDEF:%s_stddev=%s,STDEV" % (name, name),
+ "PRINT:%s_stddev:%%lf" % name,
+ ]
+
+ x, y, vals = rrdtool.graph("/dev/null", *args)
+ return dict(zip(self.rrd_schema_names, vals))
+
def execute(self):
if self.collected:
raise RuntimeError("This object has already collected its data")
# Extra arguments passed to rrdgraph.
rrd_graph_args = []
- intervals = {
- None : "-3h",
- "hour" : "-1h",
- "day" : "-25h",
- "month": "-30d",
- "week" : "-360h",
- "year" : "-365d",
- }
-
# Default dimensions for this graph
height = GRAPH_DEFAULT_HEIGHT
width = GRAPH_DEFAULT_WIDTH
self.object_id = object_id
# Get the main object
- self.object = self.get_object(self.object_id)
+ self.objects = self.get_objects(self.object_id)
+ self.objects.sort()
def __repr__(self):
return "<%s>" % self.__class__.__name__
def log(self):
return self.plugin.log
+ @property
+ def object(self):
+ """
+ Shortcut to the main object
+ """
+ if len(self.objects) == 1:
+ return self.objects[0]
+
def _make_command_line(self, interval, format=DEFAULT_IMAGE_FORMAT,
width=None, height=None, with_title=True, thumbnail=False):
args = [e for e in GRAPH_DEFAULT_ARGUMENTS]
if self.upper_limit is not None:
args += ["--upper-limit", self.upper_limit]
- try:
- interval = self.intervals[interval]
- except KeyError:
- interval = "end-%s" % interval
-
# Add interval
- args += ["--start", interval]
+ args += ["--start", util.make_interval(interval)]
+
+ return args
+
+ def _add_defs(self):
+ use_prefix = len(self.objects) >= 2
+
+ args = []
+ for object in self.objects:
+ if use_prefix:
+ args += object.make_rrd_defs(object.id)
+ else:
+ args += object.make_rrd_defs()
return args
return ret
- def get_object(self, *args, **kwargs):
- return self.plugin.get_object(*args, **kwargs)
+ def get_objects(self, *args, **kwargs):
+ object = self.plugin.get_object(*args, **kwargs)
- def get_object_table(self):
- return {
- "file" : self.object,
- }
-
- @property
- def object_table(self):
- if not hasattr(self, "_object_table"):
- self._object_table = self.get_object_table()
-
- return self._object_table
+ if object:
+ return [object,]
- def get_object_files(self):
- files = {}
-
- for id, obj in self.object_table.items():
- files[id] = obj.file
-
- return files
+ return []
def generate_graph(self, interval=None, **kwargs):
+ assert self.objects, "Cannot render graph without any objects"
+
# Make sure that all collected data is in the database
# to get a recent graph image
- if self.object:
- self.object.commit()
+ for object in self.objects:
+ object.commit()
args = self._make_command_line(interval, **kwargs)
self.log.info(_("Generating graph %s") % self)
- #object_files = self.get_object_files()
+ rrd_graph = self.rrd_graph
- if self.object:
- args += self.object.make_rrd_defs()
+ # Add DEFs for all objects
+ if not any((e.startswith("DEF:") for e in rrd_graph)):
+ args += self._add_defs()
- args += self.rrd_graph
+ args += rrd_graph
args = self._add_vdefs(args)
# Convert arguments to string