Whamcloud - gitweb
9c9cf5a1bc53ddabde972918be76520a82ee2bc3
[fs/lustre-release.git] / lustre / utils / llobdstat
1 #!/usr/bin/perl
2 # llobdstat is a utility that parses obdfilter statistics files
3 # found at proc/fs/lustre/<ostname>/stats.
4 # It is mainly useful to watch the statistics change over time.
5
6 my $pname = $0;
7
8 my $defaultpath = "/proc/fs/lustre";
9 my $obdstats = "stats";
10
11 sub usage()
12 {
13     print STDERR "Usage: $pname <ost_name> [<interval> [<count>}]\n";
14     print STDERR "where  ost_name  : ost name under $defaultpath/obdfilter\n";
15     print STDERR "       interval  : sample interaval in seconds\n";
16     print STDERR "example: $pname lustre-OST0000 2\n";
17     print STDERR "Use CTRL + C to stop statistics printing\n";
18     exit 1;
19 }
20
21 my $statspath = "None";
22 my $interval = 0;
23 my $counter = undef;
24
25 if (($#ARGV < 0) || ($#ARGV > 2)) {
26     usage();
27 } else {
28     if ( $ARGV[0] =~ /help$/ ) {
29         usage();
30     }
31     if ( -f $ARGV[0] ) {
32         $statspath = $ARGV[0];
33     } elsif ( -f "$ARGV[0]/$obdstats" ) {
34         $statspath = "$ARGV[0]/$obdstats";
35     } else {
36         my $st = `ls $defaultpath/obdfilter/$ARGV[0]/$obdstats 2> /dev/null`;
37         chop $st;
38         if ( -f "$st" ) {
39             $statspath = $st;
40         }
41     }
42     if ( $statspath =~ /^None$/ ) {
43         die "Cannot locate stat file for: $ARGV[0]\n";
44     }
45     if ($#ARGV > 0) {
46         $interval = $ARGV[1];
47     }
48     if ($#ARGV > 1) {
49         $counter = $ARGV[2];
50     }
51 }
52
53 print "$pname on $statspath\n";
54
55 my %cur;
56 my %last;
57 my $mhz = 0;
58
59 # Removed some statstics like open, close that obdfilter doesn't contain.
60 # To add statistics parameters one needs to specify parameter names in the
61 # below declarations in the same sequence.
62 my ($read_bytes, $write_bytes, $create, $destroy, $statfs, $punch,
63     $snapshot_time) = ("read_bytes", "write_bytes", "create", "destroy",
64                        "statfs", "punch", "snapshot_time");
65
66 my @extinfo = ($create, $destroy, $statfs, $punch);
67 my %shortname = ($create => "cx", $destroy => "dx", $statfs => "st", $punch => "pu");
68
69 sub get_cpumhz()
70 {
71     my $cpu_freq;
72     my $itc_freq; # On Itanium systems use this
73     if (open(CPUINFO, "/proc/cpuinfo")==0) {
74         return;
75     }
76     while (<CPUINFO>) {
77         if (/^cpu MHz\s+:\s*([\d\.]+)/) { $cpu_freq=$1; }
78         elsif (/^itc MHz\s+:\s*([\d\.]+)/) { $itc_freq=$1; }
79     }
80     if (defined($itc_freq)) {
81         $mhz = $itc_freq;
82     } elsif (defined($cpu_freq)) {
83         $mhz = $cpu_freq;
84     } else {
85         $mhz = 1;
86     }
87     close CPUINFO;
88 }
89
90 get_cpumhz();
91 print "Processor counters run at $mhz MHz\n";
92
93 # read statistics from obdfilter stats file.
94 # This subroutine gets called after every interval specified by user.
95 sub readstat()
96 {
97     my $prevcount;
98     my @iodata;
99
100     seek STATS, 0, 0;
101     while (<STATS>) {
102         chop;
103 #        ($name, $cumulcount, $samples, $unit, $min, $max, $sum, $sumsquare)
104         @iodata = split(/\s+/, $_);
105         my $name = $iodata[0];
106
107         $prevcount = $cur{$name};
108         if (defined($prevcount)) {
109             $last{$name} = $prevcount;
110         }
111         if ($name =~ /^read_bytes$/ || $name =~ /^write_bytes$/) {
112             $cur{$name} = $iodata[6];
113         }
114         elsif ($name =~ /^snapshot_time$/) {
115 #            $cumulcount =~ /(\d+)/;
116             $cur{$name} = $iodata[1];
117         } else {
118             $cur{$name} = $iodata[1];
119         }
120     }
121 }
122
123 # process stats information read from obdfilter stats file.
124 # This subroutine gets called after every interval specified by user.
125 sub process_stats()
126 {
127     my $delta;
128     my $data;
129     my $last_time = $last{$snapshot_time};
130     if (!defined($last_time)) {
131         printf "Read: %-g, Write: %-g, create/destroy: %-g/%-g, stat: %-g, punch: %-g\n",
132         $cur{$read_bytes}, $cur{$write_bytes},
133         $cur{$create}, $cur{$destroy},
134         $cur{$statfs}, $cur{$punch};
135         if ($interval) {
136             print "[NOTE: cx: create, dx: destroy, st: statfs, pu: punch ]\n\n";
137             print "Timestamp   Read-delta  ReadRate  Write-delta  WriteRate\n";
138             print "--------------------------------------------------------\n";
139         }
140     } else {
141         my $timespan = $cur{$snapshot_time} - $last{$snapshot_time};
142         my $rdelta = $cur{$read_bytes} - $last{$read_bytes};
143         my $rrate = ($rdelta) / ($timespan * ( 1 << 20 ));
144         my $wdelta = $cur{$write_bytes} - $last{$write_bytes};
145         my $wrate = ($wdelta) / ($timespan * ( 1 << 20 ));
146         $rdelta = ($rdelta) / (1024 * 1024);
147         $wdelta = ($wdelta) / (1024 * 1024);
148         # This print repeats after every interval.
149         printf "%10lu  %6.2fMB  %6.2fMB/s   %6.2fMB  %6.2fMB/s",
150                $cur{$snapshot_time}, $rdelta, $rrate, $wdelta, $wrate;
151
152         $delta = $cur{$getattr} - $last{$getattr};
153         if ( $delta != 0 ) {
154             $rdelta = int ($delta/$timespan);
155             print " ga:$delta,$rdelta/s";
156         }
157
158         for $data ( @extinfo ) {
159             $delta = $cur{$data} - $last{$data};
160             if ($delta != 0) {
161                 print " $shortname{$data}:$delta";
162             }
163         }
164         print "\n";
165         $| = 1;
166     }
167 }
168
169 #Open the obdfilter stat file with STATS
170 open(STATS, $statspath) || die "Cannot open $statspath: $!\n";
171 do {
172     # read the statistics from stat file.
173     readstat();
174     process_stats();
175     if ($interval) {
176         sleep($interval);
177         %last = %cur;
178     }
179     # Repeat the statistics printing after every "interval" specified in
180     # command line, up to counter times, if specified
181 } while ($interval && (defined($counter) ? $counter-- > 0 : 1));
182 close STATS;
183 # llobdfilter.pl ends here.