From 428f3570f98224e7fd2ff18e1e199068b3285a5d Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Sat, 21 Jan 2006 19:18:33 +0000 Subject: Build a slightly better polling RRD collector. --- tools/rrdui-collect.py | 106 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 83 insertions(+), 23 deletions(-) diff --git a/tools/rrdui-collect.py b/tools/rrdui-collect.py index 892fdf8..0585812 100644 --- a/tools/rrdui-collect.py +++ b/tools/rrdui-collect.py @@ -1,13 +1,27 @@ #!/usr/bin/python -import os, sys, time +import os, sys, time, math import rrdtool from rrdui import * -def readItemValue(host, community, oid): +# This entire module is nasty. Don't do this at home. It's a python interim +# replacement for a C daemon that needs writing. It's about the least efficient +# way to go about SNMP polling. - cmd = "snmpget -c %s -Ov -OQ -v 2c %s %s" % (community, host, oid) +class Timer: + def __init__(self, interval, cmds, item): + self.interval = interval + self.cmds = cmds + self.item = item + self.last = 0 + +def logMsg(msg): + stamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) + print >> sys.stderr, "%s: %s" % (stamp, msg) + + +def readItemValue(cmd): p = os.popen(cmd, "r") out = p.read() (pid, status) = os.wait() @@ -19,41 +33,87 @@ def readItemValue(host, community, oid): pass if status != 0: - print "Couldn't query %s for %s" % (host, oid) # XXXXXX + logMsg("WARNING: Couldn't query %s for %s" % (host, oid)) out = "U" - return out.strip() -def updateItems(graphs): - for item in graphs: - if not os.path.exists(item.filedata): - continue +def loadTimers(items): + timers = [] + for item in items: (fields, interval) = item.getPollingInfo() - values = {} + if not len(fields): + continue + + if interval < 10: + logMsg("WARNING: Ignoring interval less than 10 seconds") + interval = 10 + + cmds = {} for fieldname in fields.keys(): - info = fields[fieldname].split(":") + field = fields[fieldname] + info = field.split("/") if len(info) != 4: - raise "Bad src format" # XXXXXXXXX + logMsg("ERROR: Bad src format: %s" % field) + sys.exit(1) if info[0] != "SNMP": - raise "Unknown src method: %s" % info[0] # XXXXXXXXX + logMsg("ERROR: Unknown src method: %s" % info[0]) + sys.exit(1) + + # TODO: Note that we don't check our arguments ... + # Nasty and temporary untill we get the C daemon going + cmd = "snmpget -c %s -Ov -OQ -v 2c %s %s" % (info[2], info[1], info[3]) + cmds[fieldname] = cmd + + timer = Timer(interval, cmds, item) + timers.append(timer) - value = readItemValue(host = info[1], community = info[2], oid = info[3]) - values[fieldname] = value + return timers - print ":".join(values.keys()), ":".join(values.values()) - args = [item.filedata, "--template", ":".join(values.keys()), - "N:%s" % ":".join(values.values())] +def updateItem(timer): + + if not os.path.exists(timer.item.filedata): + logMsg("WARNING: RRD file does not exist: %s" % timer.item.filedata) + return + + values = {} + for field in timer.cmds.keys(): + values[field] = readItemValue(timer.cmds[field]) + + args = [timer.item.filedata, "--template", ":".join(values.keys()), + "N:%s" % ":".join(values.values())] + try: rrdtool.update(*args) + print args + except Error, e: + logMsg("ERROR: Couldn't update RRD file: %s (args: %s)", e.value, args) -graphs = loadGraphs() -while True: - updateItems(graphs) - # TODO: Work out the interval stuff. for now all at 10 seconds - time.sleep(10) +graphs = loadGraphs() +timers = loadTimers(graphs) +while True: + # Update when and where necessary. Note we keep calling + # time.time() as updating takes time + for timer in timers: + if (timer.last + timer.interval) < time.time(): + updateItem(timer) + timer.last = time.time() + + # Now figure out how long to sleep + next = 0 + for timer in timers: + if not timer.last: + continue + if not next or (timer.last + timer.interval) < next: + next = timer.last + timer.interval + + secs = next - time.time() + print "%d %d %d" % (secs, next, time.time()) + if(secs > 0): + print "sleeping for %d" % secs + time.sleep(secs) -- cgit v1.2.3