Whamcloud - gitweb
LU-2558 test: recovery-small 19a FAIL no eviction
[fs/lustre-release.git] / lustre / utils / llstat
1 #!/usr/bin/perl
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.
8
9 # Subroutine for printing usages information
10 sub usage()
11 {
12         print STDERR "Usage: $pname [-c] [-g] [-i <interval>] [-h <help>] <stats_file>\n";
13         print STDERR "       stats_file : /proc/fs/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 /proc/fs/lustre/ost/OSS/ost/stats)\n";
19         print STDERR "Use CTRL + C to stop statistics printing\n";
20         exit 1;
21 }
22
23 sub print_headings()
24 {       my $cc = $_[0];
25         if ($graphable) {
26                 if ( $print_once && $interval ) {
27                         printf "Timestamp [Name Count Rate Total Unit]...";
28                         printf "\n--------------------------------------------------------------------";
29                         $print_once = 0;
30                 }
31                 if ($cc && !$starttime) {
32                         $starttime = $cc
33                 }
34                 printf "\n%-5.0f", ($cc - $starttime);
35         } else {
36                 printf "$statspath @ $cc\n";
37                 printf "%-25s %-10s %-10s %-10s", "Name", "Cur.Count", "Cur.Rate", "#Events";
38                 if ( $anysum ) {
39                         printf "%-8s %10s %10s %12s %10s", "Unit", "last", "min", "avg", "max";
40                 }
41                 if ( $anysumsquare ) {
42                         printf "%10s", "stddev";
43                 }
44                 printf "\n";
45         }
46 }
47
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.
51 sub readstat()
52 {
53         seek STATS, 0, 0;
54         while (<STATS>) {
55         chop;
56         ($name, $cumulcount, $samples, $unit, $min, $max, $sum, $sumsquare) 
57                 = split(/\s+/, $_);
58         $prevcount = %cumulhash->{$name};
59         if (defined($prevcount)) {
60                 $diff = $cumulcount - $prevcount;
61                 if ($name eq "snapshot_time") {
62                         $tdiff = int($diff);
63                         &print_headings($cumulcount);
64                         $| = 1;
65                         if ($tdiff == 0) {
66                             $tdiff = 1; # avoid division by zero
67                         }
68                 }
69                 elsif ($cumulcount!=0) {
70                         if ($graphable) {
71                             my $myunit = $unit;
72                             my $myname = $name;
73                             if (defined($sum)) {
74                                 $myunit = "[reqs]";
75                                 $myname = $myname . "_rq";
76                             }
77                             printf "   %s %lu %lu %lu %s", 
78                             $myname, $diff, ($diff/$tdiff), $cumulcount, $myunit;
79                         } else {
80                             printf "%-25s %-10lu %-10lu %-10lu",
81                             $name, $diff, ($diff/$tdiff), $cumulcount;
82                         }
83                         if (defined($sum)) {
84                                 my $sum_orig = $sum;
85                                 my $sum_diff = $sum - %sumhash->{$name};
86                                 if ($graphable) {
87                                     printf "   %s %lu %.2f %lu %s",
88                                     $name, $sum_diff, ($sum_diff/$tdiff), $sum, $unit;
89                                 } else {
90                                     printf "%-8s %10lu %10lu %12.2f %10lu", $unit, 
91                                     $sum_diff, $min, ($sum/$cumulcount), $max;
92                                 }
93                                 if (defined($sumsquare)) {
94                                         my $s = $sumsquare - (($sum_orig*$sum_orig)/$cumulcount);
95                                         if ($s >= 0) {
96                                                 my $cnt = ($cumulcount >= 2) ? $cumulcount : 2 ;
97                                                 my $stddev = sqrt($s/($cnt - 1));
98                                                 if (!$graphable) {
99                                                         printf " %9.2f ", $stddev;
100                                                 }
101                                         }
102                                 }
103                         }
104                         if (!$graphable) {
105                                 printf "\n";
106                         }
107                         $| = 1;
108                 }
109         } else {
110                 if ($cumulcount!=0) {
111                         # print info when interval is not specified.
112                         printf "%-25s $cumulcount\n", $name
113                 }
114                 if (defined($sum)) {
115                         $anysum = 1;
116                 }
117                 if (defined($sumsquare)) {
118                         $anysumsquare = 1;
119                 }
120         }
121         %cumulhash->{$name} = $cumulcount;
122         %sumhash->{$name} = $sum;
123         } #end of while
124 }
125
126 #Globals
127 $pname = $0;
128 $defaultpath = "/proc/fs/lustre";
129 $obdstats = "stats";
130 $clear = 0;
131 $graphable = 0;
132 $interval = 0;
133 $statspath = "None";
134 $anysumsquare = 0;
135 $mhz = 0;
136 $print_once = 1;
137 %cumulhash;
138 %sumhash;
139 $anysum = 0;
140 $obddev = "";
141 $starttime = 0;
142 $ONE_MB = 1048576;
143
144 # Command line parameter parsing
145 use Getopt::Std;
146 getopts('hcgi:') or usage();
147 usage() if $opt_h;
148 $clear = 1 if $opt_c;
149 $graphable = 1 if $opt_g;
150 $interval = $opt_i if $opt_i;
151
152 my $i = 0;
153 foreach (@ARGV) {
154         $obddev = $_;
155         $i++;
156         if ($i > 1) {
157                 print "ERROR: extra argument $_\n";
158                 usage();
159         }
160 }
161 if ( !$obddev ) {
162         print "ERROR: Need to specify stats_file\n";
163         usage();
164 }
165 # Process arguments
166 if ( -f $obddev ) {
167         $statspath = $obddev;
168 } elsif ( -f "$obddev/$obdstats" ) {
169         $statspath = "$obddev/$obdstats";
170 } else {
171         my $st = glob("$defaultpath/*/$obddev/$obdstats");
172         if ( -f "$st" ) {
173                 $statspath = $st;
174         } else {
175                 $st = glob("$defaultpath/*/*/$obddev/$obdstats");
176                 if ( -f "$st" ) {
177                         $statspath = $st;
178                 }
179         }
180 }
181 if ( $statspath =~ /^None$/ ) {
182         die "Cannot locate stat file for: $obddev\n";
183 }
184 # Clears stats file before printing information in intervals
185 if ( $clear ) {
186         open ( STATS, "> $statspath") || die "Cannot clear $statspath: $!\n";
187         print STATS " ";
188         close STATS;
189         sleep($interval);           
190 }
191 use POSIX qw(strftime);
192 $time_v = time();
193 $hostname = `lctl list_nids | head -1`;
194 chop($hostname);
195 print "$pname: STATS on ", strftime("%D", localtime($time_v));
196 print " $statspath on $hostname\n";
197 open(STATS, $statspath) || die "Cannot open $statspath: $!\n";
198 do {
199         readstat();
200         if ($interval) { 
201                 sleep($interval);
202         }
203 } while ($interval);
204 close STATS;