2 # llstat is a utility that takes stats files as input with optional
3 # clear-flag. The clear-flag is used to clear the stats file before
4 # printing stats information. The lustre stats files generally located
5 # inside proc/fs/lustre/. This program first reads the required statistics
6 # information from specified stat file, process the information and prints
7 # the output after every interval specified by user.
9 # Subroutine for printing usages information
12 print STDERR "Usage: $pname [-c] [-g] [-i <interval>] [-h <help>] <stats_file>\n";
13 print STDERR " stats_file : lustre/.../stat\n";
14 print STDERR " -i interval: polling period\n";
15 print STDERR " -c : clear stats file first\n";
16 print STDERR " -g : graphable output format\n";
17 print STDERR " -h : help, display this information\n";
18 print STDERR "example: $pname -i 1 ost (monitors lustre/ost/OSS/ost/stats)\n";
19 print STDERR "Use CTRL + C to stop statistics printing\n";
26 if ( $print_once && $interval ) {
27 printf "Timestamp [Name Count Rate Total Unit]...";
28 printf "\n--------------------------------------------------------------------";
31 if ($cc && !$starttime) {
34 printf "\n%-5.0f", ($cc - $starttime);
36 printf "$statspath @ $cc\n";
37 printf "%-25s %-10s %-10s %-10s", "Name", "Cur.Count", "Cur.Rate", "#Events";
39 printf "%-8s %10s %10s %12s %10s", "Unit", "last", "min", "avg", "max";
41 if ( $anysumsquare ) {
42 printf "%10s", "stddev";
48 # known units are: reqs, bytes, usec, bufs, regs, pages
49 # readstat subroutine reads and processes statistics from stats file.
50 # This subroutine gets called after every interval specified by user.
56 ($name, $cumulcount, $samples, $unit, $min, $max, $sum, $sumsquare)
58 $prevcount = %cumulhash->{$name};
59 if (defined($prevcount)) {
60 $diff = $cumulcount - $prevcount;
61 if ($name eq "snapshot_time") {
63 &print_headings($cumulcount);
66 $tdiff = 1; # avoid division by zero
69 elsif ($cumulcount!=0) {
75 $myname = $myname . "_rq";
77 printf " %s %lu %lu %lu %s",
78 $myname, $diff, ($diff/$tdiff), $cumulcount, $myunit;
80 printf "%-25s %-10lu %-10lu %-10lu",
81 $name, $diff, ($diff/$tdiff), $cumulcount;
85 my $sum_diff = $sum - %sumhash->{$name};
87 printf " %s %lu %.2f %lu %s",
88 $name, $sum_diff, ($sum_diff/$tdiff), $sum, $unit;
90 printf "%-8s %10lu %10lu %12.2f %10lu", $unit,
91 $sum_diff, $min, ($sum/$cumulcount), $max;
93 if (defined($sumsquare)) {
94 my $s = $sumsquare - (($sum_orig*$sum_orig)/$cumulcount);
96 my $cnt = ($cumulcount >= 2) ? $cumulcount : 2 ;
97 my $stddev = sqrt($s/($cnt - 1));
99 printf " %9.2f ", $stddev;
110 if ($cumulcount!=0) {
111 # print info when interval is not specified.
112 printf "%-25s $cumulcount\n", $name
117 if (defined($sumsquare)) {
121 %cumulhash->{$name} = $cumulcount;
122 %sumhash->{$name} = $sum;
143 # Command line parameter parsing
145 getopts('hcgi:') or usage();
147 $clear = 1 if $opt_c;
148 $graphable = 1 if $opt_g;
149 $interval = $opt_i if $opt_i;
156 print "ERROR: extra argument $_\n";
161 print "ERROR: Need to specify stats_file\n";
166 $statspath = $obddev;
167 } elsif ( -f "$obddev/$obdstats" ) {
168 $statspath = "$obddev/$obdstats";
170 my $st = glob("/{proc,sys}/fs/lustre/*/$obddev/$obdstats");
174 $st = glob("/{proc,sys}/fs/lustre/*/*/$obddev/$obdstats");
180 if ( $statspath =~ /^None$/ ) {
181 die "Cannot locate stat file for: $obddev\n";
183 # Clears stats file before printing information in intervals
185 open ( STATS, "> $statspath") || die "Cannot clear $statspath: $!\n";
190 use POSIX qw(strftime);
192 $hostname = `lctl list_nids | head -1`;
194 print "$pname: STATS on ", strftime("%D", localtime($time_v));
195 print " $statspath on $hostname\n";
196 open(STATS, $statspath) || die "Cannot open $statspath: $!\n";