"""
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
if '@' in host :
host, host_domain = host.split('@')
else:
host_domain = domain
if '@' in node :
node, node_domain = node.split('@')
else:
node_domain = domain
# host has domain in collectd?
if host_domain :
host = hostjoin(host, host_domain)
if not parts :
# keep host for following lines
continue
instance = parts.pop(0)
# possibly multiple tags..
for tag in parts :
yield host, instance, (node_domain, node, tag)
def map_interfaces (options, file):
"""
Read (hostname, instance}: (nodename, tag) pairs from file.
"""
for host, instance, node_info in load(file) :
log.debug("%s/%s -> %s", host, instance, node_info)
yield (host, instance), node_info
def collectd_interfaces (options, file, collectd_domain, collectd_plugin) :
"""
Read collectd (host, instance, (domain, node, tag)) items, and yield (collectd-rrd, node_info) 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("%s/${host}.%s/%s/%s-${instance}.rrd", options.collectd_rrd, collectd_domain, collectd_plugin, options.collectd_type)
for host, instance, node_info in load(file, domain=collectd_domain) :
if options.collectd_instance == 'type' :
type = options.collectd_type + '-' + instance
else :
type = options.collectd_type
if options.collectd_instance == 'plugin' :
plugin = collectd_plugin + '-' + instance
else :
plugin = collectd_plugin
rrd = os.path.join(options.collectd_rrd, host, plugin, type) + '.rrd'
if not os.path.exists(rrd) :
log.warn("%s/%s: missing collectd rrd: %s", host, instance, rrd)
continue
# out
log.debug("%s: %s", rrd, node_info)
yield rrd, node_info