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

# Content
1 #!/usr/bin/perl -w
2
3 #
4 # i-scream central monitoring system
5 # http://www.i-scream.org.uk
6 # 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 #-----------------------------------------------------------------
24 # Machine statistics grabber
25 # $Author: tdb $
26 # $Id: statgrab.pl,v 1.48 2002/05/21 16:47:11 tdb Exp $
27 #
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 # Have to hope this will work really.
45 my($ostype) = `uname -s`; chop($ostype);
46
47 # Decide which paths we should use.
48 my($topbin); my($dfbin); my($usersbin);
49 my($unamebin); my($uptimebin); my($sysctlbin);
50
51 if ($ostype eq "SunOS") {
52 # covers: Solaris 8
53 $topbin = "/usr/local/sbin/top -d2 -s1 0";
54 $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 $topbin = "/usr/bin/top -d1 -n2 -b -p0";
62 $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 $topbin = "/usr/bin/top -d2 -s1 0";
70 $dfbin = "/bin/df";
71 $usersbin = "/usr/bin/users";
72 $unamebin = "/usr/bin/uname";
73 $uptimebin = "/usr/bin/uptime";
74 $sysctlbin = "/sbin/sysctl";
75 }
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
83 # Run the following components: -
84 &print_ident();
85 &include_osver();
86 &include_uptime();
87 &include_users();
88 &include_top();
89 &include_disk();
90
91 # End the program normally.
92 exit(0);
93
94
95
96
97 # 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 print 'packet.version statgrab.pl $Revision: 1.48 $';
102 print "\n";
103 }
104
105 # sub to print pairs of data, separated by a single space character.
106 # If the second argument is undefined, then the pair is still printed,
107 # however, the value shall be displayed as the the 'default' value
108 # if the passed value was undefined.
109 sub print_pair($$$) {
110 my($default, $name, $value) = @_;
111
112 if (!defined $value) {
113 $value = $default;
114 }
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 # sub to find out disk partition information, if it exists.
125 sub include_disk() {
126
127 # Run the df program.
128 my(@df) = `$dfbin -akl`;
129
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 $line =~ /^([^\s]*)\s*([0-9]*)\s*([0-9]*)\s*([0-9]*)\s*[^\s]*\s*(\/[^\s]*)\s*/;
135 # $4 will not match unless everything before it does...
136 if (defined $5) {
137 my ($filesystem, $kbytes, $used, $avail, $mount) = ($1, $2, $3, $4, $5);
138 &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 ++$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 sub include_users() {
152
153 # Find out all users on this machine.
154 my($users) = `$usersbin`;
155 $users = "\n" unless defined $users;
156 chop $users;
157 my($users_count) = 0;
158 $users_count++ while $users =~ /\w+/g;
159 my($users_list) = $users." ";
160
161 &print_pair(0, "packet.users.count", $users_count);
162 &print_pair("unknown", "packet.users.list", $users_list);
163 }
164
165
166 # sub to run a series of regexps on the output of 'top' to
167 # gather various machine statistics.
168 sub include_top() {
169
170 # Find out some numbers from top.
171 my(@top) = `$topbin`;
172 my($top) = join(" ", @top);
173 $top =~ s/\n/ /g;
174
175 if($ostype eq "SunOS") {
176 &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 &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 $top =~ /([0-9]+?)([KMG]) real/;
191 my($real) = $1;
192 $real*=1024 if $2 eq "G";
193 $real/=1024 if $2 eq "K";
194 &print_pair(0, "packet.memory.total", $real);
195
196 $top =~ /([0-9]+?)([KMG]) free/;
197 my($free) = $1;
198 $free*=1024 if $2 eq "G";
199 $free/=1024 if $2 eq "K";
200 &print_pair(0, "packet.memory.free", $free);
201
202 $top =~ /([0-9]+?)([KMG]) swap in use/;
203 my($swap_in_use) = $1;
204 $swap_in_use*=1024 if $2 eq "G";
205 $swap_in_use/=1024 if $2 eq "K";
206 # DO NOT print this one out... save it for in a moment...
207
208 $top =~ /([0-9]+?)([KMG]) swap free/;
209 my($swap_free) = $1;
210 $swap_free*=1024 if $2 eq "G";
211 $swap_free/=1024 if $2 eq "K";
212 &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 &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 &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
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
233 # The following need to be specified in megabytes.
234 # If they are preceeded by a G, then multiply by 1024.
235
236 # 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
244 &print_pair(0, "packet.memory.total", $real);
245 &print_pair(0, "packet.memory.free", $free);
246
247 $top =~ /Swap: ([0-9]+?)([KMG]) Total/;
248 my($swap_total) = $1;
249 $swap_total*=1024 if $2 eq "G";
250 $swap_total/=1024 if $2 eq "K";
251 &print_pair(0, "packet.swap.total", $swap_total);
252
253 $top =~ /Swap:.*, ([0-9]+?)([KMG]) Free/;
254 my($swap_free) = $1;
255 $swap_free*=1024 if $2 eq "G";
256 $swap_free/=1024 if $2 eq "K";
257 &print_pair(0, "packet.swap.free", $swap_free);
258
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 }
265 elsif ($ostype eq "Linux") {
266 my ($top) = "";
267 foreach my $line (@top) {
268 $top = $line . $top;
269 }
270 $top =~ s/\n/ /g;
271
272 &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 &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
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
288 # The following need to be specified in megabytes.
289 # If they are preceeded by a G, then multiply by 1024.
290
291 $top =~ /Mem:.*?([0-9]+)([KMG])\s+(av|total)/;
292 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 $top =~ /Mem:.*?([0-9]+)([KMG])\s+free/;
298 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 $top =~ /Swap:.*?([0-9]+)([KMG])\s+(av|total)/;
304 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 $top =~ /Swap:.*?([0-9]+)([KMG])\s+free/;
310 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 else {
316 # we could have some catchall here
317 # but as it stands this means we'll just skip top stuff
318 # for unknown systems
319 }
320 }
321
322 # sub to get details of the machine's operating system.
323 sub include_osver() {
324
325 # Find out details about the operating system
326 # If these values remain undefined, then the print_pair
327 # function shall show the value to be the string "unknown".
328 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
334 &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
340 }
341
342 # sub to get system uptime in seconds.
343 sub include_uptime() {
344
345 # 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 # grab the uptime
363 my($uptime) = `$uptimebin`;
364
365 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
371 # work out the days, hours, and minutes
372
373 if ($uptime =~ /day.*,\s+([0-9]+):([0-9]+)/) {
374 # normal
375 $uptime =~ /up\s+([0-9]+)\s+[^\s]+,\s+([0-9]+):([0-9]+)/;
376 $uptime = "$1:$2:$3";
377 }
378 else {
379 if ($uptime =~ /day/) {
380 if ($uptime =~ /hr/) {
381 # 0 minutes
382 $uptime =~ /up\s+([0-9]+)\s+[^\s]+,\s+([0-9]+)\s+[^\s]+,/;
383 $uptime = "$1:$2:0";
384 }
385 elsif ($uptime =~ /min/) {
386 # 0 hours
387 $uptime =~ /up\s+([0-9]+)\s+[^\s]+,\s+([0-9]+)\s+[^\s]+,/;
388 $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 }
396 elsif ($uptime =~ /hr/) {
397 # 0 days and 0 minutes
398 $uptime =~ /up\s+([0-9]+)\s+/;
399 $uptime = "0:$1:0";
400 }
401 elsif ($uptime =~ /min/) {
402 # 0 days and 0 hours
403 $uptime =~ /up\s+([0-9]+)\s+/;
404 $uptime = "0:0:$1";
405 }
406 else {
407 # 0 days
408 $uptime =~ /up\s+([0-9]+):([0-9]+)/;
409 $uptime = "0:$1:$2";
410 }
411 }
412
413 # turn into seconds
414 $uptime =~ /([0-9]+):([0-9]+):([0-9]+)/;
415 $uptime = ($3+($2+($1*24))*60)*60;
416
417 # print the value out
418 &print_pair("unknown", "packet.os.uptime", $uptime);
419
420 }