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