Whamcloud - gitweb
*** empty log message ***
[fs/lustre-release.git] / lustre-iokit / obdfilter-survey / plot-obdfilter
diff --git a/lustre-iokit/obdfilter-survey/plot-obdfilter b/lustre-iokit/obdfilter-survey/plot-obdfilter
new file mode 100644 (file)
index 0000000..aaf51b0
--- /dev/null
@@ -0,0 +1,258 @@
+#!/usr/bin/perl -w
+#*  Copyright (C) 2002 Cluster File Systems, Inc.
+#*   Author: Jitendra Pawar <jitendra@clusterfs.com>
+#*
+#*   Lustre is free software; you can redistribute it and/or
+#*   modify it under the terms of version 2 of the GNU General Public
+#*   License as published by the Free Software Foundation.
+#*
+#*   Lustre 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 Lustre; if not, write to the Free Software
+#*   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# Report generation for plot-obdfilter
+# ====================================
+#        The plot-obdfilter script is used to generate csv file and
+# instructions files for gnuplot from the output of obdfilter-survey script.
+#
+#        The plot-obdfilter also creates .scr file that contains instructions
+# for gnuplot to plot the graph. After generating .dat and .scr files this
+# script invokes gnuplot to display graph.
+#
+# Syntax:
+# $ obdfilter-survey > log_filename
+# $ plot-obdfilter <log_filename>
+# [Note: 1. Please use the .summary file generated by obdfilter-survey as log_file.
+#           It is generally available at /tmp/obdfilter_survey_<date_time_system>.summary
+#        2. This script may need modifications whenever there will be
+#           modifications in output format of obdfilter-survey script.
+#        3. Gnuplot version 4.0 or above is required.]
+
+my @GraphTitle;
+sub usage() {
+       print "Usage: $0 <log_filename> [--st=<subtitle>] [--y0=<Y-axis start point>]\n";
+       print "       The $0 parses and plots graphs for output of obdfilter-survey using gnuplot.\n";
+       print "       It generates <log_filename>-<Rsize><rd/wr>.dat and\n";
+       print "       <log_filename>-<Rsize>-<rd/wr/rrd/rwr/rwa>.scr files.\n";
+       print "       Those will be used for graphing the results\n";
+       print "OPTIONS:\n";
+       print " --st: SubTitle for the graph\n";
+       print " --y0: Start point of Y-axis, Default value automatically taken based on Y-axis values ranges\n";
+       print " log_file: use the .summary file generated by obdfilter-survey as log_file.\n";
+       print "           It is generally available at /tmp/obdfilter_survey_<date_time_system>.summary\n";
+       print "e.g.   # $0 obdfilter-log --st=\"Sub-Title\" --y0=50\n";
+       exit 1;
+}
+
+# check whether gnuplot exists?
+system ("which gnuplot > /dev/null") == 0 or die "gnuplot does not exist, please install it and try again.\n";
+
+#Subroutine to write .scr file that further used by gnuplot to plot the graph.
+sub write_scr_file() {
+       my $op = $_[0];
+       my $rwlabel = $_[1];
+       print "generating plot $file-$rsz-$op.png\n";
+       open ( SCRFILE, "> $file-$rsz-$op.scr" ) or die "Can't open scr file for writing";
+       
+       if ($subtitle) {
+               print SCRFILE "set title \"@GraphTitle\\n$rwlabel, Rsize = $rsz KBytes, $subtitle\"\n";
+       } else {
+               print SCRFILE "set title \"@GraphTitle\\n$rwlabel, Rsize = $rsz KBytes\"\n";
+       }
+       print SCRFILE "set xlabel \"Threads\"\n";
+       print SCRFILE "set ylabel \"Speeds(MB/s)\"\n";
+       print SCRFILE "set logscale x\n";
+       print SCRFILE "set grid\n";
+        print SCRFILE "set terminal png\n";
+        print SCRFILE "set output \"/dev/null\"\n";
+       if ($opt_y0 != -9999) {
+               print SCRFILE "set yrange [ $opt_y0: ]\n";
+       } 
+       my $plot = "plot";
+       $i = 2;
+       $xrange = 1;
+       # generate instructions for gnuplot, with adjusting X-axes ranges
+       for ($j = $first_thread; $j <= $thread ; $j = $j + $j) {
+                       printf SCRFILE "$plot \"$file-$rsz-$op.dat\" using 1:$i axes x%dy1 title \"$rwlabel-obj$j\" with line\n", $xrange;
+               $i++;
+               $plot = "replot";
+       }
+       print SCRFILE "set output \"$file-$rsz-$op.png\"\n";
+       print SCRFILE "replot\n";
+       close SCRFILE;
+       $graphgen = 1;
+       # invoke gnuplot to display graph.
+       system ("gnuplot $file-$rsz-$op.scr") == 0 or die "ERROR: while ploting graph";
+       system ("rm $file-$rsz-$op.scr");
+}
+
+#Subroutine to write .dat file that further used by gnuplot to plot the graph.
+sub write_dat_file() {
+       my $op = $_[0];
+       print "writing data $file-$rsz-$op.dat\n";
+       # Open .csv/.dat file for writing required columns from log file.
+       open ( DATAFILE, "> $file-$rsz-$op.dat" ) or die "Can't open csv file for writing";
+       printf DATAFILE "%-6s", "thrd";
+       for ($j = $first_thread; $j <= $thread ; $j = $j + $j) {
+               printf DATAFILE "%-10s", "$op-obj$j";
+       }
+       for ( $i = $first_obj; $i <= $obj; $i = $i + $i ) {
+               printf DATAFILE "\n%-6s", $i;
+               for ($j = $first_thread; $j <= $thread ; $j = $j + $j) {
+               # switch-case can be used instead if else
+                       if ($op eq "rd") {
+                                       if ( $ard{$i}{$j} ) {
+                                               printf DATAFILE "%-10s", $ard{$i}{$j};
+                                       } else {
+                                               printf DATAFILE "%-10s", "-";
+                                       }
+                       } elsif ($op eq "wr" ) {
+                                       if ( $awr{$i}{$j} ) {
+                                               printf DATAFILE "%-10s", $awr{$i}{$j};
+                                       } else {
+                                               printf DATAFILE "%-10s", "-";
+                                       }
+                       } elsif ($op eq "rwr" ) {
+                                       if ( $arwr{$i}{$j} ) {
+                                               printf DATAFILE "%-10s", $arwr{$i}{$j};
+                                       } else {
+                                               printf DATAFILE "%-10s", "-";
+                                       }
+                       } elsif ($op eq "rrd" ) {
+                                       if ( $arrd{$i}{$j} ) {
+                                               printf DATAFILE "%-10s", $arrd{$i}{$j};
+                                       } else {
+                                               printf DATAFILE "%-10s", "-";
+                                       }
+                       } elsif ($op eq "rwa" ) {
+                                       if ( $arwa{$i}{$j} ) {
+                                               printf DATAFILE "%-10s", $arwa{$i}{$j};
+                                       } else {
+                                               printf DATAFILE "%-10s", "-";
+                                       }
+                       } 
+               }
+       }
+       close DATAFILE;
+}
+
+#Subroutine to call .scr and .dat file write routines.
+sub write_files() {
+       for ($cnt = 0; $cnt < @operations; $cnt = $cnt + 1) {
+               # switch-case can be used instead if else
+               if($operations[$cnt] eq "read") {
+                       &write_dat_file("rd");
+                       &write_scr_file("rd", "read");
+               } elsif ($operations[$cnt] eq "write") {
+                       &write_dat_file("wr");
+                       &write_scr_file("wr", "write");
+               } elsif ($operations[$cnt] eq "reread") {
+                       &write_dat_file("rrd");
+                       &write_scr_file("rrd", "reread");
+               } elsif ($operations[$cnt] eq "rewrite") {
+                       &write_dat_file("rwr");
+                       &write_scr_file("rwr", "rewrite");
+               } elsif ($operations[$cnt] eq "rewrite_again") {
+                       &write_dat_file("rwa");
+                       &write_scr_file("rwa", "rewrite_again");
+               }
+       }
+}
+
+if ( !$ARGV[0] ) {
+       usage();
+}
+$file = $ARGV[0];
+$obj = 0;
+$thread = 0;
+$first_obj = 1;
+$first_thread = 1;
+$count = 0;
+$rsz = 0;
+$subtitle = "";
+$opt_y0 = -9999;
+$cnt = 0;
+@operations = ();
+$graphgen = 0;
+# Command line parameter parsing
+use Getopt::Long;
+GetOptions ('help' => \$opt_help, 'st=s' => \$subtitle, 'y0=i' => \$opt_y0) or usage(); 
+if ($opt_help) {
+       usage();
+}
+open ( PFILE, "$file") or die "Can't open results";
+LABEL: while ( <PFILE> ) {
+       chomp;
+       @line = split( /\s+/ );
+       if ($count == 0) {
+               @GraphTitle = @line;
+               $count++;
+               next LABEL;
+       }
+       $linelen = @line;
+       if ($linelen > 26 || $linelen < 11) {
+               print "invalid file format at line $count\n";
+               exit 1; 
+       } 
+       if (!$rsz && $line[5]) {
+               $cnt = 0;
+               $rsz = $line[5];
+               $first_obj = $line[7];
+               $first_thread = $line[9];
+               for ($i = 10; $i <= $linelen; $i = $i + 5) {
+                       if ($line[$i]) {
+                               $operations[$cnt] = $line[$i];
+                               $cnt++;
+                       }               
+               }
+       }
+       if ($rsz != $line[5]) {
+               &write_files();
+               $rsz = $line[5];
+               $first_obj = $line[7];
+               $first_thread = $line[9];
+               @operations = ();                       
+               $cnt = 0;
+               for ($i = 10; $i <= $linelen; $i = $i + 5) {
+                       if ($line[$i]) {
+                               $operations[$cnt] = $line[$i];
+                               $cnt++;
+                       }               
+               }
+               $obj = 0;
+               $thread = 0;
+       }
+       for ($i = 0; $i < @operations; $i++) {
+               # switch-case can be used instead if else
+               if($operations[$i] eq "read") {
+                       $ard{$line[9]}{$line[7]} = $line[$i * 5 + 11];
+               } elsif ($operations[$i] eq "write") {
+                       $awr{$line[9]}{$line[7]} = $line[$i * 5 + 11];
+               } elsif ($operations[$i] eq "reread") {
+                       $arrd{$line[9]}{$line[7]} = $line[$i * 5 + 11];
+               } elsif ($operations[$i] eq "rewrite") {
+                       $arwr{$line[9]}{$line[7]} = $line[$i * 5 + 11];
+               } elsif ($operations[$i] eq "rewrite_again") {
+                       $arwa{$line[9]}{$line[7]} = $line[$i * 5 + 11];
+               }       
+       }
+       if ( $obj < $line[9] ) {
+               $obj = $line[9];
+       }
+       if ( $thread < $line[7] ) {
+               $thread = $line[7];
+       }
+       $count++;
+}
+close PFILE;
+if ($count > 1 && $rsz) {
+       &write_files();
+}
+if (!$graphgen) {
+       print "Invalid log file format\n";
+}