terom@32: from rrdweb import rrd terom@32: terom@32: import operator terom@32: terom@32: def host_def (idx, name, dir, ds_in, ds_out, cf) : terom@32: """ terom@32: VDEFs for given host, giving its avg/max values: terom@32: terom@32: DEF:in/out_{idx} terom@32: CDEFtraf_{idx} terom@32: VDEF:avg/max_{idx} terom@32: PRINT:{idx} avg/max {value} terom@32: """ terom@32: terom@32: params = dict( terom@32: dir=dir, ds_in=ds_in, ds_out=ds_out, cf=cf, terom@32: idx=idx, rrd='%s/%s.rrd' % (dir, name) terom@32: ) terom@32: terom@32: return [ terom@32: # in/out bandwidth in bytes/s terom@32: 'DEF:in_%(idx)d=%(rrd)s:%(ds_in)s:%(cf)s' % params, terom@32: 'DEF:out_%(idx)d=%(rrd)s:%(ds_out)s:%(cf)s' % params, terom@32: terom@32: # total traffic in bits/s terom@32: 'CDEF:traf_%(idx)d=in_%(idx)d,out_%(idx)d,+,8,*' % params, terom@32: terom@32: # average + maximum values terom@32: 'VDEF:avg_%(idx)d=traf_%(idx)d,AVERAGE' % params, terom@32: 'VDEF:max_%(idx)d=traf_%(idx)d,MAXIMUM' % params, terom@32: terom@32: # output terom@32: 'PRINT:avg_%(idx)d:%(idx)d avg %%lf' % params, terom@32: 'PRINT:max_%(idx)d:%(idx)d max %%lf' % params, terom@32: ] terom@32: terom@32: def parse_report (rrds, lines) : terom@32: """ terom@32: Parse the report output into a [ (name, avg, max) ] list terom@32: """ terom@32: terom@32: # idx values by type terom@32: data = { terom@32: 'avg': {}, terom@32: 'max': {}, terom@32: } terom@32: terom@32: # interpret output terom@32: for line in lines : terom@32: # parse terom@32: idx, type, value = line.split() terom@32: terom@32: # convert terom@32: idx = int(idx) terom@32: value = float(value) terom@32: terom@32: # store terom@32: data[type][idx] = value terom@32: terom@32: # build into name : (values) dict terom@32: return [ terom@32: ( terom@32: (name, data['avg'][idx], data['max'][idx]) terom@32: ) for idx, name in enumerate(rrds) terom@32: ] terom@32: terom@32: def calc_top_hosts (dir, rrds, ds_in, ds_out, period='15m', count=5, cf='AVERAGE') : terom@32: """ terom@32: Return the list of top-N rrd's in the given dir, sorted by total in/out bandwidth average over the given period. terom@32: """ terom@32: terom@32: # vdefs for hosts, avg/max_ in bits/s + prints terom@32: defs = [stmt for idx, name in enumerate(rrds) for stmt in host_def(idx, name, dir, ds_in, ds_out, cf)] terom@32: terom@32: # execute terom@32: _, _, output, _ = rrd.graph(False, *defs, start=('-%s' % period)) terom@32: terom@32: # parse terom@32: data = parse_report(rrds, output) terom@32: terom@32: # sort for top-N avg terom@32: data.sort(key=operator.itemgetter(1)) terom@32: top_avg = data[:count] terom@32: terom@32: # sort for top-N max terom@32: data.sort(key=operator.itemgetter(2)) terom@32: top_max = data[:count] terom@32: terom@32: # merge hosts (we lose sorting order) terom@32: return set(host for host, avg, max in top_avg + top_max) terom@32: terom@32: