Whamcloud - gitweb
LU-3478 iokit: fix sgpdd-survey scripts (output and plotting)
[fs/lustre-release.git] / lustre-iokit / sgpdd-survey / plot-sgpdd
index 274ab31..e3386ec 100755 (executable)
 #!/usr/bin/perl -w
-# Report generation for plot-sgpdd.pl
-# ===================================
-#        The plot-sgpdd.pl script is used to generate csv file and
-# instructions files for gnuplot from the output of sgpdd-survey.pl script.
+# Report generation for plot-sgpdd
+# ================================
+#        The plot-sgpdd script is used to generate csv file and
+# instructions files for gnuplot from the output of sgpdd-survey script.
 #
-#        The plot-sgpdd.pl also creates .scr file that contains instructions
+#        The plot-sgpdd 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:
-# $ plot-sgpdd.pl <log_filename>
+# $ sgpdd-survey > log_filename
+# $ plot-sgpdd <log_filename>
 # [Note: 1. This script may need modifications whenever there will be
-#           modifications in output format of sgpdd-survey.pl script.
+#           modifications in output format of sgpdd-survey script.
 #        2. Gnuplot version 4.0 or above is required.]
 
-# arg 0 is filename
-sub usages_msg() {
-       print "Usage: $0 <log_filename> \n";
-       print "       The $0 parses and plots graph for output of sgpdd-survey.pl using gnuplot,\n";
-       print "       it generates .dat and .scr files for results graphing\n";
-       print "e.g.> perl $0 sgpdd-log \n";
+sub usage() 
+{
+       print STDERR "Usage: $0 [options] <log_filename>\n";
+       print STDERR "  $0 parses and plots graphs from the output of sgpdd-survey\n";
+       print STDERR "  It generates text data files (.dat) and graphs (.png) using gnuplot.\n";
+       print STDERR "options:\n";
+       print STDERR "  --rt: Subtitle for read graphs\n";
+       print STDERR "  --wt: Subtitle for write graphs\n";
+       print STDERR "  --y: Y-axis scale\n";
+       print STDERR "e.g. # $0 --rt=\"no prefetch\" --wt=\"WB disabled\" --y=500 sgpdd.summary\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";
+
+# check whether gnuplot supports png
+$pngsupport = "ldd `which gnuplot` | grep -q libpng";
+system ("$pngsupport") == 0 or die "gnuplot installed does not support png.
+       Please install gnuplot to support png and try again.\n"; 
+
 my @GraphTitle;
+
+#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 ($opt_rdtitle || $opt_wrtitle) {
+               if ($op eq "rd") {
+                       print SCRFILE "set title \"@GraphTitle\\n$rwlabel, " .
+                                     "Rsize = $rsz, $lun LUNs, $opt_rdtitle\"\n";
+               }
+               if ($op eq "wr") {
+                       print SCRFILE "set title \"@GraphTitle\\n$rwlabel, " .
+                                     "Rsize = $rsz, $lun LUNs, $opt_wrtitle\"\n";
+               }
+       } else {
+               print SCRFILE "set title \"@GraphTitle\\n$rwlabel, " .
+                             "Rsize = $rsz, $lun LUNs\"\n";
+       }
+       print SCRFILE "set xlabel \"Threads/LUN\"\n";
+       print SCRFILE "set ylabel \"Throughput (MiB/s)\"\n";
+       print SCRFILE "set logscale x\n";
+       print SCRFILE "set grid\n";
+       print SCRFILE "set key right bottom\n";
+        print SCRFILE "set terminal png\n";
+        print SCRFILE "set output \"/dev/null\"\n";
+       if ($opt_y != 0) {
+               print SCRFILE "set yrange [ 0:$opt_y ]\n";
+       } else {
+               print SCRFILE "set yrange [ 0: ]\n";
+       }
+
+       my $plot = "plot";
+       $i = 2;
+       $xrange = 1;
+       # generate instructions for gnuplot, with adjusting X-axes ranges
+       for ($j = $first_crg; $j <= $crg ; $j = $j + $j) {
+               $tmp=$j/$lun;
+               printf SCRFILE "$plot \"$file-$rsz-$op.dat\" " .
+                              "using 1:$i:xticlabels(1) axes x%dy1 " .
+                              "title \"$tmp crg/LUN\" " .
+                              "with linespoints lw 2\n", $xrange;
+               $i++;
+               $plot = "replot";
+       }
+       print SCRFILE "set output \"$file-$rsz-$op.png\"\n";
+       print SCRFILE "replot\n";
+       close SCRFILE;
+       # 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.
+       my $datafile = "$file-$rsz-$op.dat";
+       open ( DATAFILE, "> $datafile" ) or die "Can't open csv $datafile for writing";
+       printf DATAFILE "%-6s", "thrd";
+       for ($j = $first_crg; $j <= $crg ; $j = $j + $j) {
+               $tmp = $j/$lun;
+               printf DATAFILE "%-10s", "$tmp-crg";
+       }
+       for ( $i = $first_thread; $i <= $thread; $i = $i + $i ) {
+               printf DATAFILE "\n%-6s", $i/$lun;
+               for ($j = $first_crg; $j <= $crg ; $j = $j + $j) {
+                       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", "-";
+                               }
+                       }
+               }
+       }
+       close DATAFILE;
+}
+
+#Subroutine to call .scr and .dat file write routines.
+sub write_files() {
+       for ($cnt = 0; $cnt < @operations; $cnt = $cnt + 1) {
+               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");
+               }
+       }
+}
+
 if ( !$ARGV[0] ) {
-       usages_msg();
+       usage();
 }
-$file = $ARGV[0];
-$region = 0;
+$crg = 0;
 $thread = 0;
+$first_crg = 1;
+$first_thread = 1;
 $count = 0;
-open ( PFILE, "$file") or die "Can't open results";
+$rsz = 0;
+$opt_rdtitle = "";
+$opt_wrtitle = "";
+$opt_y = 0;
+$cnt = 0;
+@operations = ();
+# Command line parameter parsing
+use Getopt::Long;
+GetOptions ('help' => \$opt_help, 'rt=s' => \$opt_rdtitle, 'wt=s' => \$opt_wrtitle, 'y=i' => \$opt_y) or usage(); 
+if ($opt_help) {
+       usage();
+}
+$file = $ARGV[0];
+
+open ( PFILE, "$file") or die "Can't open $file";
 LABEL: while ( <PFILE> ) {
        chomp;
+       # replace error strings to ensure same ordering of line fields
+       s/failed/failed . . . . ./g;
        @line = split( /\s+/ );
        if ($count == 0) {
-               @GraphTitle = @line;
+               @GraphTitle = @line[0 .. 6];
                $count++;
                next LABEL;
        }
-       $rindex = 18;
-       if ($line[9]) {
-           if ($line[10] eq "failed") {
-               $rindex = 12;
-           } else {
-               $out{$line[7]}{$line[5]} = $line[9];    
-           }
+       # output format
+       # dev  1 sz  1048576K rsz 1024K crg     1 thr     8 write  604.55 [  606.43,  606.43]  read  754.02 [  756.95,  756.95]
+       $linelen = @line;
+       if ($linelen < 11) {
+               print "invalid file format at line $count\n";
+               exit 1;
        }
-       #print "rg$line[5] th$line[7] w$line[9] r$line[$rindex]\n";
-       if ($line[$rindex]) {
-           if (!($line[$rindex+1] eq "failed")) {
-               if ($line[5] <= 1 ) {
-                       $out{$line[7]}{$line[5] - 1} = $line[$rindex];
-               } else {
-                       $out{$line[7]}{$line[5] + 1} = $line[$rindex];
+       if ($line[10]) {
+               if ($line[10] eq "ENOMEM") {
+                       next LABEL;
                }
-           }
        }
-       if ( $region < $line[7] ) {
-               $region = $line[7];
+       if (!$rsz || $rsz ne $line[5]) {
+               &write_files() unless !$rsz;
+               $cnt = 0;
+               $lun = $line[1];
+               $rsz = $line[5];
+               $first_crg = $line[7];
+               $first_thread = $line[9];
+               for ($i = 10; $i <= $linelen; $i = $i + 5) {
+                       if ($line[$i]) {
+                               $operations[$cnt] = $line[$i];
+                               $cnt++;
+                       }
+               }
        }
-       if ( $thread < $line[5] ) {
-               $thread = $line[5];
+       for ($i = 0; $i < @operations; $i++) {
+               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];
+               }
+       }
+       if ( $crg < $line[7] ) {
+               $crg = $line[7];
+       }
+       if ( $thread < $line[9] ) {
+               $thread = $line[9];
        }
        $count++;
 }
 close PFILE;
-
-print "@GraphTitle\n";
-# Open .csv file for writting required columns from log file.
-open ( DATAFILE, "> $file.dat" ) or die "Can't open csv file for writting";
-printf DATAFILE "%-6s", "0";
-for ($j = 1; $j <= $thread ; $j = $j + $j) {
-       printf DATAFILE "%-8s%-8s", "wr$j", "rd$j";
-}
-for ( $i = 1; $i <= $region; $i = $i + $i ) {
-       printf DATAFILE "\n%-6s", $i;
-       for ($j = 1; $j <= $thread ; $j = $j + $j) {
-               if ( $out{$i}{$j} ) {
-                       printf DATAFILE "%-8s", $out{$i}{$j};
-                   } else {
-                       printf DATAFILE "%-8s", "-";
-                   }
-               if ( $j <= 1 && $out{$i}{$j - 1}) {
-                   printf DATAFILE "%-8s", $out{$i}{$j - 1};
-               } elsif ($out{$i}{$j + 1}) {
-                   printf DATAFILE "%-8s", $out{$i}{$j + 1};
-               } else {
-                   printf DATAFILE "%-8s", "-";
-               }
-       }
-}
-close DATAFILE;
-open ( SCRFILE, "> $file.scr" ) or die "Can't open scr file for writting";
-print SCRFILE "set title \"@GraphTitle\"\n";
-print SCRFILE "set xlabel \"Threads\"\n";
-print SCRFILE "set ylabel \"Speeds(MB/s)\"\n";
-my $plot = "plot";
-$i = 2;
-$xrange = 1;
-# generate instructions for gnuplot, with adjusting X-axes ranges
-for ($j = 1; $j <= $thread ; $j = $j + $j) {
-       if ($j > 15 ) {
-               $xrange = 2;
-       }
-       printf SCRFILE "$plot \"$file.dat\" using 1:$i axes x%dy1 title \"write$j\" with line\n", $xrange;
-       $plot = "replot";
-       $i++;
-       printf SCRFILE "$plot \"$file.dat\" using 1:$i axes x%dy1 title \"read$j\" with line\n", $xrange;
-       $i++;
+if ($count > 1 && $rsz) {
+       &write_files()
+} else {
+       print "Invalid log file format\n";
 }
-print SCRFILE "pause -1\n";
-close SCRFILE;
-system ("gnuplot $file.scr") == 0 or die "ERROR: while ploting graph.\nMake sure that gnuplot is working properly";