ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/host/generic/statgrab.pl
Revision: 1.49
Committed: Mon Jun 10 14:10:44 2002 UTC (22 years, 3 months ago) by tdb
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.48: +2 -2 lines
State: FILE REMOVED
Log Message:
Tidy up of files. These are all old things that are not only no longer used
but are also probably useless to anyone other than us. This saves checking
them out all the time, and makes the "cms/source" tree contain only current
stuff. They'll still exist in the attic's though :)

File Contents

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