ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/host/generic/statgrab.pl
Revision: 1.33
Committed: Tue Feb 13 12:18:07 2001 UTC (23 years, 9 months ago) by tdb
Content type: text/plain
Branch: MAIN
Changes since 1.32: +43 -2 lines
Log Message:
Added some basic support for Linux. Linux top chucks out values in K's, so we
need to strip down to Megabytes (to be inline with the others).
Also, not convinced about the output of top, it seems to be stating that only
a couple of % of CPU is in use, when I can see clearly this isn't correct.

File Contents

# Content
1 #!/usr/bin/perl -w
2
3 #-----------------------------------------------------------------
4 # Machine statistics grabber
5 # $Author: tdb1 $
6 # $Id: statgrab.pl,v 1.32 2001/02/13 11:57:48 tdb1 Exp $
7 #
8 # A Perl script to return various information about a host machine
9 # by examining the output of some common Unix/Linux commands.
10 # This is a stopgap to act as a generic way of collecting the
11 # data. It is perhaps more reliable than the current Java host
12 # at doing this and it can obviously be used by a C++ program as
13 # well until the C++ host is ready to find the information out
14 # itself.
15 #-----------------------------------------------------------------
16
17
18 $| = 1;
19
20
21 # You'd be silly not to use this ;)
22 use strict;
23
24 # Have to hope this will work really.
25 my($ostype) = `uname -s`; chop($ostype);
26
27 # Decide which paths we should use.
28 my($topbin); my($dfbin); my($usersbin); my($unamebin); my($uptimebin);
29
30 if ($ostype eq "SunOS") {
31 # covers: Solaris 8
32 $topbin = "/usr/local/sbin/top -d2 -s1 0";
33 $dfbin = "/usr/bin/df";
34 $usersbin = "/usr/ucb/users";
35 $unamebin = "/usr/bin/uname";
36 $uptimebin = "/usr/bin/uptime";
37 }
38 elsif ($ostype eq "Linux") {
39 # covers: Debian r2.2
40 $topbin = "/usr/bin/top -d1 -n0 -b";
41 $dfbin = "/bin/df";
42 $usersbin = "/usr/bin/users";
43 $unamebin = "/bin/uname";
44 $uptimebin = "/usr/bin/uptime";
45 }
46 elsif ($ostype eq "FreeBSD") {
47 # covers: FreeBSD 4.2-STABLE
48 $topbin = "/usr/bin/top -d2 -s1 0";
49 $dfbin = "/bin/df";
50 $usersbin = "/usr/bin/users";
51 $unamebin = "/usr/bin/uname";
52 $uptimebin = "/usr/bin/uptime";
53 }
54 else {
55 print "statgrab.pl Error: Unable to identify system type - \"$ostype\".\n";
56 print "\"uname -s\" does not report one of the following known types;\n";
57 print " SunOS, Linux, FreeBSD\n";
58 exit(1);
59 }
60
61 # Run the following components: -
62 &print_ident();
63 &include_osver();
64 &include_uptime();
65 &include_users();
66 &include_top();
67 &include_disk();
68
69 # End the program normally.
70 exit(0);
71
72
73
74
75 # prints out an identifier for this version of statgrab.pl
76 # the host should check this when reading data
77 # means the host must be checked and updated to work with newer versions.
78 sub print_ident() {
79 print 'version statgrab.pl $Revision: 1.32 $';
80 print "\n";
81 }
82
83 # sub to print pairs of data, separated by a single space character.
84 # If the second argument is undefined, then the pair is still printed,
85 # however, the value shall be displayed as the the 'default' value
86 # if the passed value was undefined.
87 sub print_pair($$$) {
88 my($default, $name, $value) = @_;
89
90 if (!defined $value) {
91 $value = $default;
92 }
93
94 # Remove the trailing linefeed if we've not already done so.
95 chomp($value);
96
97 # print the pair of data with a space inbetween.
98 print "$name $value\n";
99 }
100
101
102 # sub to find out disk partition information, if it exists.
103 sub include_disk() {
104
105 # Run the df program.
106 my(@df) = `$dfbin -ak`;
107
108 # Go through each line of the program, looking for each thing we want.
109 my($partition_no) = 0;
110 for (my($i) = 0; $i < $#df; $i++) {
111 my($line) = $df[$i];
112 $line =~ /^(\/[^\s]*)\s*([0-9]*)\s*([0-9]*)\s*([0-9]*)\s*[^\s]*\s*(\/[^\s]*)\s*/;
113 # $4 will not match unless everything before it does...
114 if (defined $5) {
115 my ($filesystem, $kbytes, $used, $avail, $mount) = ($1, $2, $3, $4, $5);
116 &print_pair("unknown", "packet.disk.p$partition_no.attributes.name", $filesystem);
117 &print_pair(0, "packet.disk.p$partition_no.attributes.kbytes", $kbytes);
118 &print_pair(0, "packet.disk.p$partition_no.attributes.used", $used);
119 &print_pair(0, "packet.disk.p$partition_no.attributes.avail", $avail);
120 &print_pair("unknown", "packet.disk.p$partition_no.attributes.mount", $mount);
121 ++$partition_no;
122 }
123 }
124
125 }
126
127 # sub to find out the list of all (non-unique) usernames logged
128 # in to the machine and how many their are. (not
129 sub include_users() {
130
131 # Find out all users on this machine.
132 my($users) = `$usersbin`;
133 $users = "\n" unless defined $users;
134 chop $users;
135 my($users_count) = 0;
136 $users_count++ while $users =~ /\w+/g;
137 my($users_list) = $users." ";
138
139 &print_pair(0, "packet.users.count", $users_count);
140 &print_pair("unknown", "packet.users.list", $users_list);
141 }
142
143
144 # sub to run a series of regexps on the output of 'top' to
145 # gather various machine statistics.
146 sub include_top() {
147
148 # Find out some numbers from top.
149 my(@top) = `$topbin`;
150 my($top) = join(" ", @top);
151 $top =~ s/\n//g;
152
153 if($ostype eq "SunOS") {
154 &print_pair(0, "packet.processes.total", $top =~ /([^\s]+?) processes:/);
155 &print_pair(0, "packet.processes.sleeping", $top =~ / ([^\s]+?) sleeping/);
156 &print_pair(0, "packet.processes.zombie", $top =~ / ([^\s]+?) zombie/);
157 &print_pair(0, "packet.processes.stopped", $top =~ / ([^\s]+?) stopped/);
158 &print_pair(0, "packet.processes.cpu", $top =~ /([^\s]+?)\s*on cpu/);
159 &print_pair(0, "packet.cpu.idle", $top =~ /([^\s]+?)% idle/);
160 &print_pair(0, "packet.cpu.user", $top =~ /([^\s]+?)% user/);
161 &print_pair(0, "packet.cpu.kernel", $top =~ /([^\s]+?)% kernel/);
162 &print_pair(0, "packet.cpu.iowait", $top =~ /([^\s]+?)% iowait/);
163 &print_pair(0, "packet.cpu.swap", $top =~ /([^\s]+?)% swap/);
164
165 # The following need to be specified in megabytes.
166 # If they are preceeded by a G, then multiply by 1024.
167
168 $top =~ /([^\s]+?)([MG]) real/;
169 my($real) = $1;
170 $real*=1024 if $2 eq "G";
171 &print_pair(0, "packet.memory.total", $real);
172
173 $top =~ /([^\s]+?)([MG]) free/;
174 my($free) = $1;
175 $free*=1024 if $2 eq "G";
176 &print_pair(0, "packet.memory.free", $free);
177
178 $top =~ /([^\s]+?)([MG]) swap in use/;
179 my($swap_in_use) = $1;
180 $swap_in_use*=1024 if $2 eq "G";
181 # DO NOT print this one out... save it for in a moment...
182
183 $top =~ /([^\s]+?)([MG]) swap free/;
184 my($swap_free) = $1;
185 $swap_free*=1024 if $2 eq "G";
186 &print_pair(0, "packet.swap.free", $swap_free);
187
188 # AJ requested total swap instead of swap_in_use, so here we go!
189 &print_pair(0, "packet.swap.total", $swap_free + $swap_in_use);
190 }
191 elsif ($ostype eq "FreeBSD") {
192 &print_pair(0, "packet.processes.total", $top =~ /([^\s]+?) processes:/);
193 &print_pair(0, "packet.processes.sleeping", $top =~ / ([^\s]+?) sleeping/);
194 &print_pair(0, "packet.processes.zombie", $top =~ / ([^\s]+?) zombie/);
195 &print_pair(0, "packet.processes.stopped", $top =~ / ([^\s]+?) stopped/);
196 &print_pair(0, "packet.processes.cpu", $top =~ /([^\s]+?)\s*running/);
197 &print_pair(0, "packet.cpu.idle", $top =~ /([^\s]+?)% idle/);
198 &print_pair(0, "packet.cpu.user", $top =~ /([^\s]+?)% user/);
199 &print_pair(0, "packet.cpu.kernel", $top =~ /([^\s]+?)% system/);
200 &print_pair(0, "packet.cpu.iowait", $top =~ /([^\s]+?)% interrupt/);
201 &print_pair(0, "packet.cpu.swap", $top =~ /([^\s]+?)% swap/);
202
203 # The following need to be specified in megabytes.
204 # If they are preceeded by a G, then multiply by 1024.
205
206 # !! Can't get the total memory !!
207 #$top =~ /([^\s]+?)([MG]) real/;
208 #my($real) = $1;
209 #$real*=1024 if $2 eq "G";
210 #&print_pair(0, "packet.memory.total", $real);
211 &print_pair(0, "packet.memory.total", 0);
212
213 $top =~ /([^\s]+?)([MG]) Free/;
214 my($free) = $1;
215 $free*=1024 if $2 eq "G";
216 &print_pair(0, "packet.memory.free", $free);
217
218 $top =~ /Swap: ([^\s]+?)([MG]) Total/;
219 my($swap_total) = $1;
220 $swap_total*=1024 if $2 eq "G";
221 &print_pair(0, "packet.swap.total", $swap_total);
222
223 $top =~ /Swap:.*, ([^\s]+?)([MG]) Free/;
224 my($swap_free) = $1;
225 $swap_free*=1024 if $2 eq "G";
226 &print_pair(0, "packet.swap.free", $swap_free);
227 }
228 elsif ($ostype eq "Linux") {
229 &print_pair(0, "packet.processes.total", $top =~ /([^\s]+?) processes:/);
230 &print_pair(0, "packet.processes.sleeping", $top =~ / ([^\s]+?) sleeping/);
231 &print_pair(0, "packet.processes.zombie", $top =~ / ([^\s]+?) zombie/);
232 &print_pair(0, "packet.processes.stopped", $top =~ / ([^\s]+?) stopped/);
233 &print_pair(0, "packet.processes.cpu", $top =~ /([^\s]+?)\s*running/);
234 &print_pair(0, "packet.cpu.idle", $top =~ /([^\s]+?)% idle/);
235 &print_pair(0, "packet.cpu.user", $top =~ /([^\s]+?)% user/);
236 &print_pair(0, "packet.cpu.kernel", $top =~ /([^\s]+?)% system/);
237 &print_pair(0, "packet.cpu.iowait", $top =~ /([^\s]+?)% interrupt/);
238 &print_pair(0, "packet.cpu.swap", $top =~ /([^\s]+?)% swap/);
239
240 # The following need to be specified in megabytes.
241 # If they are preceeded by a G, then multiply by 1024.
242
243 $top =~ / ([^\s]+?)([KMG]) av/;
244 my($real) = $1;
245 $real*=1024 if $2 eq "G";
246 $real/=1024 if $2 eq "K";
247 &print_pair(0, "packet.memory.total", int($real));
248
249 $top =~ / ([^\s]+?)([KMG]) free/;
250 my($free) = $1;
251 $free*=1024 if $2 eq "G";
252 $free/=1024 if $2 eq "K";
253 &print_pair(0, "packet.memory.free", int($free));
254
255 $top =~ /Swap:\s+([^\s]+?)([KMG]) av/;
256 my($swap_total) = $1;
257 $swap_total*=1024 if $2 eq "G";
258 $swap_total/=1024 if $2 eq "K";
259 &print_pair(0, "packet.swap.total", int($swap_total));
260
261 $top =~ /Swap:.*, ([^\s]+?)([KMG]) free/;
262 my($swap_free) = $1;
263 $swap_free*=1024 if $2 eq "G";
264 $swap_free/=1024 if $2 eq "K";
265 &print_pair(0, "packet.swap.free", int($swap_free));
266 }
267 else {
268 # we could have some catchall here
269 # but as it stands this means we'll just skip top stuff
270 # for unknown systems
271 }
272 }
273
274 # sub to get details of the machine's operating system.
275 sub include_osver() {
276
277 # Find out details about the operating system
278 # If these values remain undefined, then the print_pair
279 # function shall show the value to be the string "unknown".
280 my($os_name) = `$unamebin -s`;
281 my($os_release) = `$unamebin -r`;
282 my($os_platform) = `$unamebin -m`;
283 my($os_sysname) = `$unamebin -n`;
284 my($os_version) = `$unamebin -v`;
285
286 &print_pair("unknown", "packet.os.name", $os_name);
287 &print_pair("unknown", "packet.os.release", $os_release);
288 &print_pair("unknown", "packet.os.platform", $os_platform);
289 &print_pair("unknown", "packet.os.sysname", $os_sysname);
290 &print_pair("unknown", "packet.os.version", $os_version);
291
292 }
293
294 # sub to get system uptime in seconds.
295 sub include_uptime() {
296
297 # debug stuff, all the different cases
298
299 # normal
300 #my($uptime) = " 4:48pm up 49 day(s), 6:30, 201 users, load average: 0.33, 0.35, 0.38\n";
301 # 0 days
302 #my($uptime) = " 4:48pm up 6:30, 201 users, load average: 0.33, 0.35, 0.38\n";
303 # 0 hours
304 #my($uptime) = " 4:48pm up 49 day(s), 30 min(s), 201 users, load average: 0.33, 0.35, 0.38\n";
305 # 0 mins
306 #my($uptime) = " 4:48pm up 49 day(s), 6 hr(s), 201 users, load average: 0.33, 0.35, 0.38\n";
307 # 0 days and 0 mins
308 #my($uptime) = " 4:48pm up 6 hr(s), 201 users, load average: 0.33, 0.35, 0.38\n";
309 # 0 days and 0 hours
310 #my($uptime) = " 4:48pm up 30 min(s), 201 users, load average: 0.33, 0.35, 0.38\n";
311 # 0 hours and 0 mins
312 #my($uptime) = " 4:48pm up 49 day(s), 201 users, load average: 0.33, 0.35, 0.38\n";
313
314 # grab the uptime
315 my($uptime) = `$uptimebin`;
316
317 &print_pair(0, "packet.load.load1", $uptime =~ /load average.?:\s*([^\s]+?),/);
318 &print_pair(0, "packet.load.load5", $uptime =~ /load average.?:\s*.+?,\s*([^\s]+?),/);
319 &print_pair(0, "packet.load.load15", $uptime =~ /load average.?:\s*.+?,\s*.+?,\s*([^\s]+)/);
320
321 # work out the days, hours, and minutes
322
323 if ($uptime =~ /day.*,\s+([0-9]+):([0-9]+)/) {
324 # normal
325 $uptime =~ /up\s+([0-9]+)\s+.*,\s+([0-9]+):([0-9]+)/;
326 $uptime = "$1:$2:$3";
327 }
328 else {
329 if ($uptime =~ /day/) {
330 if ($uptime =~ /hr/) {
331 # 0 minutes
332 $uptime =~ /up\s+([0-9]+)\s+.*,\s+([0-9]+)\s+.*,/;
333 $uptime = "$1:$2:0";
334 }
335 elsif ($uptime =~ /min/) {
336 # 0 hours
337 $uptime =~ /up\s+([0-9]+)\s+.*,\s+([0-9]+)\s+.*,/;
338 $uptime = "$1:0:$2";
339 }
340 else {
341 # 0 hours and 0 mins
342 $uptime =~ /up\s+([0-9]+)/;
343 $uptime = "$1:0:0";
344 }
345 }
346 elsif ($uptime =~ /hr/) {
347 # 0 days and 0 minutes
348 $uptime =~ /up\s+([0-9]+)\s+/;
349 $uptime = "0:$1:0";
350 }
351 elsif ($uptime =~ /min/) {
352 # 0 days and 0 hours
353 $uptime =~ /up\s+([0-9]+)\s+/;
354 $uptime = "0:0:$1";
355 }
356 else {
357 # 0 days
358 $uptime =~ /up\s+([0-9]+):([0-9]+)/;
359 $uptime = "0:$1:$2";
360 }
361 }
362
363 # turn into seconds
364 $uptime =~ /([0-9]+):([0-9]+):([0-9]+)/;
365 $uptime = ($3+($2+($1*24))*60)*60;
366
367 # print the value out
368 &print_pair("unknown", "packet.os.uptime", $uptime);
369
370 }