"""
Handle host-interface mappings for stats.
"""
import shlex
import os.path
import logging; log = logging.getLogger('pvl.rrd.hosts')
def hostjoin (*hosts) :
"""
DNS hostname join.
"""
return '.'.join(hosts)
def hostreverse (host) :
"""
Reverse hostname.
"""
return '.'.join(reversed(host.split('.')))
def load (file, domain=None) :
"""
Parse hosts from file, yielding
(host, node, iface, tag)
file - read host/ifaces from file
domain - append given domain to hostname
"""
host = None
for idx, line in enumerate(file, 1) :
line = line.rstrip()
if not line :
continue
# comment?
if line.startswith('#') :
continue
# line
parts = shlex.split(line)
if not line[0].isspace() :
host = parts.pop(0)
# host-spec?
if '=' in host :
host, node = host.split('=')
else :
node = host
# host has domain in collectd?
if domain :
host = hostjoin(host, domain)
if not parts :
# keep host for following lines
continue
iface = parts.pop(0)
# possibly multiple tags..
for tag in parts :
yield host, node, iface, tag
def map_interfaces (options, file):
"""
Read (hostname, interface}: (nodename, tag) pairs from file.
"""
for host, node, iface, tag in load(file) :
log.debug("%s/%s -> %s/%s", host, iface, node, tag)
yield (host, iface), (node, tag)
def collectd_interfaces (options, file, collectd_domain, collectd_plugin) :
"""
Read collectd (host, type-instance, name) items, and yield (collectd-rrd, out-rrd) tuples.
file - read host/ports from file
collectd_domain - append given domain to collectd hostname
collectd_plugin - use given collectd plugin's type-instances
"""
log.info("scanning %s/<host>.%s/%s/%s-<port>.rrd", options.collectd_rrd, collectd_domain, collectd_plugin, options.collectd_type)
for collectd_host, interface_host, port, tag in load(file, domain=collectd_domain) :
# flip from DNS-ordering -> path-ordering
if options.reverse_host :
interface_host = hostreverse(interface_host)
if options.collectd_instance == 'type' :
type = options.collectd_type + '-' + port
else :
type = options.collectd_type
if options.collectd_instance == 'plugin' :
plugin = collectd_plugin + '-' + port
else :
plugin = collectd_plugin
collectd_rrd = os.path.join(options.collectd_rrd, collectd_host, plugin, type) + '.rrd'
if not os.path.exists(collectd_rrd) :
log.warn("%s/%s: missing collectd rrd: %s", collectd_host, port, collectd_rrd)
continue
# out
interface_rrd = os.path.join(interface_host, tag + '.rrd')
log.debug("%s: %s", interface_rrd, collectd_rrd)
yield collectd_rrd, interface_rrd