1#!/usr/bin/env python 2 3""" 4Extract iperf data from json blob and format for gnuplot. 5""" 6 7import json 8import os 9import sys 10 11from optparse import OptionParser 12 13import pprint 14# for debugging, so output to stderr to keep verbose 15# output out of any redirected stdout. 16pp = pprint.PrettyPrinter(indent=4, stream=sys.stderr) 17 18 19def generate_output(iperf, options): 20 """Do the actual formatting.""" 21 for i in iperf.get('intervals'): 22 for ii in i.get('streams'): 23 if options.verbose: 24 pp.pprint(ii) 25 row = '{0} {1} {2} {3} {4}\n'.format( 26 round(float(ii.get('start')), 4), 27 ii.get('bytes'), 28 # to Gbits/sec 29 round(float(ii.get('bits_per_second')) / (1000*1000*1000), 3), 30 ii.get('retransmits'), 31 round(float(ii.get('snd_cwnd')) / (1000*1000), 2) 32 ) 33 yield row 34 35 36def main(): 37 """Execute the read and formatting.""" 38 usage = '%prog [ -f FILE | -o OUT | -v ]' 39 parser = OptionParser(usage=usage) 40 parser.add_option('-f', '--file', metavar='FILE', 41 type='string', dest='filename', 42 help='Input filename.') 43 parser.add_option('-o', '--output', metavar='OUT', 44 type='string', dest='output', 45 help='Optional file to append output to.') 46 parser.add_option('-v', '--verbose', 47 dest='verbose', action='store_true', default=False, 48 help='Verbose debug output to stderr.') 49 options, _ = parser.parse_args() 50 51 if not options.filename: 52 parser.error('Filename is required.') 53 54 file_path = os.path.normpath(options.filename) 55 56 if not os.path.exists(file_path): 57 parser.error('{f} does not exist'.format(f=file_path)) 58 59 with open(file_path, 'r') as fh: 60 data = fh.read() 61 62 try: 63 iperf = json.loads(data) 64 except Exception as ex: # pylint: disable=broad-except 65 parser.error('Could not parse JSON from file (ex): {0}'.format(str(ex))) 66 67 if options.output: 68 absp = os.path.abspath(options.output) 69 output_dir, _ = os.path.split(absp) 70 if not os.path.exists(output_dir): 71 parser.error('Output file directory path {0} does not exist'.format(output_dir)) 72 fh = open(absp, 'a') 73 else: 74 fh = sys.stdout 75 76 for i in generate_output(iperf, options): 77 fh.write(i) 78 79 80if __name__ == '__main__': 81 main()