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