diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 18:21:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 18:21:43 +0000 |
commit | c8c3bd06ef1a7248c8195d050d8a4075d051256e (patch) | |
tree | 419655deec1b0af0c5d3ec488693f1494fb20959 /contrib/iperf3_to_gnuplot.py | |
parent | Initial commit. (diff) | |
download | iperf3-c8c3bd06ef1a7248c8195d050d8a4075d051256e.tar.xz iperf3-c8c3bd06ef1a7248c8195d050d8a4075d051256e.zip |
Adding upstream version 3.16.upstream/3.16
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'contrib/iperf3_to_gnuplot.py')
-rwxr-xr-x | contrib/iperf3_to_gnuplot.py | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/contrib/iperf3_to_gnuplot.py b/contrib/iperf3_to_gnuplot.py new file mode 100755 index 0000000..6a1f7a0 --- /dev/null +++ b/contrib/iperf3_to_gnuplot.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python + +""" +Extract iperf data from json blob and format for gnuplot. +""" + +import json +import os +import sys + +from optparse import OptionParser + +import pprint +# for debugging, so output to stderr to keep verbose +# output out of any redirected stdout. +pp = pprint.PrettyPrinter(indent=4, stream=sys.stderr) + + +def generate_output(iperf, options): + """Do the actual formatting.""" + for i in iperf.get('intervals'): + for ii in i.get('streams'): + if options.verbose: + pp.pprint(ii) + row = '{0} {1} {2} {3} {4}\n'.format( + round(float(ii.get('start')), 4), + ii.get('bytes'), + # to Gbits/sec + round(float(ii.get('bits_per_second')) / (1000*1000*1000), 3), + ii.get('retransmits'), + round(float(ii.get('snd_cwnd')) / (1000*1000), 2) + ) + yield row + + +def summed_output(iperf, options): + """Format summed output.""" + + for i in iperf.get('intervals'): + + row_header = None + + byte = list() + bits_per_second = list() + retransmits = list() + snd_cwnd = list() + + for ii in i.get('streams'): + if options.verbose: + pp.pprint(i) + # grab the first start value + if row_header is None: + row_header = round(float(ii.get('start')), 2) + # aggregate the rest of the values + byte.append(ii.get('bytes')) + bits_per_second.append(float(ii.get('bits_per_second')) / (1000*1000*1000)) + retransmits.append(ii.get('retransmits')) + snd_cwnd.append(float(ii.get('snd_cwnd')) / (1000*1000)) + + row = '{h} {b} {bps} {r} {s}\n'.format( + h=row_header, + b=sum(byte), + bps=round(sum(bits_per_second), 3), + r=sum(retransmits), + s=round(sum(snd_cwnd) / len(snd_cwnd), 2) + ) + + yield row + + +def main(): + """Execute the read and formatting.""" + usage = '%prog [ -f FILE | -o OUT | -v ]' + parser = OptionParser(usage=usage) + parser.add_option('-f', '--file', metavar='FILE', + type='string', dest='filename', + help='Input filename.') + parser.add_option('-o', '--output', metavar='OUT', + type='string', dest='output', + help='Optional file to append output to.') + parser.add_option('-s', '--sum', + dest='summed', action='store_true', default=False, + help='Summed version of the output.') + parser.add_option('-v', '--verbose', + dest='verbose', action='store_true', default=False, + help='Verbose debug output to stderr.') + options, _ = parser.parse_args() + + if not options.filename: + parser.error('Filename is required.') + + file_path = os.path.normpath(options.filename) + + if not os.path.exists(file_path): + parser.error('{f} does not exist'.format(f=file_path)) + + with open(file_path, 'r') as fh: + data = fh.read() + + try: + iperf = json.loads(data) + except Exception as ex: # pylint: disable=broad-except + parser.error('Could not parse JSON from file (ex): {0}'.format(str(ex))) + + if options.output: + absp = os.path.abspath(options.output) + output_dir, _ = os.path.split(absp) + if not os.path.exists(output_dir): + parser.error('Output file directory path {0} does not exist'.format(output_dir)) + fh = open(absp, 'a') + else: + fh = sys.stdout + + if options.summed: + fmt = summed_output + else: + fmt = generate_output + + for i in fmt(iperf, options): + fh.write(i) + + +if __name__ == '__main__': + main() |