From c50b5ea849ca07ca3d27d46dcb200f67ba7e6b81 Mon Sep 17 00:00:00 2001 From: Brian Tierney Date: Tue, 15 Dec 2015 15:26:55 -0800 Subject: [PATCH] adding scripts to generate gnuplots from iperf3 data --- contrib/README.txt | 7 ++++ contrib/iperf3.gp | 37 +++++++++++++++++ contrib/iperf3_to_gnuplot.py | 77 ++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 contrib/README.txt create mode 100644 contrib/iperf3.gp create mode 100755 contrib/iperf3_to_gnuplot.py diff --git a/contrib/README.txt b/contrib/README.txt new file mode 100644 index 0000000..346e593 --- /dev/null +++ b/contrib/README.txt @@ -0,0 +1,7 @@ + +This directory contains files that might be useful to analyze iperf3 results + +iperf3_to_gnuplot.py: converts iperf3 JSON output to format easy to plot in gnuplot + +iperf3.gp: sample gnuplot commands to plot throught and retransmits + diff --git a/contrib/iperf3.gp b/contrib/iperf3.gp new file mode 100644 index 0000000..0bf49ea --- /dev/null +++ b/contrib/iperf3.gp @@ -0,0 +1,37 @@ +# +# sample Gnuplot command file for iperf3 results +set term x11 +#set term png +#set term postscript landscape color +set key width -12 + +# iperf3 data fields +#start bytes bits_per_second retransmits snd_cwnd + +set output "iperf3.png" +#set output "iperf3.eps" + +#set nokey + +set grid xtics +set grid ytics +set grid linewidth 1 +set title "TCP performance: 40G to 10G host" +set xlabel "time (seconds)" +set ylabel "Bandwidth (Gbits/second)" +set xrange [0:60] +set yrange [0:15] +set ytics nomirror +set y2tics +set y2range [0:2500] +# dont plot when retransmits = 0 +set datafile missing '0' +set pointsize 1.6 + +plot "40Gto10G.old.dat" using 1:3 title '3.10 kernel' with linespoints lw 3 pt 5, \ + "40Gto10G.new.dat" using 1:3 title '4.2 kernel' with linespoints lw 3 pt 7, \ + "40Gto10G.old.dat" using 1:4 title 'retransmits' with points pt 7 axes x1y2 + +#plot "iperf3.old.dat" using 1:3 title '3.10 kernel' with linespoints lw 3 pt 5, \ +# "iperf3.new.dat" using 1:3 title '4.2 kernel' with linespoints lw 3 pt 7 + diff --git a/contrib/iperf3_to_gnuplot.py b/contrib/iperf3_to_gnuplot.py new file mode 100755 index 0000000..a37be48 --- /dev/null +++ b/contrib/iperf3_to_gnuplot.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python + +""" +Extract iperf data from json blob and format for gnuplot. +""" + +import json +import os +import sys + +import os.path +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): + 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 main(): + 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('-v', '--verbose', + dest='verbose', action='store_true', default=False, + help='Verbose debug output to stderr.') + options, args = 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 e: + parser.error('Could not parse JSON from file (ex): {0}'.format(str(e))) + + if options.output: + absp = os.path.abspath(options.output) + d,f = os.path.split(absp) + if not os.path.exists(d): + parser.error('Output file directory path {0} does not exist'.format(d)) + fh = open(absp, 'a') + else: + fh = sys.stdout + + for i in generate_output(iperf, options): + fh.write(i) + + +if __name__ == '__main__': + main() \ No newline at end of file