Whamcloud - gitweb
aaf51b095282cfc5d45d7ce7c3d76571e7c5392f
[fs/lustre-release.git] / lustre-iokit / obdfilter-survey / plot-obdfilter
1 #!/usr/bin/perl -w
2 #*  Copyright (C) 2002 Cluster File Systems, Inc.
3 #*   Author: Jitendra Pawar <jitendra@clusterfs.com>
4 #*
5 #*   Lustre is free software; you can redistribute it and/or
6 #*   modify it under the terms of version 2 of the GNU General Public
7 #*   License as published by the Free Software Foundation.
8 #*
9 #*   Lustre is distributed in the hope that it will be useful,
10 #*   but WITHOUT ANY WARRANTY; without even the implied warranty of
11 #*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 #*   GNU General Public License for more details.
13 #*
14 #*   You should have received a copy of the GNU General Public License
15 #*   along with Lustre; if not, write to the Free Software
16 #*   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 #
18 # Report generation for plot-obdfilter
19 # ====================================
20 #        The plot-obdfilter script is used to generate csv file and
21 # instructions files for gnuplot from the output of obdfilter-survey script.
22 #
23 #        The plot-obdfilter also creates .scr file that contains instructions
24 # for gnuplot to plot the graph. After generating .dat and .scr files this
25 # script invokes gnuplot to display graph.
26 #
27 # Syntax:
28 # $ obdfilter-survey > log_filename
29 # $ plot-obdfilter <log_filename>
30 # [Note: 1. Please use the .summary file generated by obdfilter-survey as log_file.
31 #           It is generally available at /tmp/obdfilter_survey_<date_time_system>.summary
32 #        2. This script may need modifications whenever there will be
33 #           modifications in output format of obdfilter-survey script.
34 #        3. Gnuplot version 4.0 or above is required.]
35
36 my @GraphTitle;
37 sub usage() {
38         print "Usage: $0 <log_filename> [--st=<subtitle>] [--y0=<Y-axis start point>]\n";
39         print "       The $0 parses and plots graphs for output of obdfilter-survey using gnuplot.\n";
40         print "       It generates <log_filename>-<Rsize><rd/wr>.dat and\n";
41         print "       <log_filename>-<Rsize>-<rd/wr/rrd/rwr/rwa>.scr files.\n";
42         print "       Those will be used for graphing the results\n";
43         print "OPTIONS:\n";
44         print " --st: SubTitle for the graph\n";
45         print " --y0: Start point of Y-axis, Default value automatically taken based on Y-axis values ranges\n";
46         print " log_file: use the .summary file generated by obdfilter-survey as log_file.\n";
47         print "           It is generally available at /tmp/obdfilter_survey_<date_time_system>.summary\n";
48         print "e.g.   # $0 obdfilter-log --st=\"Sub-Title\" --y0=50\n";
49         exit 1;
50 }
51
52 # check whether gnuplot exists?
53 system ("which gnuplot > /dev/null") == 0 or die "gnuplot does not exist, please install it and try again.\n";
54
55 #Subroutine to write .scr file that further used by gnuplot to plot the graph.
56 sub write_scr_file() {
57         my $op = $_[0];
58         my $rwlabel = $_[1];
59         print "generating plot $file-$rsz-$op.png\n";
60         open ( SCRFILE, "> $file-$rsz-$op.scr" ) or die "Can't open scr file for writing";
61         
62         if ($subtitle) {
63                 print SCRFILE "set title \"@GraphTitle\\n$rwlabel, Rsize = $rsz KBytes, $subtitle\"\n";
64         } else {
65                 print SCRFILE "set title \"@GraphTitle\\n$rwlabel, Rsize = $rsz KBytes\"\n";
66         }
67         print SCRFILE "set xlabel \"Threads\"\n";
68         print SCRFILE "set ylabel \"Speeds(MB/s)\"\n";
69         print SCRFILE "set logscale x\n";
70         print SCRFILE "set grid\n";
71         print SCRFILE "set terminal png\n";
72         print SCRFILE "set output \"/dev/null\"\n";
73         if ($opt_y0 != -9999) {
74                 print SCRFILE "set yrange [ $opt_y0: ]\n";
75         } 
76         my $plot = "plot";
77         $i = 2;
78         $xrange = 1;
79         # generate instructions for gnuplot, with adjusting X-axes ranges
80         for ($j = $first_thread; $j <= $thread ; $j = $j + $j) {
81                         printf SCRFILE "$plot \"$file-$rsz-$op.dat\" using 1:$i axes x%dy1 title \"$rwlabel-obj$j\" with line\n", $xrange;
82                 $i++;
83                 $plot = "replot";
84         }
85         print SCRFILE "set output \"$file-$rsz-$op.png\"\n";
86         print SCRFILE "replot\n";
87         close SCRFILE;
88         $graphgen = 1;
89         # invoke gnuplot to display graph.
90         system ("gnuplot $file-$rsz-$op.scr") == 0 or die "ERROR: while ploting graph";
91         system ("rm $file-$rsz-$op.scr");
92 }
93
94 #Subroutine to write .dat file that further used by gnuplot to plot the graph.
95 sub write_dat_file() {
96         my $op = $_[0];
97         print "writing data $file-$rsz-$op.dat\n";
98         # Open .csv/.dat file for writing required columns from log file.
99         open ( DATAFILE, "> $file-$rsz-$op.dat" ) or die "Can't open csv file for writing";
100         printf DATAFILE "%-6s", "thrd";
101         for ($j = $first_thread; $j <= $thread ; $j = $j + $j) {
102                 printf DATAFILE "%-10s", "$op-obj$j";
103         }
104         for ( $i = $first_obj; $i <= $obj; $i = $i + $i ) {
105                 printf DATAFILE "\n%-6s", $i;
106                 for ($j = $first_thread; $j <= $thread ; $j = $j + $j) {
107                 # switch-case can be used instead if else
108                         if ($op eq "rd") {
109                                         if ( $ard{$i}{$j} ) {
110                                                 printf DATAFILE "%-10s", $ard{$i}{$j};
111                                         } else {
112                                                 printf DATAFILE "%-10s", "-";
113                                         }
114                         } elsif ($op eq "wr" ) {
115                                         if ( $awr{$i}{$j} ) {
116                                                 printf DATAFILE "%-10s", $awr{$i}{$j};
117                                         } else {
118                                                 printf DATAFILE "%-10s", "-";
119                                         }
120                         } elsif ($op eq "rwr" ) {
121                                         if ( $arwr{$i}{$j} ) {
122                                                 printf DATAFILE "%-10s", $arwr{$i}{$j};
123                                         } else {
124                                                 printf DATAFILE "%-10s", "-";
125                                         }
126                         } elsif ($op eq "rrd" ) {
127                                         if ( $arrd{$i}{$j} ) {
128                                                 printf DATAFILE "%-10s", $arrd{$i}{$j};
129                                         } else {
130                                                 printf DATAFILE "%-10s", "-";
131                                         }
132                         } elsif ($op eq "rwa" ) {
133                                         if ( $arwa{$i}{$j} ) {
134                                                 printf DATAFILE "%-10s", $arwa{$i}{$j};
135                                         } else {
136                                                 printf DATAFILE "%-10s", "-";
137                                         }
138                         } 
139                 }
140         }
141         close DATAFILE;
142 }
143
144 #Subroutine to call .scr and .dat file write routines.
145 sub write_files() {
146         for ($cnt = 0; $cnt < @operations; $cnt = $cnt + 1) {
147                 # switch-case can be used instead if else
148                 if($operations[$cnt] eq "read") {
149                         &write_dat_file("rd");
150                         &write_scr_file("rd", "read");
151                 } elsif ($operations[$cnt] eq "write") {
152                         &write_dat_file("wr");
153                         &write_scr_file("wr", "write");
154                 } elsif ($operations[$cnt] eq "reread") {
155                         &write_dat_file("rrd");
156                         &write_scr_file("rrd", "reread");
157                 } elsif ($operations[$cnt] eq "rewrite") {
158                         &write_dat_file("rwr");
159                         &write_scr_file("rwr", "rewrite");
160                 } elsif ($operations[$cnt] eq "rewrite_again") {
161                         &write_dat_file("rwa");
162                         &write_scr_file("rwa", "rewrite_again");
163                 }
164         }
165 }
166
167 if ( !$ARGV[0] ) {
168         usage();
169 }
170 $file = $ARGV[0];
171 $obj = 0;
172 $thread = 0;
173 $first_obj = 1;
174 $first_thread = 1;
175 $count = 0;
176 $rsz = 0;
177 $subtitle = "";
178 $opt_y0 = -9999;
179 $cnt = 0;
180 @operations = ();
181 $graphgen = 0;
182 # Command line parameter parsing
183 use Getopt::Long;
184 GetOptions ('help' => \$opt_help, 'st=s' => \$subtitle, 'y0=i' => \$opt_y0) or usage(); 
185 if ($opt_help) {
186         usage();
187 }
188 open ( PFILE, "$file") or die "Can't open results";
189 LABEL: while ( <PFILE> ) {
190         chomp;
191         @line = split( /\s+/ );
192         if ($count == 0) {
193                 @GraphTitle = @line;
194                 $count++;
195                 next LABEL;
196         }
197         $linelen = @line;
198         if ($linelen > 26 || $linelen < 11) {
199                 print "invalid file format at line $count\n";
200                 exit 1; 
201         } 
202         if (!$rsz && $line[5]) {
203                 $cnt = 0;
204                 $rsz = $line[5];
205                 $first_obj = $line[7];
206                 $first_thread = $line[9];
207                 for ($i = 10; $i <= $linelen; $i = $i + 5) {
208                         if ($line[$i]) {
209                                 $operations[$cnt] = $line[$i];
210                                 $cnt++;
211                         }               
212                 }
213         }
214         if ($rsz != $line[5]) {
215                 &write_files();
216                 $rsz = $line[5];
217                 $first_obj = $line[7];
218                 $first_thread = $line[9];
219                 @operations = ();                       
220                 $cnt = 0;
221                 for ($i = 10; $i <= $linelen; $i = $i + 5) {
222                         if ($line[$i]) {
223                                 $operations[$cnt] = $line[$i];
224                                 $cnt++;
225                         }               
226                 }
227                 $obj = 0;
228                 $thread = 0;
229         }
230         for ($i = 0; $i < @operations; $i++) {
231                 # switch-case can be used instead if else
232                 if($operations[$i] eq "read") {
233                         $ard{$line[9]}{$line[7]} = $line[$i * 5 + 11];
234                 } elsif ($operations[$i] eq "write") {
235                         $awr{$line[9]}{$line[7]} = $line[$i * 5 + 11];
236                 } elsif ($operations[$i] eq "reread") {
237                         $arrd{$line[9]}{$line[7]} = $line[$i * 5 + 11];
238                 } elsif ($operations[$i] eq "rewrite") {
239                         $arwr{$line[9]}{$line[7]} = $line[$i * 5 + 11];
240                 } elsif ($operations[$i] eq "rewrite_again") {
241                         $arwa{$line[9]}{$line[7]} = $line[$i * 5 + 11];
242                 }       
243         }
244         if ( $obj < $line[9] ) {
245                 $obj = $line[9];
246         }
247         if ( $thread < $line[7] ) {
248                 $thread = $line[7];
249         }
250         $count++;
251 }
252 close PFILE;
253 if ($count > 1 && $rsz) {
254         &write_files();
255 }
256 if (!$graphgen) {
257         print "Invalid log file format\n";
258 }