#!/usr/bin/python # # Munin plugin to show the network traffic of libvirt managed virtual machines # # Copyright Guido Guenther # # depends: python-libvirt, python-libxml2 # # If you don't want to use the default uri use: # # [libvirt-*] # env.uri qemu:///system # # in your plugin configuration import re, sys, os import libvirt import libxml2 def canon(name): return re.sub(r"[^a-zA-Z0-9_]", "_", name) def print_config(uri): """print the plugin config, determine the domains""" print """graph_title Virtual Domain Network I/O graph_vlabel Bytes rx (-)/ tx (+) per ${graph_period} graph_category Virtual Machines graph_info This graph shows the network I/O of the virtual machines """ conn = libvirt.openReadOnly(uri) ids = conn.listDomainsID() for id in ids: dom = conn.lookupByID(id) name = dom.name() print "%s_rx.label %s" % (canon(name), name) print "%s_rx.type DERIVE" % canon(name) print "%s_rx.min 0" % canon(name) print "%s_rx.graph no" % canon(name) print "%s_tx.label %s" % (canon(name), name) print "%s_tx.type DERIVE" % canon(name) print "%s_tx.min 0" % canon(name) print "%s_tx.negative %s_rx" % (canon(name), canon(name)) def get_ifaces(dom): xml = dom.XMLDesc(0) doc = None try: doc = libxml2.parseDoc(xml) except: return [] ctx = doc.xpathNewContext() ifaces = [] try: ret = ctx.xpathEval("/domain/devices/interface") for node in ret: devdst = None for child in node.children: if child.name == "target": devdst = child.prop("dev") if devdst == None: continue ifaces.append(devdst) finally: if ctx != None: ctx.xpathFreeContext() if doc != None: doc.freeDoc() return ifaces def fetch_values(uri): conn = libvirt.openReadOnly(uri) ids = conn.listDomainsID() for id in ids: rd = 0 wr = 0 dom = conn.lookupByID(id) name = dom.name() ifaces = get_ifaces(dom) for iface in ifaces: try: stats = dom.interfaceStats(iface) rd += stats[0] wr += stats[4] except TypeError: print >>sys.stderr, "Cannot get ifstats for '%s' on '%s'" % (iface, name) print "%s_rx.value %d" % (canon(name), rd) print "%s_tx.value %d" % (canon(name), wr) def main(sys): uri = os.getenv("uri") if len(sys) > 1: if sys[1] in [ 'autoconf', 'detect' ]: if libvirt.openReadOnly(uri): print "yes" return 0 else: print "no" return 1 elif sys[1] == 'config': print_config(uri) return 0 fetch_values(uri) return 0 if __name__ == "__main__": sys.exit(main(sys.argv)) # vim:et:ts=4:sw=4: