pvl/rrd/hosts.py
author Tero Marttila <terom@paivola.fi>
Sun, 07 Sep 2014 14:40:31 +0300
changeset 428 956b3d4918bb
parent 425 4e828d47421a
permissions -rw-r--r--
pvl.rrd.hosts: also support @domain for the collectd host
"""
    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