+ @property
+ def stepsize(self):
+ return self.interval
+
+ @property
+ def file(self):
+ """
+ The absolute path to the RRD file of this plugin.
+ """
+ return os.path.join(DATABASE_DIR, "%s.rrd" % self.id)
+
+ def create(self):
+ """
+ Creates an empty RRD file with the desired data structures.
+ """
+ # Skip if the file does already exist.
+ if os.path.exists(self.file):
+ return
+
+ dirname = os.path.dirname(self.file)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+
+ # Create argument list.
+ args = [
+ "--step", "%s" % self.default_interval,
+ ] + self.get_rrd_schema()
+
+ rrdtool.create(self.file, *args)
+
+ self.log.debug(_("Created RRD file %s.") % self.file)
+
+ def get_rrd_schema(self):
+ schema = [
+ "--step", "%s" % self.stepsize,
+ ]
+ for line in self.rrd_schema:
+ if line.startswith("DS:"):
+ try:
+ (prefix, name, type, lower_limit, upper_limit) = line.split(":")
+
+ line = ":".join((
+ prefix,
+ name,
+ type,
+ "%s" % self.stepsize,
+ lower_limit,
+ upper_limit
+ ))
+ except ValueError:
+ pass
+
+ schema.append(line)
+
+ xff = 0.1
+
+ cdp_length = 0
+ for rra_timespan in self.rra_timespans:
+ if (rra_timespan / self.stepsize) < self.rra_rows:
+ rra_timespan = self.stepsize * self.rra_rows
+
+ if cdp_length == 0:
+ cdp_length = 1
+ else:
+ cdp_length = rra_timespan // (self.rra_rows * self.stepsize)
+
+ cdp_number = math.ceil(rra_timespan / (cdp_length * self.stepsize))
+
+ for rra_type in self.rra_types:
+ schema.append("RRA:%s:%.10f:%d:%d" % \
+ (rra_type, xff, cdp_length, cdp_number))
+
+ return schema
+
+ def info(self):
+ return rrdtool.info(self.file)
+
+ ### Basic methods
+
+ def init(self, **kwargs):
+ """
+ Do some custom initialization stuff here.
+ """
+ pass
+
+ def read(self):
+ """
+ Gathers the statistical data, this plugin collects.
+ """
+ raise NotImplementedError
+
+ def submit(self):
+ """
+ Flushes the read data to disk.
+ """
+ # Do nothing in case there is no data to submit.
+ if not self.data:
+ return
+
+ self.log.debug(_("Submitting data to database. %d entries.") % len(self.data))
+ rrdtool.update(self.file, *self.data)
+ self.data = []
+
+ def _read(self, *args, **kwargs):
+ """
+ This method catches errors from the read() method and logs them.
+ """
+ try:
+ return self.read(*args, **kwargs)
+
+ # Catch any exceptions, so collecty does not crash.
+ except Exception, e:
+ self.log.critical(_("Unhandled exception in read()!"), exc_info=True)
+
+ def _submit(self, *args, **kwargs):
+ """
+ This method catches errors from the submit() method and logs them.
+ """
+ try:
+ return self.submit(*args, **kwargs)
+
+ # Catch any exceptions, so collecty does not crash.
+ except Exception, e:
+ self.log.critical(_("Unhandled exception in submit()!"), exc_info=True)
+
+ def run(self):
+ self.log.debug(_("Started."))
+
+ while self.running:
+ # Reset the timer.
+ self.timer.reset()
+
+ # Wait until the timer has successfully elapsed.
+ if self.timer.wait():
+ self.log.debug(_("Collecting..."))
+ self._read()
+
+ self._submit()
+ self.log.debug(_("Stopped."))