rrdweb/backend.py
changeset 32 47e977c23ba2
equal deleted inserted replaced
31:cd9ca8068b09 32:47e977c23ba2
       
     1 from rrdweb import rrd
       
     2 
       
     3 import operator
       
     4 
       
     5 def host_def (idx, name, dir, ds_in, ds_out, cf) :
       
     6     """
       
     7         VDEFs for given host, giving its avg/max values:
       
     8 
       
     9             DEF:in/out_{idx}
       
    10             CDEFtraf_{idx}
       
    11             VDEF:avg/max_{idx}
       
    12             PRINT:{idx} avg/max {value}
       
    13     """
       
    14 
       
    15     params = dict(
       
    16         dir=dir, ds_in=ds_in, ds_out=ds_out, cf=cf,
       
    17         idx=idx, rrd='%s/%s.rrd' % (dir, name)
       
    18     )
       
    19 
       
    20     return [
       
    21         # in/out bandwidth in bytes/s
       
    22         'DEF:in_%(idx)d=%(rrd)s:%(ds_in)s:%(cf)s' % params,
       
    23         'DEF:out_%(idx)d=%(rrd)s:%(ds_out)s:%(cf)s' % params,
       
    24 
       
    25         # total traffic in bits/s
       
    26         'CDEF:traf_%(idx)d=in_%(idx)d,out_%(idx)d,+,8,*' % params,
       
    27 
       
    28         # average + maximum values
       
    29         'VDEF:avg_%(idx)d=traf_%(idx)d,AVERAGE' % params,
       
    30         'VDEF:max_%(idx)d=traf_%(idx)d,MAXIMUM' % params,
       
    31 
       
    32         # output
       
    33         'PRINT:avg_%(idx)d:%(idx)d avg %%lf' % params,
       
    34         'PRINT:max_%(idx)d:%(idx)d max %%lf' % params,
       
    35     ]
       
    36 
       
    37 def parse_report (rrds, lines) :
       
    38     """
       
    39         Parse the report output into a [ (name, avg, max) ] list
       
    40     """
       
    41 
       
    42     # idx values by type
       
    43     data = {
       
    44         'avg': {},
       
    45         'max': {},
       
    46         }
       
    47 
       
    48     # interpret output
       
    49     for line in lines :
       
    50         # parse
       
    51         idx, type, value = line.split()
       
    52         
       
    53         # convert
       
    54         idx = int(idx)
       
    55         value = float(value)
       
    56         
       
    57         # store
       
    58         data[type][idx] = value
       
    59     
       
    60     # build into name : (values) dict
       
    61     return [
       
    62         (
       
    63             (name, data['avg'][idx], data['max'][idx])
       
    64         ) for idx, name in enumerate(rrds)
       
    65     ]
       
    66 
       
    67 def calc_top_hosts (dir, rrds, ds_in, ds_out, period='15m', count=5, cf='AVERAGE') :
       
    68     """
       
    69         Return the list of top-N rrd's in the given dir, sorted by total in/out bandwidth average over the given period.
       
    70     """
       
    71 
       
    72     # vdefs for hosts, avg/max_<idx> in bits/s + prints
       
    73     defs = [stmt for idx, name in enumerate(rrds) for stmt in host_def(idx, name, dir, ds_in, ds_out, cf)]
       
    74     
       
    75     # execute
       
    76     _, _, output, _ = rrd.graph(False, *defs, start=('-%s' % period))
       
    77     
       
    78     # parse
       
    79     data = parse_report(rrds, output)
       
    80 
       
    81     # sort for top-N avg
       
    82     data.sort(key=operator.itemgetter(1))
       
    83     top_avg = data[:count]
       
    84 
       
    85     # sort for top-N max
       
    86     data.sort(key=operator.itemgetter(2))
       
    87     top_max = data[:count]
       
    88 
       
    89     # merge hosts (we lose sorting order)
       
    90     return set(host for host, avg, max in top_avg + top_max)
       
    91 
       
    92