Whamcloud - gitweb
LU-7768 fld: Do not retry fld request
[fs/lustre-release.git] / lustre / utils / plot-llstat
1 #!/usr/bin/perl -w
2 # Report generation for llstat
3 # ===============================
4 #        The plot-llstat script is used to generate csv file and
5 # instructions files for gnuplot from the output of llstat script.
6 # Since llstat is generic in nature, plot-llstat is also generic
7 # script.
8 #
9 # Assume that:
10 # operations = { open, close, read_bytes, write_bytes, connect, create, .. etc.}
11 # parameters = { Rate, Total}
12 #
13 #        plot-llstat script creates dat(csv) file using number of operations
14 # specified by the user. Number of operations equals to number of columns in csv
15 # file. And values in those columns are equals to the corresponding value of
16 # the "$param_inx" parameter from the output file.
17 #        The plot-llstat also creates .scr file that contains instructions
18 # for gnuplot to plot the graph. After generating .dat and .scr files this
19 # script invokes gnuplot to display graph.
20
21 # Featrues:
22 # 1. This script is generic in nature, works with any operations names.
23 # 2. User have option to setect operations of their choice for graph generation.
24 # 3. This script automatically selects different y axes according to the ranges
25 #    of values of the parameter.
26 # 4. One can change parameter to be consider for graphing 
27 #    by changing value of $param_inx.
28
29 # Syntax:
30 # $ plot-llstat <results_filename> [parameter index (default=2, i.e. Rate)]
31 # [Note: 1. The output filt given to this script must have been generated 
32 #           with -g option to the llstat script.
33 #        2. This script may need modifications whenever there will be 
34 #           modifications in output format of llstat script.]
35
36 # arg 0 is filename 
37 sub usages_msg(){
38         print "$0 parses and graphs the output of llstat using gnuplot,\n";
39         print "and generates .dat files for use in spreadsheets.\n";
40         print "Usage: $0 <results_filename> [parameter_index]\n";
41         print "         where parameter_index is one of:\n";
42         print "            1 - Count per interval\n";
43         print "            2 - Rate (count per second) (default)\n";
44         print "            3 - Total count\n";
45         print "ex: # llstat -i2 -g -c lustre-OST0000 > log\n";
46         print "    # $0 log 3\n";
47         exit 1;
48 }
49
50 my $count = 0;          # count for number of rows in csv(.dat) file.
51 my $jumpcolumn = -1;    # Columns to be skiped to get op. name and the "$param_inx" param. 
52 my @columns;            # Array for Operations names.
53 my $columnvalues = "";  # Values of the "$param_inx" parameter for all operations.
54 my @line;               # To store recently read line from log file
55 my $param_inx = 2;      # Index of the parameter are you interested in graphing.
56                         # Default is 2 for Rate.
57 my $GraphTitle;
58 if ( !$ARGV[0] ) {
59         usages_msg();   
60 }
61
62 if ( $ARGV[1] ) {
63         $param_inx = $ARGV[1];  
64 }
65
66 $file = $ARGV[0];
67
68 # Open log file for reading
69 open ( PFILE, "$file") or die "Can't open results log file";
70 @alllines = <PFILE>;
71 close PFILE;
72 LABLE:while ( $count <= $#alllines ) {
73         $line = $alllines[$count];
74         #print "$line\n";
75         chop($line);
76         @line = split(/\s+/,$line); # splits line into tokens
77         # This comparison may be changed if there will be changes log file.
78         if( $line[0] eq "Timestamp" ) { 
79         # decide operations position in the logfile depends on num of 
80         # parameters(Rate, Total, etc.) present in this line.
81                 $jumpcolumn = $#line;
82                 $count = $count + 2; # skip the "---------" line from result file.
83                 last LABLE;
84         }
85         if ($line[1] eq "STATS" && $line[2] eq "on") {
86                 $GraphTitle = $line;
87                 @GraphTitle = split( /:/, $GraphTitle );
88         }
89         $count++;
90 }
91 if ($jumpcolumn < 0) {
92         print "Invalid logfile format\n";
93         exit 1;
94 }
95 $lastline = $alllines[-1];
96 @lastline = split(/\s+/,$lastline);
97 my $allcolumns = "";
98 $i = 1;
99 while ($i < $#lastline) {
100         # display operations names for user selection.
101         print "$lastline[$i] ";
102         $allcolumns = "$allcolumns$lastline[$i] "; 
103         # capture the "$param_inx" parameter in $columnvalues, 
104         # used to define axes ranges depends on values.
105         $columnvalues = "$columnvalues$lastline[$i + $param_inx] ";
106         $i = $i + $jumpcolumn;
107 }
108 print "\nSelect columns(press return to select all): ";
109 $columns = <STDIN>;
110 # consider all operations if user hit return.
111 if ( $columns eq "\n" ) {
112         $columns = $allcolumns;
113 }
114 chop ($columns);
115 @columns = split (/\s+/, $columns);
116 # Open .csv file for writting required columns from log file.
117 open ( DATAFILE, "> $file.dat" ) or die "Can't open csv file for writting";
118 print DATAFILE "0 ";
119 for ($i = 0; $i < $#lastline; $i++) {
120         for ($j = 0; $j <= $#columns; $j++) {
121                 if ($columns[$j] eq $lastline[$i]) {
122                         print DATAFILE "$columns[$j]$lastline[$i + 4] ";
123                 }
124                 
125         }
126 }
127 print DATAFILE "\n";
128 my $found = 0;
129 # depends on $jumpcolumn, capture operation names and value of 
130 # the "$param_inx" parameter for that perticular operation.
131 while ( $count <= $#alllines )  {
132         $line = $alllines[$count];
133         #print "$line\n";
134         chop($line);
135         @line = split(/\s+/,$line); # splits line into tokens
136         # fill the csv(.dat) file with values of operations. 
137         print DATAFILE "$line[0]";
138         for ($j = 0; $j <= $#columns; $j++) {
139                 for ($i = 1; $i < $#line ; $i++) {
140                         if ($columns[$j] eq $line[$i]) {
141                                 # capture the "$param_inx" parameter 
142                                 print DATAFILE " $line[$i + $param_inx]";
143                                 $found = 1;
144                         }
145                 }
146                 if (!$found) {
147                         print DATAFILE " 0";
148                 }
149                 $found = 0;
150         }
151         print DATAFILE "\n";
152         $count = $count + 1;
153 }
154 close DATAFILE;
155
156 # Open .csv file for reading columns titles.
157 open ( DATAFILE, "$file.dat" ) or die "Can't open csv file for reading titles\n";
158 my $titles = <DATAFILE>;
159 close DATAFILE;
160 chop($titles);
161 @titles = split (/\s+/, $titles);
162 # Open .scr file for writting instructions for gnuplot.
163 open ( SCRFILE, "> $file.scr" ) or die "Can't open scr file for writting\n";
164 print SCRFILE "set title \"$GraphTitle[1]\"\n";
165 print SCRFILE "set xlabel \"time\"\n";
166 if ($param_inx == 1) {
167     print SCRFILE "set ylabel \"units/interval\"\n";
168 } elsif ($param_inx == 3) {
169     print SCRFILE "set ylabel \"units\"\n";
170 } else {
171     print SCRFILE "set ylabel \"units/sec\"\n";
172 }
173 my $plot = "plot";
174 # generate instructions for gnuplot
175 for ($i = 2; $i <= ($#columns + 2); $i++) {
176     print SCRFILE "$plot \"$file.dat\" using 1:$i axes x1y1 title \"$titles[$i - 1]\" with line\n";
177     $plot = "replot";
178 }
179 print SCRFILE "pause -1\n";
180 close SCRFILE;
181 # invoke gnuplot to display graph.
182 system ("gnuplot $file.scr") == 0 or die "ERROR: while ploting graph.\nMake sure that gnuplot is working properly";