#!/usr/bin/python import os, sys, time, math import rrdtool from rrdui import * # 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. 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() status = status >> 8 try: p.close() except IOError: pass if status != 0: logMsg("WARNING: Couldn't query %s for %s" % (host, oid)) out = "U" return out.strip() def loadTimers(items): timers = [] for item in items: (fields, interval) = item.getPollingInfo() if not len(fields): continue if interval < 10: logMsg("WARNING: Ignoring interval less than 10 seconds") interval = 10 cmds = {} for fieldname in fields.keys(): field = fields[fieldname] info = field.split("/") if len(info) != 4: logMsg("ERROR: Bad src format: %s" % field) sys.exit(1) if info[0] != "SNMP": 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) return timers 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() 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)