Whamcloud - gitweb
land v0.9.1 on HEAD, in preparation for a 1.0.x branch
[fs/lustre-release.git] / lustre / utils / llobdstat.pl
1 #!/usr/bin/perl
2
3 my $pname = $0;
4
5 my $defaultpath = "/proc/fs/lustre";
6 my $obdstats = "stats";
7
8 sub usage()
9 {
10     print STDERR "Usage: $pname <stats_file> [<interval>]\n";
11     print STDERR "example: $pname help (to get help message)\n";
12     print STDERR "example: $pname ost1 1 (monitor /proc/fs/lustre/obdfilter/ost1/stats\n";
13     exit 1;
14 }
15
16 my $statspath = "None";
17 my $interval = 0;
18
19 if (($#ARGV < 0) || ($#ARGV > 1)) {
20     usage();
21 } else {
22     if ( $ARGV[0] =~ /help$/ ) {
23         usage();
24     }
25     if ( -f $ARGV[0] ) {
26         $statspath = $ARGV[0];
27     } elsif ( -f "$ARGV[0]/$obdstats" ) {
28         $statspath = "$ARGV[0]/$obdstats";
29     } else {
30         my $st = `ls $defaultpath/*/$ARGV[0]/$obdstats 2> /dev/null`;
31         chop $st;
32         if ( -f "$st" ) {
33             $statspath = $st;
34         }
35     }
36     if ( $statspath =~ /^None$/ ) {
37         die "Cannot locate stat file for: $ARGV[0]\n";
38     }
39     if ($#ARGV == 1) {
40         $interval = $ARGV[1];
41     } 
42 }
43
44 print "$pname on $statspath\n";
45
46 my %cur;
47 my %last;
48 my $mhz = 0;
49 my ($read_bytes, $read, $write_bytes, $write, $getattr, $setattr, $open, $close,    $create, $destroy, $statfs, $punch, $snapshot_time) = 
50     ("read_bytes", "read", "write_bytes", "write", "getattr", "setattr", "open",    "close", "create", "destroy", "statfs", "punch", "snapshot_time"); 
51
52 my @extinfo = ($setattr, $open, $close, $create, $destroy, $statfs, $punch);
53 my %shortname = ($setattr => "sa", $open => "op", $close => "cl", 
54                 $create => "cx", $destroy => "dx", $statfs => "st", $punch => "pu");
55
56 sub get_cpumhz()
57 {
58     my $cpu_freq;
59     my $itc_freq; # On Itanium systems use this
60     if (open(CPUINFO, "/proc/cpuinfo")==0) {
61         return;
62     }
63     while (<CPUINFO>) {
64         if (/^cpu MHz\s+:\s*([\d\.]+)/) { $cpu_freq=$1; }
65         elsif (/^itc MHz\s+:\s*([\d\.]+)/) { $itc_freq=$1; }
66     }
67     if (defined($itc_freq)) { $mhz = $itc_freq; }
68     elsif (defined($cpu_freq)) { $mhz = $cpu_freq; }
69     else { $mhz = 1; }
70     close CPUINFO;
71 }
72
73 get_cpumhz();
74 print "Processor counters run at $mhz MHz\n";
75
76 sub readall()
77 {
78         my $prevcount;
79         my @iodata;
80
81         seek STATS, 0, 0;
82         while (<STATS>) {
83                 chop;
84 #               ($name, $cumulcount, $samples, $unit, $min, $max, $sum, $sumsquare) 
85                 @iodata = split(/\s+/, $_);
86                 my $name = $iodata[0];
87
88                 $prevcount = $cur{$name};
89                 if (defined($prevcount)) {
90                         $last{$name} = $prevcount; 
91                 } 
92                 if ($name =~ /^read_bytes$/ || $name =~ /^write_bytes$/) {
93                         $cur{$name} = $iodata[6];
94                 }
95                 elsif ($name =~ /^snapshot_time$/) {
96 #                       $cumulcount =~ /(\d+)/;
97                         $cur{$name} = $iodata[1];
98                 }
99                 else {
100                         $cur{$name} = $iodata[1];
101                 }
102         }
103 }
104 sub process_stats()
105 {
106         my $delta;
107         my $data;
108         my $last_time = $last{$snapshot_time};
109         if (!defined($last_time)) {
110                 printf "R %-g/%-g W %-g/%-g attr %-g/%-g open %-g/%-g create %-g/%-g stat %-g punch %-g\n",
111                 $cur{$read_bytes}, $cur{$read}, 
112                 $cur{$write_bytes}, $cur{$write}, 
113                 $cur{$getattr}, $cur{$setattr}, 
114                 $cur{$open}, $cur{$close}, 
115                 $cur{$create}, $cur{$destroy}, 
116                 $cur{$statfs}, $cur{$punch}; 
117         }
118         else {
119                 my $timespan = $cur{$snapshot_time} - $last{$snapshot_time};
120         
121                 my $rdelta = $cur{$read} - $last{$read};
122                 my $rvdelta = int ($rdelta / $timespan);
123                 my $rrate = ($cur{$read_bytes} - $last{$read_bytes}) /
124                            ($timespan * ( 1 << 20 ));
125                 my $wdelta = $cur{$write} - $last{$write};
126                 my $wvdelta = int ($wdelta / $timespan);
127                 my $wrate = ($cur{$write_bytes} - $last{$write_bytes}) /
128                            ($timespan * ( 1 << 20 ));
129                 printf "R %6lu (%5lu %6.2fMb)/s W %6lu (%5lu %6.2fMb)/s",
130                         $rdelta, $rvdelta, $rrate,
131                         $wdelta, $wvdelta, $wrate;
132
133                 $delta = $cur{$getattr} - $last{$getattr};
134                 if ( $delta != 0 ) {
135                         $rdelta = int ($delta/$timespan);
136                         print " ga:$delta,$rdelta/s";
137                 }
138                 
139                 for $data ( @extinfo ) {
140                         $delta = $cur{$data} - $last{$data};
141                         if ($delta != 0) {
142                                 print " $shortname{$data}:$delta";
143                         }
144                 }
145                 print "\n";
146                 $| = 1;
147         }
148 }
149
150 open(STATS, $statspath) || die "Cannot open $statspath: $!\n";
151 do {
152         readall();
153         process_stats();
154         if ($interval) { 
155                 sleep($interval);
156                 %last = %cur;
157         }
158 } while ($interval);
159 close STATS;
160