1 #!/usr/bin/perl
   2 #
   3 # CDDL HEADER START
   4 #
   5 # The contents of this file are subject to the terms of the
   6 # Common Development and Distribution License (the "License").
   7 # You may not use this file except in compliance with the License.
   8 #
   9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10 # or http://www.opensolaris.org/os/licensing.
  11 # See the License for the specific language governing permissions
  12 # and limitations under the License.
  13 #
  14 # When distributing Covered Code, include this CDDL HEADER in each
  15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16 # If applicable, add the following below this CDDL HEADER, with the
  17 # fields enclosed by brackets "[]" replaced with your own identifying
  18 # information: Portions Copyright [yyyy] [name of copyright owner]
  19 #
  20 # CDDL HEADER END
  21 #
  22 #
  23 # Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24 # Use is subject to license terms.
  25 #
  26 # ident "%Z%%M% %I%     %E% SMI"
  27 #
  28 
  29 #
  30 # Compare filebench results
  31 #
  32 # Usage: filebench_summary <dir1> <dir2> ...
  33 #
  34 
  35 use CGI ':standard';
  36 
  37 $maxiopsoverall = 0;
  38 $maxiopsrate = 0;
  39 $maxbandwidth = 0;
  40 
  41 #
  42 # Create html and text
  43 #
  44 open (HTML, ">index.html");
  45 print HTML start_html(-title=>'Filebench');
  46 print HTML "<body>";
  47 #
  48 # Print aggregate flowop stats
  49 #
  50 foreach $dir (@ARGV) {
  51 
  52     printf ("Generating html for $dir\n");
  53     open (PROFILE, "<$dir/thisrun.prof");
  54     $description = <PROFILE>;
  55     $description =~ s/.*"(.+)".*/$1/;
  56 
  57     $files = `ls $dir/stats.*.out $dir/*/stats.*.out 2>/dev/null`;
  58     foreach $file (split(/\n/, $files)) {
  59         print "file = $file\n";
  60 
  61         # Search backwards in-case the hostname is of FQDN or there's a
  62         # '.' in $dir.
  63         $rstr = reverse $file;
  64         ($rfstype, $rworkload, $rprefix) = split(/\./, $rstr);
  65         $prefix = reverse $rprefix;
  66         $workload = reverse $rworkload;
  67         $fstype = reverse $rfstype;
  68 
  69         $dataset = $dir;
  70         $dataset =~ s/.*\/(.+)$/$1/;
  71         $dataset =~ s/\/$//;
  72         $desc{$dataset} = "$description";
  73 
  74         open (STATS, $file);
  75         $tmp = <STATS>;
  76         while (<STATS>) {
  77             ($flowop, $ops, $bandwidth, $latency, $cpu, $wait, $seconds) = split(/[ \t]+/, $_);
  78             
  79             if (/^$/) {
  80                 $tmp = <STATS>;
  81                 ($fluff, $opcnt, $ops, $reads, $writes, $bandwidth, 
  82                     $cpu) = split(/[ \tA-z:\/,]+/, $tmp);
  83                 $ops{$workload, $dataset} = $ops;
  84                 last;
  85             }
  86             
  87             $ops =~ s/ops\/s//;
  88             $bandwidth =~ s/mb\/s//;
  89             $latency =~ s/ms\/op//;
  90             $cpu =~ s/us\/op//;
  91             
  92             # Collapse shadow reads into single metric
  93             if ($flowop =~ /shadowread/) {
  94                 $flowop = "shadow-read";
  95             }
  96             
  97             # Collapse database writes into single metric
  98             if ($flowop =~ /db.*write/) {
  99                 $flowop = "db-write";
 100             }
 101             
 102             # Collapse database writes into single metric
 103             if ($flowop =~ /db.*write/) {
 104                 $flowop = "db-write";
 105             }
 106             
 107             $datasets{$dataset} = $dataset;
 108             $workloads{$workload} = $workload;
 109 
 110             $flowops{$flowop} = $flowop;
 111             $wkl_flowops{$flowop, $workload} = $flowop;
 112             $wkl_workload{$flowop, $workload} = $workload;
 113             $flow_ops{$flowop, $workload, $dataset} += $ops;
 114             $flow_bandwidth{$flowop, $workload, $dataset} += $bandwidth;
 115             $flow_latency{$flowop, $workload, $dataset} += $latency;
 116             $flow_cpu{$flowop, $workload, $dataset} += $cpu;
 117 
 118             $bandwidth{$workload, $dataset} += $bandwidth;
 119             $latency{$workload, $dataset} += $latency;
 120             $cpu{$workload, $dataset} += $cpu;
 121 
 122             $flowopcnt{$flowop, $workload, $dataset}++;
 123             $workloadcnt{$workload, $dataset}++;
 124         }
 125         close(STATS);
 126     }
 127 }
 128 
 129 # HTML IOPS
 130 print HTML h1('Throughput breakdown (ops per second)');
 131 print HTML "<table border=1>";
 132 print HTML "<b><td>Workload</td>";
 133 foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
 134     print HTML "<td>$desc{$dataset}</td>";
 135 }
 136 print HTML "</b></tr>";
 137 
 138 foreach $workload (sort (keys %workloads)) {
 139     print HTML "<b><tr><td>$workload</td>";
 140     $last = 0;
 141     foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
 142         $color = "white";
 143         $this = $ops{$workload, $dataset};
 144         if ($last && ($this - $last) < ($last * -0.1)) {
 145                 $color = "red";
 146         }
 147         if ($last && ($this - $last) > ($last * 0.1)) {
 148                 $color = "green";
 149         }
 150         printf HTML ("<td>%d</td\n", $this);
 151         $last = $ops{$workload, $dataset};
 152     }
 153     print HTML "</b></tr>";
 154 }
 155 print HTML "</table>";
 156 
 157 # HTML Bandwidth
 158 print HTML h1('Bandwidth breakdown (MB/s)');
 159 print HTML "<table border=1>";
 160 print HTML "<td>Workload</td>";
 161 foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
 162     print HTML "<td>$desc{$dataset}</td>";
 163 }
 164 print HTML "</tr>";
 165 foreach $workload (sort (keys %workloads)) {
 166     $bandwidth = 0;
 167     foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
 168         $bandwidth +=  $bandwidth{$workload, $dataset};
 169     }
 170     next if ($bandwidth == 0);
 171     print HTML "<tr><td>$workload</td>";
 172     foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
 173         printf HTML ("<td>%d</td>\n", $bandwidth{$workload, $dataset});
 174     }
 175     print HTML "</tr>";
 176 }
 177 print HTML "</table>";
 178 
 179 # HTML Latency
 180 print HTML h1('Latency breakdown (ms per op)');
 181 print HTML "<table border=1>";
 182 print HTML "<td>Workload</td>";
 183 foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
 184     print HTML "<td>$desc{$dataset}</td>";
 185 }
 186 
 187 print HTML "</tr>";
 188 foreach $workload (sort (keys %workloads)) {
 189     print HTML "<tr><td>$workload</td>";
 190     foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
 191         if ( $workloadcnt{$workload, $dataset}) {
 192             printf HTML ("<td>%.1f</td>", $latency{$workload,
 193                 $dataset} / $workloadcnt{$workload, $dataset});
 194         } else {
 195              printf HTML ("<td></td>");
 196         }
 197     }
 198     print HTML "</tr>";
 199     foreach $flowop (keys %wkl_flowops) {
 200         next if ("$wkl_workload{$flowop}" ne "$workload");
 201         print HTML "<tr><td><i>__$wkl_flowops{$flowop}</td>";
 202         foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
 203              if ( $flowopcnt{$flowop, $dataset}) {
 204                  printf HTML ("<td>%.1f</td>\n", $flow_latency{$flowop, 
 205                     $dataset} / $flowopcnt{$flowop, $dataset});
 206              } else {
 207                  printf HTML ("<td></td>");
 208              }
 209         }
 210         print HTML "</i></tr>";
 211     }
 212 }
 213 print HTML "</table>";
 214 
 215 # HTML Efficiency
 216 print HTML h1('Efficiency breakdown (Code path length in uS/op)');
 217 print HTML "<table border=1>";
 218 print HTML "<td>Workload</td>";
 219 foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
 220     print HTML "<td>$desc{$dataset}</td>";
 221 }
 222 print HTML "</tr>";
 223 foreach $workload (sort (keys %workloads)) {
 224     print HTML "<tr><td>$workload</td>";
 225     foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
 226         if ($workloadcnt{$workload, $dataset}) {
 227             printf HTML ("<td>%d</td>", $cpu{$workload, $dataset}
 228                 / $workloadcnt{$workload, $dataset});
 229         } else {
 230              printf HTML ("<td></td>");
 231         }
 232     }
 233     print HTML "</tr>";
 234     foreach $flowop (keys %wkl_flowops) {
 235         next if ("$wkl_workload{$flowop}" ne "$workload");
 236         print HTML "<tr><td><i>__$wkl_flowops{$flowop}</td>";
 237         foreach $dataset (sort {$a cmp $b}(keys %datasets)) {
 238             if ($flowopcnt{$flowop, $dataset}) {
 239                 printf HTML ("<td>%d</td>\n", $flow_cpu{$flowop, 
 240                     $dataset} / $flowopcnt{$flowop, $dataset});
 241             } else {
 242                  printf HTML ("<td></td>");
 243             }
 244         }
 245         print HTML "</i></tr>";
 246     }
 247 }
 248 print HTML "</table>";
 249 
 250 end_html();