summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rwxr-xr-xtools/rrdui-cgi.py109
-rw-r--r--tools/rrdui-collect.py59
-rw-r--r--tools/rrdui-create.py28
-rw-r--r--tools/rrdui.py96
-rw-r--r--tools/rrdui.pycbin0 -> 2659 bytes
5 files changed, 292 insertions, 0 deletions
diff --git a/tools/rrdui-cgi.py b/tools/rrdui-cgi.py
new file mode 100755
index 0000000..8b376f5
--- /dev/null
+++ b/tools/rrdui-cgi.py
@@ -0,0 +1,109 @@
+#!/usr/bin/python
+
+import os, sys, time
+import sets, cgi, shlex
+import rrdtool
+
+from rrdui import *
+
+def listGraphs():
+
+ graphs = loadGraphs()
+ categories = {}
+ for item in graphs:
+ if not categories.has_key(item.category):
+ categories[item.category] = []
+ categories[item.category].append(item)
+
+ groups = categories.keys()
+ groups.sort()
+
+ print "Content-Type: text/xml\n"
+ print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ print "<data>"
+ for group in groups:
+ print " <category name=\"%s\">" % group
+ categories[group].sort()
+ for item in categories[group]:
+ print " <graph name=\"%s\" width=\"%d\" height=\"%d\" title=\"%s\"/>" % \
+ (item.name, item.width, item.height, item.title)
+ print " </category>"
+ print "</data>"
+
+
+def displayGraph():
+
+ # print "Content-Type: text/plain"
+ print "Content-Type: image/png"
+ print ""
+
+ form = cgi.FieldStorage()
+ if not form.has_key("category") or not form.has_key("name"):
+ raise "Required arguments not specified"
+
+ name = form["name"].value
+ category = form["category"].value
+ item = GraphDef(category, name)
+
+ # Default to one day display
+ end = int(time.time())
+ start = end - 86400
+ if form.has_key("start"):
+ start = int(form["start"].value)
+ if form.has_key("end"):
+ end = int(form["end"].value)
+
+ # Default to Height and Width in graph
+ height = item.height
+ width = item.width
+ if form.has_key("width"):
+ width = int(form["width"].value)
+ if form.has_key("height"):
+ height = int(form["height"].value)
+
+
+ args = ["-", "--imgformat=PNG", "--rigid",
+ "--start=%d" % start,
+ "--end=%d" % end,
+ "--title=%s" % item.title,
+ "--height=%d" % height,
+ "--width=%d" % width ]
+
+ # TODO Check color syntax
+ if form.has_key("color"):
+ colors = form.getlist("color");
+ for color in colors:
+ args.append("--color")
+ args.append(color.replace(":", "#"))
+
+ commands = item.commands.replace("{START}",
+ time.strftime("%Y-%m-%d %H\\:%M", time.localtime(start)))
+ commands = commands.replace("{END}",
+ time.strftime("%Y-%m-%d %H\\:%M", time.localtime(end)))
+ commands = commands.replace("{RRD}", item.filedata)
+ args.extend(shlex.split(commands))
+
+ args.extend(shlex.split(item.options))
+
+ print >> sys.stderr, str(args)
+ rrdtool.graph(*args)
+
+
+if not os.environ.has_key("PATH_INFO"):
+ raise "PATH_INFO not set"
+
+path = os.environ["PATH_INFO"].strip("/")
+parts = path.split("/")
+
+method = parts[0]
+del parts[0]
+if not method:
+ method = "list"
+
+
+if method == "list":
+ listGraphs()
+elif method == "graph":
+ displayGraph()
+else:
+ raise "Invalid request: %s" % method
diff --git a/tools/rrdui-collect.py b/tools/rrdui-collect.py
new file mode 100644
index 0000000..892fdf8
--- /dev/null
+++ b/tools/rrdui-collect.py
@@ -0,0 +1,59 @@
+#!/usr/bin/python
+
+import os, sys, time
+import rrdtool
+
+from rrdui import *
+
+def readItemValue(host, community, oid):
+
+ cmd = "snmpget -c %s -Ov -OQ -v 2c %s %s" % (community, host, oid)
+ p = os.popen(cmd, "r")
+ out = p.read()
+ (pid, status) = os.wait()
+ status = status >> 8
+
+ try:
+ p.close()
+ except IOError:
+ pass
+
+ if status != 0:
+ print "Couldn't query %s for %s" % (host, oid) # XXXXXX
+ out = "U"
+
+ return out.strip()
+
+
+def updateItems(graphs):
+ for item in graphs:
+ if not os.path.exists(item.filedata):
+ continue
+
+ (fields, interval) = item.getPollingInfo()
+
+ values = {}
+ for fieldname in fields.keys():
+ info = fields[fieldname].split(":")
+ if len(info) != 4:
+ raise "Bad src format" # XXXXXXXXX
+ if info[0] != "SNMP":
+ raise "Unknown src method: %s" % info[0] # XXXXXXXXX
+
+ value = readItemValue(host = info[1], community = info[2], oid = info[3])
+ values[fieldname] = value
+
+ print ":".join(values.keys()), ":".join(values.values())
+ args = [item.filedata, "--template", ":".join(values.keys()),
+ "N:%s" % ":".join(values.values())]
+ rrdtool.update(*args)
+
+
+graphs = loadGraphs()
+while True:
+ updateItems(graphs)
+ # TODO: Work out the interval stuff. for now all at 10 seconds
+ time.sleep(10)
+
+
+
diff --git a/tools/rrdui-create.py b/tools/rrdui-create.py
new file mode 100644
index 0000000..3b46021
--- /dev/null
+++ b/tools/rrdui-create.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+
+import os, sys
+import rrdtool
+
+from rrdui import *
+
+def createItems(graphs):
+
+ for item in graphs:
+ if os.path.exists(item.filedata):
+ continue
+
+ args = [item.filedata, "-b-1y", "-s10"]
+
+ # The creation info
+ (fields, rras) = item.getCreateInfo()
+
+ # Flesh it out properly, and add it
+ args.extend(["RRA:%s" % r for r in rras])
+ args.extend(["DS:%s:%s" % (f, fields[f]) for f in fields.keys()])
+
+ # And create it
+ rrdtool.create(*args)
+
+# Basics
+graphs = loadGraphs()
+createItems(graphs)
diff --git a/tools/rrdui.py b/tools/rrdui.py
new file mode 100644
index 0000000..ee10eae
--- /dev/null
+++ b/tools/rrdui.py
@@ -0,0 +1,96 @@
+import os, sys, time
+import ConfigParser
+
+# TODO: Temporary
+CONFDIR = "/data/projects/rrdui/conf"
+WORKDIR = "/data/projects/rrdui/work"
+
+class GraphDef:
+ filename = None
+ filedata = None
+ title = ""
+ height = 0
+ width = 0
+ options = ""
+ commands = ""
+ category = ""
+ name = ""
+
+ __config = None
+
+ def __init__(self, category, name):
+ self.filename = "%s/%s/%s" % (CONFDIR, category, name)
+ self.filedata = "%s/%s-%s.rrd" % (WORKDIR, category, name)
+ self.category = category
+ self.name = name
+
+ cfg = self.__config = ConfigParser.RawConfigParser()
+ cfg.read(self.filename)
+
+ # Loading general stuff
+ if cfg.has_option("general", "title"):
+ self.title = cfg.get("general", "title")
+
+ # Loading graph stuff
+ if cfg.has_option("graph", "width"):
+ self.width = int(cfg.get("graph", "width"))
+ if cfg.has_option("graph", "height"):
+ self.height = int(cfg.get("graph", "height"))
+ if cfg.has_option("graph", "options"):
+ self.options = cfg.get("graph", "options")
+ if not cfg.has_option("graph", "commands"):
+ raise "Missing commands attribute in: %s" % self.filename
+ self.commands = cfg.get("graph", "commands")
+
+
+ def getCreateInfo(self):
+ cfg = self.__config
+ rra = None
+ fields = {}
+
+ # The RRA info
+ if cfg.has_option("create", "rra"):
+ rra = cfg.get("create", "rra").split()
+
+ # The various fields
+ for field in cfg.options("create"):
+ if not field.startswith("field."):
+ continue
+ fieldname = field[6:]
+ fields[fieldname] = cfg.get("create", field)
+
+ return (fields, rra)
+
+
+ def getPollingInfo(self):
+ cfg = self.__config
+ interval = 300
+ fields = {}
+
+ # The interval
+ if cfg.has_option("poll", "interval"):
+ interval = int(cfg.get("poll", "interval"))
+
+ # The various fields
+ for field in cfg.options("poll"):
+ if not field.startswith("field."):
+ continue
+ fieldname = field[6:]
+ fields[fieldname] = cfg.get("poll", field)
+
+ return (fields, interval)
+
+
+def loadGraphs():
+
+ # List files and add appropriate paths
+ graphs = []
+ for category in os.listdir(CONFDIR):
+ dir = "%s/%s" % (CONFDIR, category)
+ if not os.path.isdir(dir):
+ continue
+ for f in os.listdir(dir):
+ graphs.append(GraphDef(category, f))
+ return graphs
+
+
diff --git a/tools/rrdui.pyc b/tools/rrdui.pyc
new file mode 100644
index 0000000..4bd62ce
--- /dev/null
+++ b/tools/rrdui.pyc
Binary files differ