The following changes since commit 0d81daf9d164c4bf829f4911e1f7b211c2e661fb: Init buflen for our dummy buffer (2013-07-09 18:45:19 -0600) are available in the git repository at: git://git.kernel.dk/fio.git master Erwan Velu (14): Adding genfio tool : an fio job creator Adding fio2gnuplot tool genfio: Adding runtime=0 support genfio: Adding cached_based option genfio: Claryfing default options genfio: Adding prefix to fio filename genfio: Fixing empty ETA while runtime > 0 fio2gnuplot: Adding 2D graphs for each fio trace fio2gnuplot: Adding sample files fio2gnuplot: Don't graph 3D if not enough data fio2gnuplot: Adjusting y axis plot (2D) genfio: Warn users if read occurs before write genfio: Adding iodepth support genfio: Enforce time_based if runtime > 0 tools/genfio | 323 ++++++++++++++++++++++++++++++++ tools/plot/fio2gnuplot.py | 360 ++++++++++++++++++++++++++++++++++++ tools/plot/graph2D.gpm | 34 ++++ tools/plot/graph3D.gpm | 80 ++++++++ tools/plot/math.gpm | 25 +++ tools/plot/samples/Makefile | 19 ++ tools/plot/samples/fio-logs.tar.gz | Bin 0 -> 68085 bytes 7 files changed, 841 insertions(+), 0 deletions(-) create mode 100755 tools/genfio create mode 100755 tools/plot/fio2gnuplot.py create mode 100644 tools/plot/graph2D.gpm create mode 100644 tools/plot/graph3D.gpm create mode 100644 tools/plot/math.gpm create mode 100644 tools/plot/samples/Makefile create mode 100644 tools/plot/samples/fio-logs.tar.gz --- Diff of recent changes: diff --git a/tools/genfio b/tools/genfio new file mode 100755 index 0000000..6d3220d --- /dev/null +++ b/tools/genfio @@ -0,0 +1,323 @@ +#!/bin/bash +# +# Copyright (C) 2013 eNovance SAS <licensing@xxxxxxxxxxxx> +# Author: Erwan Velu <erwan@xxxxxxxxxxxx> +# +# The license below covers all files distributed with fio unless otherwise +# noted in the file itself. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +BLK_SIZE= +BLOCK_SIZE=4k +SEQ=-1 +TEMPLATE=/tmp/template.fio +OUTFILE= +DISKS= +RUNTIME=300 +ETA=0 +MODES="write,randwrite,read,randread" +SHORT_HOSTNAME= +CACHED_IO="FALSE" +PREFIX="" +PREFIX_FILENAME="" +IODEPTH=1 + +show_help() { + PROG=$(basename $0) + echo "usage of $PROG:" + cat << EOF +-h : Show this help & exit +-c : Enable cached-based IOs + Disabled by default +-a : Run sequential test then parallel one + Disabled by default +-s : Run sequential test (default value) + one test after another then one disk after another + Disabled by default +-p : Run parallel test + one test after anoter but all disks at the same time + Enabled by default +-D iodepth : Run with the specified iodepth + Default is 32 +-d disk1[,disk2,disk3,..] : Run the tests on the selected disks + Separated each disk with a comma + Disk name shall be "sdxx", /dev/ shall NOT be used here +-r seconds : Time in seconds per benchmark + 0 means till the end of the device + Default is 300 seconds +-b blocksize[,blocksize1, ...] : The blocksizes to test under fio format (4k, 1m, ...) + Separated each blocksize with a comma + Default is 4k +-m mode1,[mode2,mode3, ...] : Define the fio IO profile to use like read, write, randread, randwrite + Default is "write,randwrite,read,randread" +-x prefix : Add a prefix to the fio filename + Useful to let a context associated with the file + If the prefix features a / (slash), prefix will be considered as a directory + +Example: + +$PROG -d sdb,sdc,sdd,sde -a -b 4k,128k,1m -r 100 -a -x dellr720-day2/ + + Will generate an fio file that will run + - a sequential bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 4k with write,randwrite,read,randread tests + ETA ~ 4 tests * 4 disks * 100 seconds + - a sequential bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 128k with write,randwrite,read,randread tests + ETA ~ 4 tests * 4 disks * 100 seconds + - a sequential bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 1m with write,randwrite,read,randread tests + ETA ~ 4 tests * 4 disks * 100 seconds + - a parallel bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 4k with write,randwrite,read,randread tests + ETA ~ 4 tests * 100 seconds + - a parallel bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 128k with write,randwrite,read,randread tests + ETA ~ 4 tests * 100 seconds + - a parallel bench on /dev/sdb /dev/sdc /dev/sdd /dev/sde for block size = 1m with write,randwrite,read,randread tests + ETA ~ 4 tests * 100 seconds + +Generating dellr720-day2/localhost-4k,128k,1m-all-write,randwrite,read,randread-sdb,sdc,sdd,sde.fio +Estimated Time = 6000 seconds : 1 hour 40 minutes +EOF +} + +gen_template() { +cat >$TEMPLATE << EOF +[global] +ioengine=libaio +iodepth=$IODEPTH +invalidate=1 +ramp_time=5 +EOF + +if [ "$RUNTIME" != "0" ]; then +cat >>$TEMPLATE << EOF +runtime=$RUNTIME +time_based +EOF +fi + +if [ "$CACHED_IO" = "FALSE" ]; then +cat >>$TEMPLATE << EOF +direct=1 +EOF +fi + +} + +gen_seq_suite() { +TYPE=$1 +cat >> $OUTFILE << EOF +[$TYPE-$disk-$BLK_SIZE-seq] +stonewall +bs=$BLK_SIZE +filename=/dev/$disk +rw=$TYPE +write_bw_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$disk-$TYPE-seq.results +write_iops_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$disk-$TYPE-seq.results +EOF +ETA=$(($ETA + $RUNTIME)) +} + +gen_seq_fio() { +for disk in $(echo $DISKS | tr "," " "); do + for mode in $(echo $MODES | tr "," " "); do + gen_seq_suite "$mode" + done +done +} + + +gen_para_suite() { +TYPE=$1 +NEED_WALL=$2 +D=0 +for disk in $(echo $DISKS | tr "," " "); do + cat >> $OUTFILE << EOF +[$TYPE-$disk-$BLK_SIZE-para] +bs=$BLK_SIZE +EOF + +if [ "$D" = 0 ]; then + echo "stonewall" >> $OUTFILE + D=1 +fi + +cat >> $OUTFILE << EOF +filename=/dev/$disk +rw=$TYPE +write_bw_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$disk-$TYPE-para.results +write_iops_log=${PREFIX_FILENAME}$SHORT_HOSTNAME-$BLK_SIZE-$disk-$TYPE-para.results +EOF +done + +ETA=$(($ETA + $RUNTIME)) +echo >> $OUTFILE +} + +gen_para_fio() { +for mode in $(echo $MODES | tr "," " "); do + gen_para_suite "$mode" +done +} + +gen_fio() { +case $SEQ in + 2) + gen_seq_fio + gen_para_fio + ;; + 1) + gen_seq_fio + ;; + 0) + gen_para_fio + ;; +esac +} + +parse_cmdline() { +while getopts "hacpsd:b:r:m:x:D:" opt; do + case $opt in + h) + show_help + exit 0 + ;; + b) + BLOCK_SIZE=$OPTARG + ;; + c) + CACHED_IO="TRUE" + ;; + s) + if [ "$SEQ" = "-1" ]; then + SEQ=1 + fi + ;; + x) + PREFIX=$OPTARG + echo "$PREFIX" | grep -q "/" + if [ "$?" -eq 0 ]; then + mkdir -p $PREFIX + # No need to keep the prefix for the log files + # we do have a directory for that + PREFIX_FILENAME="" + else + # We need to keep the prefix for the log files + PREFIX_FILENAME=$PREFIX + fi + ;; + r) + RUNTIME=$OPTARG + ;; + p) + if [ "$SEQ" = "-1" ]; then + SEQ=0 + fi + ;; + m) + MODES=$OPTARG; + ;; + d) + DISKS=$OPTARG + ;; + D) + IODEPTH=$OPTARG + ;; + a) + SEQ=2 + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + ;; + esac +done + +if [ "$SEQ" = "-1" ]; then + SEQ=0 +fi + +SHORT_HOSTNAME=$(hostname -s) +case $SEQ in + 2) + OUTFILE=${PREFIX}$SHORT_HOSTNAME-$BLOCK_SIZE-all-$MODES-$DISKS.fio + ;; + + 1) + OUTFILE=${PREFIX}$SHORT_HOSTNAME-$BLOCK_SIZE-sequential-$MODES-$DISKS.fio + ;; + 0) + OUTFILE=${PREFIX}$SHORT_HOSTNAME-$BLOCK_SIZE-parallel-$MODES-$DISKS.fio + ;; +esac + +if [ -z "$DISKS" ]; then + echo "Missing DISKS !" + echo "Please read the help !" + show_help + exit 1 +fi + +} + +check_mode_order() { +FOUND_WRITE="NO" +CAUSE="You are reading data before writing them " + +# If no write occurs, let's show a different message +echo $MODES | grep -q "write" +if [ "$?" -ne 0 ]; then + CAUSE="You are reading data while never wrote them before" +fi + +for mode in $(echo $MODES | tr "," " "); do + echo $mode | grep -q write + if [ "$?" -eq 0 ]; then + FOUND_WRITE="YES" + fi + echo $mode | grep -q "read" + if [ "$?" -eq 0 ]; then + if [ "$FOUND_WRITE" = "NO" ]; then + echo "###############################################################" + echo "# Warning : $CAUSE#" + echo "# On some storage devices, this could lead to invalid results #" + echo "# #" + echo "# Press Ctrl-C to adjust pattern order if you have doubts #" + echo "# Or Wait 5 seconds before the file will be created #" + echo "###############################################################" + sleep 5 + # No need to try showing the message more than one time + return + fi + fi +done +} + + +########## MAIN +parse_cmdline $@ +check_mode_order +gen_template + +echo "Generating $OUTFILE" +cp -f $TEMPLATE $OUTFILE +echo >> $OUTFILE + +for BLK_SIZE in $(echo $BLOCK_SIZE | tr "," " "); do + gen_fio +done +ETA_H=$(($ETA / 3600)) +ETA_M=$((($ETA - ($ETA_H*3600)) / 60)) +if [ "$ETA" = "0" ]; then + echo "Cannot estimate ETA as RUNTIME=0" +else + echo "Estimated Time = $ETA seconds : $ETA_H hour $ETA_M minutes" +fi diff --git a/tools/plot/fio2gnuplot.py b/tools/plot/fio2gnuplot.py new file mode 100755 index 0000000..ef32ee0 --- /dev/null +++ b/tools/plot/fio2gnuplot.py @@ -0,0 +1,360 @@ +#!/usr/bin/python +# +# Copyright (C) 2013 eNovance SAS <licensing@xxxxxxxxxxxx> +# Author: Erwan Velu <erwan@xxxxxxxxxxxx> +# +# The license below covers all files distributed with fio unless otherwise +# noted in the file itself. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import os +import fnmatch +import sys +import getopt +import re +import math + +def find_file(path, pattern): + fio_data_file=[] + # For all the local files + for file in os.listdir(path): + # If the file math the regexp + if fnmatch.fnmatch(file, pattern): + # Let's consider this file + fio_data_file.append(file) + + return fio_data_file + +def generate_gnuplot_script(fio_data_file,title,gnuplot_output_filename,mode,disk_perf): + f=open("mygraph",'w') + if len(fio_data_file) > 1: + f.write("call \'graph3D.gpm\' \'%s' \'%s\' \'\' \'%s\' \'%s\'\n" % (title,gnuplot_output_filename,gnuplot_output_filename,mode)) + + pos=0 + # Let's create a temporary file for each selected fio file + for file in fio_data_file: + tmp_filename = "gnuplot_temp_file.%d" % pos + png_file=file.replace('.log','') + raw_filename = "%s-2Draw" % (png_file) + smooth_filename = "%s-2Dsmooth" % (png_file) + trend_filename = "%s-2Dtrend" % (png_file) + avg = average(disk_perf[pos]) + f.write("call \'graph2D.gpm\' \'%s' \'%s\' \'\' \'%s\' \'%s\' \'%s\' \'%s\' \'%f\'\n" % (title,tmp_filename,raw_filename,mode,smooth_filename,trend_filename,avg)) + pos = pos +1 + + f.close() + +def generate_gnuplot_math_script(title,gnuplot_output_filename,mode,average): + f=open("mymath",'a') + f.write("call \'math.gpm\' \'%s' \'%s\' \'\' \'%s\' \'%s\' %s\n" % (title,gnuplot_output_filename,gnuplot_output_filename,mode,average)) + f.close() + +def compute_aggregated_file(fio_data_file, gnuplot_output_filename): + temp_files=[] + pos=0 + # Let's create a temporary file for each selected fio file + for file in fio_data_file: + tmp_filename = "gnuplot_temp_file.%d" % pos + temp_files.append(open(tmp_filename,'r')) + pos = pos +1 + + f = open(gnuplot_output_filename, "w") + index=0 + # Let's add some information + for tempfile in temp_files: + f.write("# Disk%d was coming from %s\n" % (index,fio_data_file[index])) + f.write(tempfile.read()) + f.write("\n") + tempfile.close() + index = index + 1 + f.close() + +def average(s): return sum(s) * 1.0 / len(s) + +def compute_temp_file(fio_data_file,disk_perf): + files=[] + temp_outfile=[] + blk_size=0 + for file in fio_data_file: + files.append(open(file)) + pos = len(files) - 1 + tmp_filename = "gnuplot_temp_file.%d" % pos + temp_outfile.append(open(tmp_filename,'w')) + disk_perf.append([]) + + shall_break = False + while True: + current_line=[] + for file in files: + s=file.readline().replace(',',' ').split() + if not s: + shall_break=True + break; + current_line.append(s); + + if shall_break == True: + break + + last_time = -1 + index=0 + perfs=[] + for line in current_line: + time, perf, x, block_size = line + if (blk_size == 0): + blk_size=int(block_size) + + # We ignore the first 500msec as it doesn't seems to be part of the real benchmark + # Time < 500 usually reports BW=0 breaking the min computing + if ((int(time)) > 500): + disk_perf[index].append(int(perf)) + perfs.append(perf) + index = index + 1 + + # If we reach this point, it means that all the traces are coherent + for p in enumerate(perfs): + temp_outfile[p[0]].write("%s %.2f %s\n" % (p[0], float(float(time)/1000), p[1])) + + for file in files: + file.close() + for file in temp_outfile: + file.close() + return blk_size + +def compute_math(fio_data_file, title,gnuplot_output_filename,mode,disk_perf): + global_min=[] + global_max=[] + average_file=open(gnuplot_output_filename+'.average', 'w') + min_file=open(gnuplot_output_filename+'.min', 'w') + max_file=open(gnuplot_output_filename+'.max', 'w') + stddev_file=open(gnuplot_output_filename+'.stddev', 'w') + global_file=open(gnuplot_output_filename+'.global','w') + + min_file.write('DiskName %s\n' % mode) + max_file.write('DiskName %s\n'% mode) + average_file.write('DiskName %s\n'% mode) + stddev_file.write('DiskName %s\n'% mode ) + for disk in xrange(len(fio_data_file)): +# print disk_perf[disk] + min_file.write("# Disk%d was coming from %s\n" % (disk,fio_data_file[disk])) + max_file.write("# Disk%d was coming from %s\n" % (disk,fio_data_file[disk])) + average_file.write("# Disk%d was coming from %s\n" % (disk,fio_data_file[disk])) + stddev_file.write("# Disk%d was coming from %s\n" % (disk,fio_data_file[disk])) + avg = average(disk_perf[disk]) + variance = map(lambda x: (x - avg)**2, disk_perf[disk]) + standard_deviation = math.sqrt(average(variance)) +# print "Disk%d [ min=%.2f max=%.2f avg=%.2f stddev=%.2f \n" % (disk,min(disk_perf[disk]),max(disk_perf[disk]),avg, standard_deviation) + average_file.write('%d %d\n' % (disk, avg)) + stddev_file.write('%d %d\n' % (disk, standard_deviation)) + local_min=min(disk_perf[disk]) + local_max=max(disk_perf[disk]) + min_file.write('%d %d\n' % (disk, local_min)) + max_file.write('%d %d\n' % (disk, local_max)) + global_min.append(int(local_min)) + global_max.append(int(local_max)) + + global_disk_perf = sum(disk_perf, []) + avg = average(global_disk_perf) + variance = map(lambda x: (x - avg)**2, global_disk_perf) + standard_deviation = math.sqrt(average(variance)) + + global_file.write('min=%.2f\n' % min(global_disk_perf)) + global_file.write('max=%.2f\n' % max(global_disk_perf)) + global_file.write('avg=%.2f\n' % avg) + global_file.write('stddev=%.2f\n' % standard_deviation) + global_file.write('values_count=%d\n' % len(global_disk_perf)) + global_file.write('disks_count=%d\n' % len(fio_data_file)) + #print "Global [ min=%.2f max=%.2f avg=%.2f stddev=%.2f \n" % (min(global_disk_perf),max(global_disk_perf),avg, standard_deviation) + + average_file.close() + min_file.close() + max_file.close() + stddev_file.close() + global_file.close() + try: + os.remove('mymath') + except: + True + + generate_gnuplot_math_script("Average values of "+title,gnuplot_output_filename+'.average',mode,int(avg)) + generate_gnuplot_math_script("Min values of "+title,gnuplot_output_filename+'.min',mode,average(global_min)) + generate_gnuplot_math_script("Max values of "+title,gnuplot_output_filename+'.max',mode,average(global_max)) + generate_gnuplot_math_script("Standard Deviation of "+title,gnuplot_output_filename+'.stddev',mode,int(standard_deviation)) + +def parse_global_files(fio_data_file, global_search): + max_result=0 + max_file='' + for file in fio_data_file: + f=open(file) + disk_count=0 + search_value=-1 + + # Let's read the complete file + while True: + try: + # We do split the name from the value + name,value=f.readline().split("=") + except: + f.close() + break + # If we ended the file + if not name: + # Let's process what we have + f.close() + break + else: + # disks_count is not global_search item + # As we need it for some computation, let's save it + if name=="disks_count": + disks_count=int(value) + + # Let's catch the searched item + if global_search in name: + search_value=float(value) + + # Let's process the avg value by estimated the global bandwidth per file + # We keep the biggest in memory for reporting + if global_search == "avg": + if (disks_count > 0) and (search_value != -1): + result=disks_count*search_value + if (result > max_result): + max_result=result + max_file=file + # Let's print the avg output + if global_search == "avg": + print "Biggest aggregated value of %s was %2.f in file %s\n" % (global_search, max_result, max_file) + else: + print "Global search %s is not yet implemented\n" % global_search + +def render_gnuplot(): + print "Running gnuplot Rendering\n" + try: + os.system("gnuplot mymath") + os.system("gnuplot mygraph") + except: + print "Could not run gnuplot on mymath or mygraph !\n" + sys.exit(1); + +def print_help(): + print 'fio2gnuplot.py -ghbio -t <title> -o <outputfile> -p <pattern>' + print + print '-h --help : Print this help' + print '-p <pattern> or --pattern <pattern> : A pattern in regexp to select fio input files' + print '-b or --bandwidth : A predefined pattern for selecting *_bw.log files' + print '-i or --iops : A predefined pattern for selecting *_iops.log files' + print '-g or --gnuplot : Render gnuplot traces before exiting' + print '-o or --outputfile <file> : The basename for gnuplot traces' + print ' - Basename is set with the pattern if defined' + print '-t or --title <title> : The title of the gnuplot traces' + print ' - Title is set with the block size detected in fio traces' + print '-G or --Global <type> : Search for <type> in .global files match by a pattern' + print ' - Available types are : min, max, avg, stddev' + print ' - The .global extension is added automatically to the pattern' + +def main(argv): + mode='unknown' + pattern='' + pattern_set_by_user=False + title='No title' + gnuplot_output_filename='result' + disk_perf=[] + run_gnuplot=False + parse_global=False + global_search='' + + try: + opts, args = getopt.getopt(argv[1:],"ghbio:t:p:G:") + except getopt.GetoptError: + print_help() + sys.exit(2) + + for opt, arg in opts: + if opt in ("-b", "--bandwidth"): + pattern='*_bw.log' + elif opt in ("-i", "--iops"): + pattern='*_iops.log' + elif opt in ("-p", "--pattern"): + pattern_set_by_user=True + pattern=arg + pattern=pattern.replace('\\','') + elif opt in ("-o", "--outputfile"): + gnuplot_output_filename=arg + elif opt in ("-t", "--title"): + title=arg + elif opt in ("-g", "--gnuplot"): + run_gnuplot=True + elif opt in ("-G", "--Global"): + parse_global=True + global_search=arg + elif opt in ("-h", "--help"): + print_help() + sys.exit(1) + + # Adding .global extension to the file + if parse_global==True: + if not gnuplot_output_filename.endswith('.global'): + pattern = pattern+'.global' + + fio_data_file=find_file('.',pattern) + if len(fio_data_file) == 0: + print "No log file found with pattern %s!" % pattern + sys.exit(1) + + fio_data_file=sorted(fio_data_file, key=str.lower) + for file in fio_data_file: + print 'Selected %s' % file + if "_bw.log" in file : + mode="Bandwidth (KB/sec)" + if "_iops.log" in file : + mode="IO per Seconds (IO/sec)" + if (title == 'No title') and (mode != 'unknown'): + if "Bandwidth" in mode: + title='Bandwidth benchmark with %d fio results' % len(fio_data_file) + if "IO" in mode: + title='IO benchmark with %d fio results' % len(fio_data_file) + + #We need to adjust the output filename regarding the pattern required by the user + if (pattern_set_by_user == True): + gnuplot_output_filename=pattern + # As we do have some regexp in the pattern, let's make this simpliest + # We do remove the simpliest parts of the expression to get a clear file name + gnuplot_output_filename=gnuplot_output_filename.replace('-*-','-') + gnuplot_output_filename=gnuplot_output_filename.replace('*','-') + gnuplot_output_filename=gnuplot_output_filename.replace('--','-') + gnuplot_output_filename=gnuplot_output_filename.replace('.log','') + # Insure that we don't have any starting or trailing dash to the filename + gnuplot_output_filename = gnuplot_output_filename[:-1] if gnuplot_output_filename.endswith('-') else gnuplot_output_filename + gnuplot_output_filename = gnuplot_output_filename[1:] if gnuplot_output_filename.startswith('-') else gnuplot_output_filename + + if parse_global==True: + parse_global_files(fio_data_file, global_search) + else: + blk_size=compute_temp_file(fio_data_file,disk_perf) + title="%s @ Blocksize = %dK" % (title,blk_size/1024) + compute_aggregated_file(fio_data_file, gnuplot_output_filename) + compute_math(fio_data_file,title,gnuplot_output_filename,mode,disk_perf) + generate_gnuplot_script(fio_data_file,title,gnuplot_output_filename,mode,disk_perf) + + if (run_gnuplot==True): + render_gnuplot() + + # Cleaning temporary files + try: + os.remove('gnuplot_temp_file.*') + except: + True + +#Main +if __name__ == "__main__": + sys.exit(main(sys.argv)) diff --git a/tools/plot/graph2D.gpm b/tools/plot/graph2D.gpm new file mode 100644 index 0000000..2d0d30a --- /dev/null +++ b/tools/plot/graph2D.gpm @@ -0,0 +1,34 @@ +# This Gnuplot file has been generated by eNovance + +set title '$0' + +set terminal png size 1280,1024 +set output '$3.png' +#set terminal x11 + +#Preparing Axes +#set logscale x +set ytics axis out +#set data style lines +set key top left reverse +set xlabel "Time (Seconds)" +set ylabel '$4' +set xrange [0:] +set yrange [0:] + +#Set Color style +#set palette rgbformulae 22,9,23 +#set palette rgbformulae 7,5,15 +set style line 100 lt 7 lw 0.5 +set style line 1 lt 1 lw 3 pt 3 linecolor rgb "green" + +plot '$1' using 2:3 with linespoints title '$2', $7 w l ls 1 ti 'Global average value' + +set output '$5.png' +plot '$1' using 2:3 smooth csplines title '$2', $7 w l ls 1 ti 'Global average value' + +set output '$6.png' +plot '$1' using 2:3 smooth bezier title '$2', $7 w l ls 1 ti 'Global average value' + +#pause -1 +#The End diff --git a/tools/plot/graph3D.gpm b/tools/plot/graph3D.gpm new file mode 100644 index 0000000..93f7a4d --- /dev/null +++ b/tools/plot/graph3D.gpm @@ -0,0 +1,80 @@ +# This Gnuplot file has been generated by eNovance + +set title '$0' + +set terminal png size 1280,1024 +set output '$3.png' +#set terminal x11 +#3D Config +set isosamples 30 +set hidden3d +set pm3d at s solid hidden3d 100 scansbackward +set pm3d depthorder + +#Preparing Axes +#set logscale x +set ytics axis out 0,1 +#set data style lines +set grid back +set key top left reverse +set ylabel "Disk" +set xlabel "Time (Seconds)" +set zlabel '$4' +set cbrange [0:] +set zrange [0:] + +#Set Color style +#set palette rgbformulae 22,9,23 +set palette rgbformulae 7,5,15 +set style line 100 lt 7 lw 0.5 + +#Multiploting +set multiplot + +#Top Left View +set size 0.5,0.5 +set view 64,216 +set origin 0,0.5 +splot '$1' using 2:1:3 with linespoints title '$2' + +#Top Right View +set size 0.5,0.5 +set origin 0.5,0.5 +set view 90,0 +set pm3d at s solid hidden3d 100 scansbackward +set pm3d depthorder +splot '$1' using 2:1:3 with linespoints title '$2' + +#Bottom Right View +set size 0.5,0.5 +set origin 0.5,0 +set view 63,161 +set pm3d at s solid hidden3d 100 scansbackward +set pm3d depthorder +splot '$1' using 2:1:3 with linespoints title '$2' + +#Bottom Left View +set size 0.5,0.5 +set origin 0,0 +set pm3d map +splot '$1' using 2:1:3 with linespoints title '$2' + +#Unsetting multiplotting +unset multiplot +#pause -1 + +#Preparing 3D Interactive view +set mouse +set terminal png size 1024,768 +set output '$3-3D.png' + +#set term x11 +set view 64,216 +set origin 0,0 +set size 1,1 +set pm3d at bs solid hidden3d 100 scansbackward +set pm3d depthorder +splot '$1' using 2:1:3 with linespoints title '$2' + +#pause -1 +#The End diff --git a/tools/plot/math.gpm b/tools/plot/math.gpm new file mode 100644 index 0000000..81e03da --- /dev/null +++ b/tools/plot/math.gpm @@ -0,0 +1,25 @@ +# This Gnuplot file has been generated by eNovance + +set title '$0' + +set terminal png size 1280,1024 +set output '$3.png' + +set palette rgbformulae 7,5,15 +set style line 100 lt 7 lw 0.5 +set style fill transparent solid 0.9 noborder +set auto x +set ylabel '$4' +set xlabel "Disk" +set yrange [0:] +set style data histogram +set style histogram cluster gap 1 +set style fill solid border -1 +set boxwidth 2 +#set xtic rotate by -10 scale 10 font ",8" +set bmargin 3 +set xtics axis out +set xtic rotate by 45 scale 0 font ",8" autojustify +set xtics offset 0,-1 border -5,1,5 +set style line 1 lt 1 lw 3 pt 3 linecolor rgb "green" +plot '$1' using 2:xtic(1) ti col, $5 w l ls 1 ti 'Global average value' diff --git a/tools/plot/samples/Makefile b/tools/plot/samples/Makefile new file mode 100644 index 0000000..df0480f --- /dev/null +++ b/tools/plot/samples/Makefile @@ -0,0 +1,19 @@ +all: clean m2sw1-128k-sdb-randwrite-para.results_bw.log io bandwidth + +m2sw1-128k-sdb-randwrite-para.results_bw.log: + tar -xf fio-logs.tar.gz + +io: setup + ./fio2gnuplot.py -p 'm2sw1-128k-*-read-para*iops.log' -g + +bandwidth: setup + ./fio2gnuplot.py -p 'm2sw1-128k-*-read-para*bw.log' -g + +setup: + ln -sf ../*py ../*gpm . + +clean: + rm -rf *png mygraph mymath *py *gpm gnuplot_temp_file* *~ + rm -rf *.average *.stddev *.min *.max *.global + rm -rf m2sw1-128k-read-para-bw m2sw1-128k-read-para-iops + rm -rf *log diff --git a/tools/plot/samples/fio-logs.tar.gz b/tools/plot/samples/fio-logs.tar.gz new file mode 100644 index 0000000..2237f5e Binary files /dev/null and b/tools/plot/samples/fio-logs.tar.gz differ -- To unsubscribe from this list: send the line "unsubscribe fio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html