From: Erwan Velu <erwan@enovance.com>
To: "fio@vger.kernel.org" <fio@vger.kernel.org>
Subject: Re: [Pull Request] Updating tools
Date: Wed, 31 Jul 2013 12:36:14 +0200 [thread overview]
Message-ID: <51F8E89E.4060208@enovance.com> (raw)
In-Reply-To: <51F7ACC3.2000904@enovance.com>
[-- Attachment #1: Type: text/plain, Size: 18511 bytes --]
Dear Jens,
I've been updating my branch to add a new feature and some visual
improvements.
The main feature is if more than one file is matching the pattern, a new
set of graphing is generated allowing traces comparaisons on the same
graph as does fio_generate_plots
I've been adding sample files in the three moods (raw/smooth/trend) as
an attachement.
That's a good addition to the existing plotting I did with fio2gnuplot.
Cheers,
Erwan
The following changes since commit bf974737b15bad8d740f10503e9eab6e0b420aa2:
Update sample atomic write job file (2013-07-26 13:11:52 -0600)
are available in the git repository at:
git@github.com:enovance/fio.git erwan/outputdir
for you to fetch changes up to 428b4f6ba681dbb40c8e2213d0c6ae8f8049dcd5:
fio2gnuplot: Adding filename as title for 2D graphs (2013-07-31
12:32:40 +0200)
----------------------------------------------------------------
Erwan Velu (10):
fio2gnuplot: Option to select gnuplot's output dir
Makefile: Installing fio2gnuplot & sons
Makefile: Installing genfio at install time
Tree: Moving fio_generate_plots in tools/
fio2gnuplot: Using default install dir for gpm files
fio2gnuplot: Printing number of selected files
fio2gnuplot: Adding comparing 2D graphs
fio2gnuplot: Fixing help message
fio2gnuplot: Adding information steps
fio2gnuplot: Adding filename as title for 2D graphs
Makefile | 8 ++++--
fio_generate_plots => tools/fio_generate_plots | 0
fio_generate_plots.1 => tools/fio_generate_plots.1 | 0
tools/plot/fio2gnuplot.py | 159
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
4 files changed, 129 insertions(+), 38 deletions(-)
rename fio_generate_plots => tools/fio_generate_plots (100%)
rename fio_generate_plots.1 => tools/fio_generate_plots.1 (100%)
diff --git a/Makefile b/Makefile
index 3de9735..8494b27 100644
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,7 @@ OPTFLAGS= -O3 -g -ffast-math
CFLAGS = -std=gnu99 -Wwrite-strings -Wall
-Wdeclaration-after-statement $(OPTFLAGS) $(EXTFLAGS) $(BUILD_CFLAGS)
LIBS += -lm $(EXTLIBS)
PROGS = fio
-SCRIPTS = fio_generate_plots
+SCRIPTS = tools/fio_generate_plots tools/plot/fio2gnuplot.py tools/genfio
ifdef CONFIG_GFIO
PROGS += gfio
@@ -189,8 +189,10 @@ bindir = $(prefix)/bin
ifeq ($(CONFIG_TARGET_OS), Darwin)
mandir = /usr/share/man
+sharedir = /usr/share/fio
else
mandir = $(prefix)/man
+sharedir = $(prefix)/share/fio
endif
all: $(PROGS) $(SCRIPTS) FORCE
@@ -278,4 +280,6 @@ install: $(PROGS) $(SCRIPTS) FORCE
$(INSTALL) $(PROGS) $(SCRIPTS) $(DESTDIR)$(bindir)
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
$(INSTALL) -m 644 fio.1 $(DESTDIR)$(mandir)/man1
- $(INSTALL) -m 644 fio_generate_plots.1 $(DESTDIR)$(mandir)/man1
+ $(INSTALL) -m 644 tools/fio_generate_plots.1 $(DESTDIR)$(mandir)/man1
+ $(INSTALL) -m 755 -d $(DESTDIR)$(sharedir)
+ $(INSTALL) -m 644 tools/plot/*gpm $(DESTDIR)$(sharedir)/
diff --git a/fio_generate_plots b/tools/fio_generate_plots
similarity index 100%
rename from fio_generate_plots
rename to tools/fio_generate_plots
diff --git a/fio_generate_plots.1 b/tools/fio_generate_plots.1
similarity index 100%
rename from fio_generate_plots.1
rename to tools/fio_generate_plots.1
diff --git a/tools/plot/fio2gnuplot.py b/tools/plot/fio2gnuplot.py
index 03ef0dd..800c334 100755
--- a/tools/plot/fio2gnuplot.py
+++ b/tools/plot/fio2gnuplot.py
@@ -25,6 +25,7 @@ import sys
import getopt
import re
import math
+import shutil
def find_file(path, pattern):
fio_data_file=[]
@@ -37,40 +38,95 @@ def find_file(path, pattern):
return fio_data_file
-def
generate_gnuplot_script(fio_data_file,title,gnuplot_output_filename,mode,disk_perf):
- f=open("mygraph",'w')
+def
generate_gnuplot_script(fio_data_file,title,gnuplot_output_filename,gnuplot_output_dir,mode,disk_perf,gpm_dir):
+ print "Generating rendering scripts"
+ filename=gnuplot_output_dir+'mygraph'
+ f=open(filename,'w')
+
+ # Plotting 3D or comparing graphs doesn't have a meaning unless if
there is at least 2 traces
if len(fio_data_file) > 1:
- f.write("call \'graph3D.gpm\' \'%s' \'%s\' \'\' \'%s\'
\'%s\'\n" % (title,gnuplot_output_filename,gnuplot_output_filename,mode))
+ f.write("call \'%s/graph3D.gpm\' \'%s' \'%s\' \'\' \'%s\'
\'%s\'\n" %
(gpm_dir,title,gnuplot_output_filename,gnuplot_output_filename,mode))
+
+ # Setting up the compare files that will be plot later
+ compare=open(gnuplot_output_dir + 'compare.gnuplot','w')
+ compare.write('''
+set title '%s'
+set terminal png size 1280,1024
+set ytics axis out auto
+set key top left reverse
+set xlabel "Time (Seconds)"
+set ylabel '%s'
+set xrange [0:]
+set yrange [0:]
+'''% (title,mode))
+ compare.close()
+ #Copying the common file for all kind of graph (raw/smooth/trend)
+ compare_raw_filename="compare-%s-2Draw" % (gnuplot_output_filename)
+ compare_smooth_filename="compare-%s-2Dsmooth" %
(gnuplot_output_filename)
+ compare_trend_filename="compare-%s-2Dtrend" %
(gnuplot_output_filename)
+
shutil.copy(gnuplot_output_dir+'compare.gnuplot',gnuplot_output_dir+compare_raw_filename+".gnuplot")
+
shutil.copy(gnuplot_output_dir+'compare.gnuplot',gnuplot_output_dir+compare_smooth_filename+".gnuplot")
+
shutil.copy(gnuplot_output_dir+'compare.gnuplot',gnuplot_output_dir+compare_trend_filename+".gnuplot")
+
+ #Setting up a different output filename for each kind of graph
+ compare_raw=open(gnuplot_output_dir+compare_raw_filename +
".gnuplot",'a')
+ compare_raw.write("set output '%s.png'\n" % compare_raw_filename)
+
compare_smooth=open(gnuplot_output_dir+compare_smooth_filename+".gnuplot",'a')
+ compare_smooth.write("set output '%s.png'\n" %
compare_smooth_filename)
+
compare_trend=open(gnuplot_output_dir+compare_trend_filename+".gnuplot",'a')
+ compare_trend.write("set output '%s.png'\n" %
compare_trend_filename)
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','')
+
+ # Plotting comparing graphs doesn't have a meaning unless if
there is at least 2 traces
+ if len(fio_data_file) > 1:
+ # Adding the plot instruction for each kind of comparing graphs
+ if pos ==0 :
+ compare_raw.write("plot '%s' using 2:3 with linespoints
title '%s'" % (tmp_filename,fio_data_file[pos]))
+ compare_smooth.write("plot '%s' using 2:3 smooth
csplines title '%s'" % (tmp_filename,fio_data_file[pos]))
+ compare_trend.write("plot '%s' using 2:3 smooth bezier
title '%s'" % (tmp_filename,fio_data_file[pos]))
+ else:
+ compare_raw.write(",\\\n'%s' using 2:3 with linespoints
title '%s'" % (tmp_filename,fio_data_file[pos]))
+ compare_smooth.write(",\\\n'%s' using 2:3 smooth
csplines title '%s'" % (tmp_filename,fio_data_file[pos]))
+ compare_trend.write(",\\\n'%s' using 2:3 smooth bezier
title '%s'" % (tmp_filename,fio_data_file[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))
+ f.write("call \'%s/graph2D.gpm\' \'%s' \'%s\' \'%s\'
\'%s\' \'%s\' \'%s\' \'%s\' \'%f\'\n" %
(gpm_dir,title,tmp_filename,fio_data_file[pos],raw_filename,mode,smooth_filename,trend_filename,avg))
pos = pos +1
+ # Plotting comparing graphs doesn't have a meaning unless if there
is at least 2 traces
+ if len(fio_data_file) > 1:
+ os.remove(gnuplot_output_dir+"compare.gnuplot")
+ compare_raw.close()
+ compare_smooth.close()
+ compare_trend.close()
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))
+def
generate_gnuplot_math_script(title,gnuplot_output_filename,mode,average,gnuplot_output_dir,gpm_dir):
+ filename=gnuplot_output_dir+'mymath';
+ f=open(filename,'a')
+ f.write("call \'%s/math.gpm\' \'%s' \'%s\' \'\' \'%s\' \'%s\'
%s\n" %
(gpm_dir,title,gnuplot_output_filename,gnuplot_output_filename,mode,average))
f.close()
-def compute_aggregated_file(fio_data_file, gnuplot_output_filename):
+def compute_aggregated_file(fio_data_file, gnuplot_output_filename,
gnuplot_output_dir):
+ print "Processing data file 2/2"
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
+ tmp_filename = "%sgnuplot_temp_file.%d" % (gnuplot_output_dir, pos)
temp_files.append(open(tmp_filename,'r'))
pos = pos +1
- f = open(gnuplot_output_filename, "w")
+ f = open(gnuplot_output_dir+gnuplot_output_filename, "w")
index=0
# Let's add some information
for tempfile in temp_files:
@@ -83,14 +139,15 @@ def compute_aggregated_file(fio_data_file,
gnuplot_output_filename):
def average(s): return sum(s) * 1.0 / len(s)
-def compute_temp_file(fio_data_file,disk_perf):
+def compute_temp_file(fio_data_file,disk_perf,gnuplot_output_dir):
+ print "Processing data file 1/2"
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
+ tmp_filename = "%sgnuplot_temp_file.%d" % (gnuplot_output_dir,pos)
gnuplot_file=open(tmp_filename,'w')
temp_outfile.append(gnuplot_file)
gnuplot_file.write("#Temporary file based on file %s\n" % file)
@@ -144,14 +201,15 @@ def compute_temp_file(fio_data_file,disk_perf):
file.close()
return blk_size
-def compute_math(fio_data_file,
title,gnuplot_output_filename,mode,disk_perf):
+def compute_math(fio_data_file,
title,gnuplot_output_filename,gnuplot_output_dir,mode,disk_perf,gpm_dir):
+ print "Computing Maths"
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')
+
average_file=open(gnuplot_output_dir+gnuplot_output_filename+'.average',
'w')
+ min_file=open(gnuplot_output_dir+gnuplot_output_filename+'.min', 'w')
+ max_file=open(gnuplot_output_dir+gnuplot_output_filename+'.max', 'w')
+ stddev_file=open(gnuplot_output_dir+gnuplot_output_filename+'.stddev',
'w')
+ global_file=open(gnuplot_output_dir+gnuplot_output_filename+'.global','w')
min_file.write('DiskName %s\n' % mode)
max_file.write('DiskName %s\n'% mode)
@@ -195,14 +253,14 @@ def compute_math(fio_data_file,
title,gnuplot_output_filename,mode,disk_perf):
stddev_file.close()
global_file.close()
try:
- os.remove('mymath')
+ os.remove(gnuplot_output_dir+'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))
+ generate_gnuplot_math_script("Average values of
"+title,gnuplot_output_filename+'.average',mode,int(avg),gnuplot_output_dir,gpm_dir)
+ generate_gnuplot_math_script("Min values of
"+title,gnuplot_output_filename+'.min',mode,average(global_min),gnuplot_output_dir,gpm_dir)
+ generate_gnuplot_math_script("Max values of
"+title,gnuplot_output_filename+'.max',mode,average(global_max),gnuplot_output_dir,gpm_dir)
+ generate_gnuplot_math_script("Standard Deviation of
"+title,gnuplot_output_filename+'.stddev',mode,int(standard_deviation),gnuplot_output_dir,gpm_dir)
def parse_global_files(fio_data_file, global_search):
max_result=0
@@ -249,17 +307,28 @@ def parse_global_files(fio_data_file, global_search):
else:
print "Global search %s is not yet implemented\n" % global_search
-def render_gnuplot():
- print "Running gnuplot Rendering\n"
+def render_gnuplot(fio_data_file, gnuplot_output_dir):
+ print "Running gnuplot Rendering"
try:
- os.system("gnuplot mymath")
- os.system("gnuplot mygraph")
+ # Let's render all the compared files if some
+ if len(fio_data_file) > 1:
+ print " |-> Rendering comparing traces"
+ os.system("cd %s; for i in *.gnuplot; do gnuplot $i; done"
% gnuplot_output_dir)
+ print " |-> Rendering math traces"
+ os.system("cd %s; gnuplot mymath" % gnuplot_output_dir)
+ print " |-> Rendering 2D & 3D traces"
+ os.system("cd %s; gnuplot mygraph" % gnuplot_output_dir)
+
+ name_of_directory="the current"
+ if gnuplot_output_dir != "./":
+ name_of_directory=gnuplot_output_dir
+ print "\nRendering traces are available in %s directory" %
name_of_directory
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 'fio2gnuplot.py -ghbiod -t <title> -o <outputfile> -p
<pattern> -G <type>'
print
print '-h --help : Print this help'
print '-p <pattern> or --pattern <pattern> : A pattern in regexp
to select fio input files'
@@ -268,6 +337,7 @@ def print_help():
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 '-d or --outputdir <dir> : The directory where
gnuplot shall render files'
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'
@@ -280,13 +350,21 @@ def main(argv):
pattern_set_by_user=False
title='No title'
gnuplot_output_filename='result'
+ gnuplot_output_dir='./'
+ gpm_dir="/usr/share/fio/"
disk_perf=[]
run_gnuplot=False
parse_global=False
global_search=''
+ if not os.path.isfile(gpm_dir+'math.gpm'):
+ gpm_dir="/usr/local/share/fio/"
+ if not os.path.isfile(gpm_dir+'math.gpm'):
+ print "Looks like fio didn't got installed properly as no
gpm files found in '/usr/share/fio' or '/usr/local/share/fio'\n"
+ sys.exit(3)
+
try:
- opts, args = getopt.getopt(argv[1:],"ghbio:t:p:G:")
+ opts, args = getopt.getopt(argv[1:],"ghbio:d:t:p:G:")
except getopt.GetoptError:
print_help()
sys.exit(2)
@@ -302,6 +380,12 @@ def main(argv):
pattern=pattern.replace('\\','')
elif opt in ("-o", "--outputfile"):
gnuplot_output_filename=arg
+ elif opt in ("-d", "--outputdir"):
+ gnuplot_output_dir=arg
+ if not gnuplot_output_dir.endswith('/'):
+ gnuplot_output_dir=gnuplot_output_dir+'/'
+ if not os.path.exists(gnuplot_output_dir):
+ os.makedirs(gnuplot_output_dir)
elif opt in ("-t", "--title"):
title=arg
elif opt in ("-g", "--gnuplot"):
@@ -322,10 +406,12 @@ def main(argv):
if len(fio_data_file) == 0:
print "No log file found with pattern %s!" % pattern
sys.exit(1)
+ else:
+ print "%d files Selected with pattern '%s'" %
(len(fio_data_file), pattern)
fio_data_file=sorted(fio_data_file, key=str.lower)
for file in fio_data_file:
- print 'Selected %s' % file
+ print ' |-> %s' % file
if "_bw.log" in file :
mode="Bandwidth (KB/sec)"
if "_iops.log" in file :
@@ -336,6 +422,7 @@ def main(argv):
if "IO" in mode:
title='IO benchmark with %d fio results' % len(fio_data_file)
+ print
#We need to adjust the output filename regarding the pattern
required by the user
if (pattern_set_by_user == True):
gnuplot_output_filename=pattern
@@ -352,14 +439,14 @@ def main(argv):
if parse_global==True:
parse_global_files(fio_data_file, global_search)
else:
- blk_size=compute_temp_file(fio_data_file,disk_perf)
+ blk_size=compute_temp_file(fio_data_file,disk_perf,gnuplot_output_dir)
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)
+ compute_aggregated_file(fio_data_file, gnuplot_output_filename,
gnuplot_output_dir)
+
compute_math(fio_data_file,title,gnuplot_output_filename,gnuplot_output_dir,mode,disk_perf,gpm_dir)
+
generate_gnuplot_script(fio_data_file,title,gnuplot_output_filename,gnuplot_output_dir,mode,disk_perf,gpm_dir)
if (run_gnuplot==True):
- render_gnuplot()
+ render_gnuplot(fio_data_file, gnuplot_output_dir)
# Cleaning temporary files
try:
[-- Attachment #2: compare-vm1-1-4m-vdb-read-para.results_-_bw-2Dsmooth.png --]
[-- Type: image/png, Size: 11792 bytes --]
[-- Attachment #3: compare-vm1-1-4m-vdb-read-para.results_-_bw-2Draw.png --]
[-- Type: image/png, Size: 22335 bytes --]
[-- Attachment #4: compare-vm1-1-4m-vdb-read-para.results_-_bw-2Dtrend.png --]
[-- Type: image/png, Size: 8676 bytes --]
next prev parent reply other threads:[~2013-07-31 10:36 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-30 12:08 [Pull Request] Updating tools Erwan Velu
2013-07-31 10:36 ` Erwan Velu [this message]
2013-07-31 18:35 ` Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=51F8E89E.4060208@enovance.com \
--to=erwan@enovance.com \
--cc=fio@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.