rrdweb/pmacct.py
author Tero Marttila <terom@fixme.fi>
Sun, 23 Jan 2011 13:50:13 +0200
changeset 29 c756e522c9ac
permissions -rw-r--r--
pmacct: load pmacct data to rrd
29
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
"""
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
    A pmacct -> rrd runner
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
"""
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
import collections
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
import subprocess
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
import os.path
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
import logging
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
from rrdweb import rrd
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
log = logging.getLogger('rrdweb.pmacct')
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
## pmacct
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
# name to invoke `pmacct` as
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
PMACCT_CMD = 'pmacct'
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
# path to in/out client sockets
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
PMACCT_IN_SOCK = 'var/pmacct/host-in.sock'
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
PMACCT_OUT_SOCK = 'var/pmacct/host-out.sock'
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    22
## RRD
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    23
# path to rrd data dir
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
RRD_ROOT = 'var/rrd'
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
# path to per-host RRD file
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
HOST_RRD_PATH = '{rrd_root}/{host_ip}.rrd'
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    29
## RRD create params
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    30
# step interval (in seconds)
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
RRD_STEP = 60
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    33
# Data Source parameters
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    34
DS_TYPE = 'COUNTER'
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    35
DS_HEARTBEAT = RRD_STEP * 2
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    36
DS_BYTES_MIN = 0
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
DS_BYTES_MAX = (1000 ** 3) / 8        # 1gbps
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    38
DS_PKTS_MIN = 0
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    39
DS_PKTS_MAX = DS_BYTES_MAX / 64       # 1gbps @ 64 bytes-per-packet
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    40
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
def pmacct_cmd (*args) :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
    """
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
        Invoke the pmacct client, yielding the output as a series of lines.
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
    """
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
    
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
    # argv with name of executable in [0]
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
    argv = (PMACCT_CMD, ) + args
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
    
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
    # invoke
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
    proc = subprocess.Popen(argv, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
    # XXX: manipulate the pipes directly, to efficiently stream the output... without deadlocking..
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
    # interact (nothing on stdin)
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
    stdout, stderr = proc.communicate()
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
    # error-check
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
    if proc.returncode :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
        raise Exception("pmacct terminated with status=%d" % (proc.returncode, ))
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    60
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
    # stderr?
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
    if stderr :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
        raise Exception("pmacct terminated with errors: %s" % (stderr, ))
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
    # output
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
    for line in stdout.splitlines() :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
        yield line
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
def pmacct_summary (socket) :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
    """
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
        Query and return summary-form data from pacct, by querying the full table and parsing it.
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    72
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
        Yields a series of { field: value } dicts for each row in the table.
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
    """
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
    
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
    # `pmacct -s`
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
    output = pmacct_cmd('-p', socket, '-s')
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
    
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    79
    # the list of fields, parsed from the first line of output
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
    fields = None
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
    
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
    for line in output :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
        if not fields :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
            # parse first row
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
            fields = line.split()
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
            continue
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
        
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
        if not line :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
            # end of data
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    91
            break
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
        # parse field data
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
        values = line.split()
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
        # map by field name
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
        data = dict(zip(fields, values))
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
        yield data
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
class Host (object) :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
    """
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
        Traffic counters for some specific host.
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
    """
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
    __slots__ = ('ip', 'in_ok', 'out_ok', 'in_bytes', 'out_bytes', 'in_packets', 'out_packets')
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
    def __init__ (self, ip=None) :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
        self.ip = ip
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
        self.in_ok = self.out_ok = False
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
        self.in_bytes = self.out_bytes = self.in_packets = self.out_packets = 0
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
    def __repr__ (self) :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   115
        return 'Host(%s)' % ', '.join('%s=%r' % (name, getattr(self, name)) for name in self.__slots__)
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   116
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   117
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   118
def host_counters (in_table, out_table) :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   119
    """
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   120
        Returns the full set of in/out traffic counters for all hosts currently in the summary table.
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   122
        This processes the two tables given, by their SRC_IP/DST_IP fields.
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   124
        For each SRC_IP in the out_table, outgoing traffic is counted.
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
        For each DST_IP in the in_table, incoming traffic is counted.
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   126
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   127
        Returns a { host: Host } mapping containing the traffic counters for all hosts in the two tables.
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   128
    """
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   129
    
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
    # combined set of hosts
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
    hosts = collections.defaultdict(Host)
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
    
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
    # process incoming
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
    for row in in_table :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
        ip = row['DST_IP']
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   137
        host = hosts[ip]
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   138
        
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   139
        host.ip = ip
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
        host.in_ok = True
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
        host.in_bytes += int(row['BYTES'])
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
        host.in_packets += int(row['PACKETS'])
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
    
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   144
    # process outgoing
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
    for row in out_table :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
        ip = row['SRC_IP']
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   148
        host = hosts[ip]
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   149
        
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   150
        host.ip = ip
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   151
        host.out_ok = True
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   152
        host.out_bytes += int(row['BYTES'])
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   153
        host.out_packets += int(row['PACKETS'])
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   154
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   155
    return dict(hosts)
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
def create_host_rrd (path, rrd_step=RRD_STEP, ds_type=DS_TYPE, heartbeat=DS_HEARTBEAT, bytes_min=DS_BYTES_MIN, bytes_max=DS_BYTES_MAX, pkts_min=DS_PKTS_MIN, pkts_max=DS_PKTS_MAX, rrd_root='XXX') :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   158
    """
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   159
        Create a new .rrd file for the per-host traffic data at the given path.
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
    """
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   162
    # data sources
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
    ds_list = (
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
        # bytes
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   165
        ('in',          ds_type, bytes_min, bytes_max),
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
        ('out',         ds_type, bytes_min, bytes_max),
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   167
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
        # packets
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
        ('in_pkts',     ds_type, pkts_min, pkts_max),
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
        ('out_pkts',    ds_type, pkts_min, pkts_max),
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
    )
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
    HOUR = 60 * 60
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
    # archives
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   176
    rra_list = (
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   177
        ('AVERAGE', 0.5, 1, 1 * HOUR / RRD_STEP),  # 1 hour
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   178
    )
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
    # definitions
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
    defs = [
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
        (
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
            'DS:%s:%s:%s:%s:%s' % (name, type, heartbeat, min, max)
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
        ) for name, type, min, max in ds_list
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   185
    ] + [
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
        (
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
            'RRA:%s:%s:%s:%s' % (func, xff, steps, rows)
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
        ) for func, xff, steps, rows in rra_list
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
    ]
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
    
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
    # create using the given step
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
    rrd.create(path, *defs, step=rrd_step)
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
def update_host_rrd (path, host) :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   195
    """
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   196
        Update the .rrd file with the given current counter values.
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   197
    """
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   198
    
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   199
    # values to insert
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
    values = (
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   201
        # bytes
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   202
        ('in',          host.in_bytes if host.in_ok else 'U'),
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
        ('out',         host.out_bytes if host.out_ok else 'U'),
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   204
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
        # packets
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   206
        ('in_pkts',     host.in_packets if host.in_ok else 'U'),
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   207
        ('out_pkts',    host.out_packets if host.out_ok else 'U'),
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   208
    )
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   209
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   210
    log.debug("Update %s: %r", path, values)
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   211
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   212
    # go
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   213
    rrd.update(path, 
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   214
        # new values for current time
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   215
        'N:' + ':'.join(str(value) for ds, value in values),
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   216
        
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   217
        # names of DSs we give values for
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   218
        template    = ':'.join(name for name, value in values),
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   219
    )
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   220
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   221
def update_host (host, **rrd_opts) :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   222
    """
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   223
        Update the host's .rrd file in rrd_root with the host's data.
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   224
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   225
        Creates .rrd files for new hosts automatically, using the given options.
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   226
    """
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   227
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   228
    # path to .rrd
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   229
    rrd = HOST_RRD_PATH.format(host_ip = host.ip, **rrd_opts)
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   230
    
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   231
    # create?
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   232
    if not os.path.exists(rrd) :
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   233
        log.info("Create new .rrd for %s: %s", host.ip, rrd)
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   234
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   235
        create_host_rrd(rrd, **rrd_opts)
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   236
    
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   237
    # update
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   238
    update_host_rrd(rrd, host)
c756e522c9ac pmacct: load pmacct data to rrd
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   239