4 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License version 2 only,
8 # as published by the Free Software Foundation.
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # General Public License version 2 for more details (a copy is included
14 # in the LICENSE file that accompanied this code).
16 # You should have received a copy of the GNU General Public License
17 # version 2 along with this program; If not, see
18 # http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 # Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 # CA 95054 USA or visit www.sun.com if you need additional information or
26 # Copyright 2008 Sun Microsystems, Inc. All rights reserved
27 # Use is subject to license terms.
29 # This file is part of Lustre, http://www.lustre.org/
30 # Lustre is a trademark of Sun Microsystems, Inc.
32 # Author: Jitendra Pawar <jitendra@clusterfs.com>
34 # Report generation for plot-obdfilter
35 # ====================================
36 # The plot-obdfilter script is used to generate csv file and
37 # instructions files for gnuplot from the output of obdfilter-survey script.
39 # The plot-obdfilter also creates .scr file that contains instructions
40 # for gnuplot to plot the graph. After generating .dat and .scr files this
41 # script invokes gnuplot to display graph.
44 # $ obdfilter-survey > log_filename
45 # $ plot-obdfilter <log_filename>
46 # [Note: 1. Please use the .summary file generated by obdfilter-survey as log_file.
47 # It is generally available at /tmp/obdfilter_survey_<date_time_system>.summary
48 # 2. This script may need modifications whenever there will be
49 # modifications in output format of obdfilter-survey script.
50 # 3. Gnuplot version 4.0 or above is required.]
54 print "Usage: $0 <log_filename> [--st=<subtitle>] [--y0=<Y-axis start point>]\n";
55 print " The $0 parses and plots graphs for output of obdfilter-survey using gnuplot.\n";
56 print " It generates <log_filename>-<Rsize><rd/wr>.dat and\n";
57 print " <log_filename>-<Rsize>-<rd/wr/rrd/rwr/rwa>.scr files.\n";
58 print " Those will be used for graphing the results\n";
60 print " --st: SubTitle for the graph\n";
61 print " --y0: Start point of Y-axis, Default value automatically taken based on Y-axis values ranges\n";
62 print " log_file: use the .summary file generated by obdfilter-survey as log_file.\n";
63 print " It is generally available at /tmp/obdfilter_survey_<date_time_system>.summary\n";
64 print "e.g. # $0 obdfilter-log --st=\"Sub-Title\" --y0=50\n";
68 # check whether gnuplot exists?
69 system ("which gnuplot > /dev/null") == 0 or die "gnuplot does not exist, please install it and try again.\n";
71 #Subroutine to write .scr file that further used by gnuplot to plot the graph.
72 sub write_scr_file() {
75 print "generating plot $file-$rsz-$op.png\n";
76 open ( SCRFILE, "> $file-$rsz-$op.scr" ) or die "Can't open scr file for writing";
79 print SCRFILE "set title \"@GraphTitle\\n$rwlabel, Rsize = $rsz KBytes, $subtitle\"\n";
81 print SCRFILE "set title \"@GraphTitle\\n$rwlabel, Rsize = $rsz KBytes\"\n";
83 print SCRFILE "set xlabel \"Threads\"\n";
84 print SCRFILE "set ylabel \"Speeds(MB/s)\"\n";
85 print SCRFILE "set logscale x\n";
86 print SCRFILE "set grid\n";
87 print SCRFILE "set terminal png\n";
88 print SCRFILE "set output \"/dev/null\"\n";
89 if ($opt_y0 != -9999) {
90 print SCRFILE "set yrange [ $opt_y0: ]\n";
95 # generate instructions for gnuplot, with adjusting X-axes ranges
96 for ($j = $first_thread; $j <= $thread ; $j = $j + $j) {
97 printf SCRFILE "$plot \"$file-$rsz-$op.dat\" using 1:$i axes x%dy1 title \"$rwlabel-obj$j\" with line\n", $xrange;
101 print SCRFILE "set output \"$file-$rsz-$op.png\"\n";
102 print SCRFILE "replot\n";
105 # invoke gnuplot to display graph.
106 system ("gnuplot $file-$rsz-$op.scr") == 0 or die "ERROR: while ploting graph";
107 system ("rm $file-$rsz-$op.scr");
110 #Subroutine to write .dat file that further used by gnuplot to plot the graph.
111 sub write_dat_file() {
113 print "writing data $file-$rsz-$op.dat\n";
114 # Open .csv/.dat file for writing required columns from log file.
115 open ( DATAFILE, "> $file-$rsz-$op.dat" ) or die "Can't open csv file for writing";
116 printf DATAFILE "%-6s", "thrd";
117 for ($j = $first_thread; $j <= $thread ; $j = $j + $j) {
118 printf DATAFILE "%-10s", "$op-obj$j";
120 for ( $i = $first_obj; $i <= $obj; $i = $i + $i ) {
121 printf DATAFILE "\n%-6s", $i;
122 for ($j = $first_thread; $j <= $thread ; $j = $j + $j) {
123 # switch-case can be used instead if else
125 if ( $ard{$i}{$j} ) {
126 printf DATAFILE "%-10s", $ard{$i}{$j};
128 printf DATAFILE "%-10s", "-";
130 } elsif ($op eq "wr" ) {
131 if ( $awr{$i}{$j} ) {
132 printf DATAFILE "%-10s", $awr{$i}{$j};
134 printf DATAFILE "%-10s", "-";
136 } elsif ($op eq "rwr" ) {
137 if ( $arwr{$i}{$j} ) {
138 printf DATAFILE "%-10s", $arwr{$i}{$j};
140 printf DATAFILE "%-10s", "-";
142 } elsif ($op eq "rrd" ) {
143 if ( $arrd{$i}{$j} ) {
144 printf DATAFILE "%-10s", $arrd{$i}{$j};
146 printf DATAFILE "%-10s", "-";
148 } elsif ($op eq "rwa" ) {
149 if ( $arwa{$i}{$j} ) {
150 printf DATAFILE "%-10s", $arwa{$i}{$j};
152 printf DATAFILE "%-10s", "-";
160 #Subroutine to call .scr and .dat file write routines.
162 for ($cnt = 0; $cnt < @operations; $cnt = $cnt + 1) {
163 # switch-case can be used instead if else
164 if($operations[$cnt] eq "read") {
165 &write_dat_file("rd");
166 &write_scr_file("rd", "read");
167 } elsif ($operations[$cnt] eq "write") {
168 &write_dat_file("wr");
169 &write_scr_file("wr", "write");
170 } elsif ($operations[$cnt] eq "reread") {
171 &write_dat_file("rrd");
172 &write_scr_file("rrd", "reread");
173 } elsif ($operations[$cnt] eq "rewrite") {
174 &write_dat_file("rwr");
175 &write_scr_file("rwr", "rewrite");
176 } elsif ($operations[$cnt] eq "rewrite_again") {
177 &write_dat_file("rwa");
178 &write_scr_file("rwa", "rewrite_again");
198 # Command line parameter parsing
200 GetOptions ('help' => \$opt_help, 'st=s' => \$subtitle, 'y0=i' => \$opt_y0) or usage();
204 open ( PFILE, "$file") or die "Can't open results";
205 LABEL: while ( <PFILE> ) {
207 @line = split( /\s+/ );
214 if ($linelen > 26 || $linelen < 11) {
215 print "invalid file format at line $count\n";
218 if (!$rsz && $line[5]) {
221 $first_obj = $line[7];
222 $first_thread = $line[9];
223 for ($i = 10; $i <= $linelen; $i = $i + 5) {
225 $operations[$cnt] = $line[$i];
230 if ($rsz != $line[5]) {
233 $first_obj = $line[7];
234 $first_thread = $line[9];
237 for ($i = 10; $i <= $linelen; $i = $i + 5) {
239 $operations[$cnt] = $line[$i];
246 for ($i = 0; $i < @operations; $i++) {
247 # switch-case can be used instead if else
248 if($operations[$i] eq "read") {
249 $ard{$line[9]}{$line[7]} = $line[$i * 5 + 11];
250 } elsif ($operations[$i] eq "write") {
251 $awr{$line[9]}{$line[7]} = $line[$i * 5 + 11];
252 } elsif ($operations[$i] eq "reread") {
253 $arrd{$line[9]}{$line[7]} = $line[$i * 5 + 11];
254 } elsif ($operations[$i] eq "rewrite") {
255 $arwr{$line[9]}{$line[7]} = $line[$i * 5 + 11];
256 } elsif ($operations[$i] eq "rewrite_again") {
257 $arwa{$line[9]}{$line[7]} = $line[$i * 5 + 11];
260 if ( $obj < $line[9] ) {
263 if ( $thread < $line[7] ) {
269 if ($count > 1 && $rsz) {
273 print "Invalid log file format\n";