jablonka.czprosek.czf

hotsanic

Subversion Repositories:
[/] [trunk/] [lib/] [HotSaNIC.pm] - Blame information for rev 36

 

Line No. Rev Author Line
11simandl#
2# $Id: HotSaNIC.pm,v 1.2 2002/11/24 18:50:06 tinheap Exp $
3#
4 
5package HotSaNIC;
6 
7use Exporter;
8 
9# our ($VERSION, @ISA, @EXPORT);
10 
11($VERSION = '$Revision: 1.2 $') =~ s/.*(\d+\.\d+).*/$1/;
12 
13@ISA = qw(Exporter);
14@EXPORT = qw (
15 snmp_sysbulk
16 snmp_sysquery
17 get_module_name
18 get_config
19 read_settings
20 check_config
21 strip_unwanted
22 identify_os_type
23 parse_line
24 get_diagram_properties
25 opt2arg
26 arg2opt
27 check_args
28 dupe_control
29 convert_units
30 );
31 
32######################################################################
33#
34# control function to make sure that a module is running only once
35#
36# Usage:
37# dupe_control($what,$module-name,$message);
38#
39# $what:
40# start -> call this method at the head of a module to touch the
41# dupe-detection checkfile.
42# stop -> remove checkfile and exit normally.
43# warn -> print $message as warning and continue execution.
44# die -> remove checkfile and stop process with error.
45#
46# The given message will be preceded with a timestamp (in seconds
47# since 1970) and the module-name:
48#
49# <time> MODULE:message\n
50#
51sub dupe_control {
52 my ($what,$mod,$message)=@_;
53 if (!defined $mod) { $mod=get_module_name(); }
54 if (!defined $message) { $message="(unknown reason)"; }
55 if ($what eq "start") {
56 if (-e "running.dat") {
57 open FILE,"running.dat";
58 $pid=<FILE>;
59 close FILE;
60 chomp $pid;
61 if ((defined $pid) && ($pid ne "") && (-e "/proc/$pid")) {
62 open FILE,"/proc/$pid/stat";
63 $line=<FILE>;
64 close FILE;
65 if( index($line,"read-data") >= 0) {
66 @fileds=split / /,$line;
67 $starttime=$fileds[21]/100;
68 open FILE,"/proc/uptime";
69 $line=<FILE>;
70 close FILE;
71 ($uptime)=split / /,$line;
72 $delta=int(($uptime-$starttime)*100)/100;
73 if ( ($uptime-$starttime) > 3600) {
74 print time," ",$mod,": process running >1 hour --> KILLING!\n";
75 system "kill -9 $pid";
76 }
77 else {
78 print time," ",$mod,": process already running on PID $pid for $delta seconds.\n";
79 exit 1;
80 }
81 }
82 }
83 }
84 open FILE,">running.dat";
85 print FILE $$;
86 close FILE;
87 }
88 elsif ($what eq "stop") {
89 if (-e "running.dat") { unlink "running.dat"; }
90 exit 0;
91 }
92 elsif ($what eq "die") {
93 if (-e "running.dat") { unlink "running.dat"; }
94 die time." ".$mod.": ".$message."\n";
95 }
96 elsif ($what eq "warn") {
97 print time," ",$mod," warn: ",$message,"\n";
98 }
99 else { print time," ",$mod," method \"",$what,"\" not supported.\n"; }
100 }
101 
102######################################################################
103#
104# checks if all necessary arguments are given in the corosponding
105# hash. If not, try to reconstruct them or to set defaults.
106#
107# Usage:
108# %arguments=check_args(%arguments);
109#
110sub check_args {
111 ($check,%ARGS)=@_;
112 foreach $value (split /,/,$check) {
113 if ( (!defined $ARGS{$value}) || ($ARGS{$value} eq "") || ($ARGS{$value} eq "not configured") ) {
114 if ($value eq "MODNAME") { $ARGS{$value}=get_module_name(); }
115 if ($value eq "DEBUGLEVEL") { $ARGS{$value}=-1; }
116 if ($value eq "OSTYPE") { $ARGS{$value}=identify_os_type(); }
117 if ($value eq "SNMPWALK") {
118 my @found=grep /snmpwalk$/, `locate bin\/snmpwalk`;
119 if (@found) { $found=$found[0];chomp $found; $result=" Found: ".$found; $ARGS{$value}=$found; } else { $ARGS{$value}="echo >/dev/null"; }
120 dupe_control("warn",$ARGS{"MODNAME"},"SNMPWALK not given on commandline! $result");
121 }
122 if ($value eq "SNMPGET") {
123 my @found=grep /snmpget$/, `locate bin\/snmpget`;
124 if (@found) { $found=$found[0];chomp $found; $result=" Found: ".$found; $ARGS{$value}=$found; } else { $ARGS{$value}="echo >/dev/null"; }
125 dupe_control("warn",$ARGS{"MODNAME"},"SNMPGET not given on commandline! $result");
126 }
127 }
128 }
129 return %ARGS;
130 }
131 
132######################################################################
133#
134# converts an option-hash to cmdline argument string which can be
135# passed to a module script
136#
137# Usage:
138# $commandline_args=opt2arg(%options);
139#
140sub opt2arg {
141 my $line="";
142 my %opts=@_;
143 foreach $var (keys(%opts)) {
144 if (index("DEBUGLEVEL MODNAME OSTYPE SNMPWALK SNMPGET",$var) >= 0) {
145 $line=$line." ".$var."=\"".$opts{$var}."\"";
146 }
147 }
148 if ($opts{"DEBUGLEVEL"}>=0) { print "CLIENT-LINE: $line\n" };
149 return $line;
150 }
151 
152######################################################################
153#
154# converts cmdline arguments array to an options-hash
155#
156# Usage:
157# %options=arg2opt($commandline_args)
158#
159sub arg2opt {
160 my %HASH;
161 foreach $pair (@_) {
162 ($var,$value)=split /=/, $pair;
163 $HASH{$var}=$value;
164 }
165 if (! defined $HASH{"MODNAME"}) { $HASH{"MODNAME"}=get_module_name(); }
166 if (! defined $HASH{"OSTYPE"}) { $HASH{"OSTYPE"}=`uname`; chomp $HASH{"OSTYPE"}; }
167 if (! defined $HASH{"DEBUGLEVEL"}) { $HASH{"DEBUGLEVEL"}=-1; }
168 if ($HASH{"DEBUGLEVEL"} >=6 ) {
169 print "\n";
170 foreach (keys %HASH) { printf " %-15s %s\n",$_,$HASH{$_}; }
171 }
172 return %HASH;
173 }
174 
175######################################################################
176#
177# evaluates some diagram properties from the given range
178#
179# Usage:
180# ($description,$file_description,$build_interval,$diagram_range)=get_diagram_properties($range);
181#
182sub get_diagram_properties {
183 my ($range)=@_;
184 my ($descr,$file,$build,$fullrange);
185 if ($range eq "1h") { $descr="hour"; $file=$descr; $build=0; $fullrange=3600; }
186 elsif ($range eq "6h") { $descr="6 hours"; $file="6h"; $build=30; $fullrange=21600; }
187 elsif ($range eq "1day") { $descr="day"; $file=$descr; $build=120; $fullrange=86400; }
188 elsif ($range eq "1week") { $descr="week"; $file=$descr; $build=1000; $fullrange=604800; }
189 elsif ($range eq "1month") { $descr="month"; $file=$descr; $build=4300; $fullrange=2592000; }
190 elsif ($range eq "1year") { $descr="year"; $file=$descr; $build=52500; $fullrange=31536000; }
191 return ($descr,$file,$build,$fullrange);
192 }
193 
194######################################################################
195#
196# Query remote host via SNMP and store data in tempfile
197# GetBulk method
198#
199# Usage:
200#
201# snmp_sysbulk($path_to_snmpbulkget,$host,$community,$OIDs,$nums);
202#
203# syscall: snmpbulkget $host $community with all $OIDs permutated
204# with all $nums
205#
206# $nums refers to the last part of the OIDs.
207#
208# $OIDs and $nums have to be given space-separated.
209#
210sub snmp_sysbulk {
211 my ($binpath,$host,$community,$OIDs,$nums)=@_;
212 my $query="";
213 my @OIDs=split / /,$OIDs;
214 my @nums=split / /,$nums;
215 my $OIDcount=(@OIDs);
216 foreach $num (@nums) {
217 foreach $OID (@OIDs) {
218 $query=$query.$OID.".".$num." ";
219 }
220 }
221 my @result=`$binpath $host $community $query`;
222 
223 $num=0;
224 $count=0;
225 foreach (@result) {
226 chomp;
227 s/.* = //;
228 $num++;
229 if ($num==1) { $line=$nums[$count]; $count++ }
230 $line=$line." ".$_;
231 if ($num>=$OIDcount) {$num=0; push @results,$line;}
232 }
233 
234 return @results;
235 }
236 
237 
238######################################################################
239#
240# Query remote host via SNMP and store data in tempfile
241# snmpwalk method
242#
243# Usage:
244#
245# snmp_sysquery($path_to_snmpwalk,$host,$community,$item,@grep)
246#
247# $item: refers to the MIB you want to query ommitting the last part
248# of the OID
249#
250# @grep: an array of the OID's last parts you's like to query.
251#
252sub snmp_sysquery {
253 my ($binpath,$host,$community,$item,@grep)=@_;
254 @result=`$binpath $host $community $item`;
255 foreach $contains (@grep) {
256 foreach (grep /$contains/, @result) {
257 chomp;
258 if (/\.([0-9]*) = /, $num=$1) {
259 ($var,$value)=split / = /;
260 if (defined $lines{$num}) { $lines{$num}=$lines{$num}." $value"; } else { $lines{$num}=$value; }
261 }
262 }
263 }
264 
265 foreach $line (keys %lines) {
266 push @results,$line." ".$lines{$line};
267 }
268 
269 return @results;
270 }
271 
272######################################################################
273#
274# evaluate name of module by its subdir
275#
276# Usage:
277#
278# $modname=get_module_name();
279#
280sub get_module_name {
281 my $pwd=uc `pwd`;
282 chomp $pwd;
283 my (undef,$name)=split /MODULES\//,$pwd;
284 return $name;
285}
286 
287 
288######################################################################
289#
290# strip unwanted chars like " and multiple spaces at end / beginning
291# of each element and return the processed array.
292#
293# Usage:
294#
295# $stripped_string=strip_unwanted($raw_string);
296#
297sub strip_unwanted {
298 foreach (@_) {
299 $_ =~ s/ *= */=/g; # spaces near a =
300 $_ =~ s/\"//g; # " chars
301 $_ =~ s/ +/ /g; # multiple spaces to single
302 $_ =~ s/^ *//g; # spaces at beginning
303 $_ =~ s/ *$//g; # spaces at end
304 }
305 return @_;
306 }
307 
308 
309######################################################################
310#
311# Parse a line, strip all unwanted chars, split it by "=" into
312# a VAR and a VALUE part and make sure those parts are defined.
313#
314# Usage:
315#
316# ($var,$value,$comment)=parse_line($settings_line);
317#
318sub parse_line {
319 my ($line)=@_;
320 chomp $line;
321 
322# remove leading spaces
323 $line =~ s/^ *//g;
324 
325# weed out comments (i.e. everything following a "#"
326 my ($important,$comment)=split /#/,$line,2;
327 if ((! defined $comment) || ( $comment eq "" )) {
328 if (index($line,"#")>=0) { $comment=" "; }
329 else { $comment=""; }
330 }
331 if ((! defined $important) || ($important eq "")) { return ("","",$comment); }
332 
333# trim the edges ;)
334 ($important)=strip_unwanted($important);
335 
336# separate the variable name from its assigned value
337 my ($var,$value)=split /=/,$important,2;
338 
339# avoid undefined variables
340 $var="" if (! defined $var);
341 $value="" if (! defined $value);
342 
343# force varnames to be upcase
344 $var=uc $var;
345 
346 return ($var,$value,$comment)
347}
348 
349 
350######################################################################
351#
352# evaluate settings file and check config...
353#
354# Usage:
355#
356# %config=get_config($path_to_settings_file);
357#
358sub get_config {
359 my ($location)=@_;
360 my ($var,$value,$BINPATH,$DAEMONDIR,$LOGDIR,$PIDFILE,$DTIME,$CTIME,$STIME,$WEBDIR,$ORDER,$LOGSIZE,$LOGBACKUPS);
361 
362 my @lines=read_settings($location);
363 foreach (@lines) {
364 ($var,$value)=parse_line($_);
365 $config{$var}=$value;
366 }
367 
368 # sanity check for all config variables
369 #
370 $config{"BINPATH"}=check_config_item("BINPATH","path","","","path to \"rrdtool\"",%config);
371 $config{"DAEMONDIR"}=check_config_item("DAEMONDIR","path","","","path to \"HotSaNIC\"",%config);
372 $config{"WEBDIR"}=check_config_item("WEBDIR","path","","","path to HotSaNIC's output directory",%config);
373 $config{"LOGDIR"}=check_config_item("LOGDIR","path","\$DAEMONDIR/log","","path to HotSaNIC's logfiles",%config);
374 $config{"PIDFILE"}=check_config_item("PIDFILE","var","\$DAEMONDIR/log/rrdtimer.pid","","path to HotSaNIC's PID file",%config);
375 $config{"DTIME"}=60*check_config_item("DTIME","var","15","minutes","diagram rebuild time",%config);
376 $config{"CTIME"}=3600*check_config_item("CTIME","var","12","hours","diagram conversion time",%config);
377 $config{"STIME"}=check_config_item("STIME","var","120","seconds","module scan time",%config);
378 $config{"LOGSIZE"}=check_config_item("LOGSIZE","var","500000","bytes","max. logfile size",%config);
379 $config{"LOGBACKUPS"}=check_config_item("LOGBACKUPS","var","4","","logfiles to keep as backups",%config);
380 $config{"IMAGEFORMAT"}=check_config_item("IMAGEFORMAT","var","gif","","format of generated pictures",%config);
381 $config{"ORDER"}=check_config_item("ORDER","var","","","order of modules",%config);
382 $config{"DEBUGLEVEL"}=check_config_item("DEBUGLEVEL","var","-1","","debug level",%config);
383 
384 return %config;
385 }
386 
387 
388######################################################################
389#
390# read settings-file and strip comments and empty entries
391#
392# Usage:
393#
394# @parsed_config=read_settings($path_to_settings_file,$module_name);
395#
396# returns just the lines actually containing data - stripped by comments.
397#
398sub read_settings {
399 my ($location,$modname)=@_;
400 if (!defined $modname) {
401 $modname="rrdtimer";
402 $error="Configuration file \"settings\" missing in HotSaNIC's main directory. Probably you have to run setup.pl first.\n";
403 }
404 else { $error="Configuration file \"settings\" missing in module.\n"; }
405 if ( (! defined $location) || ($location eq "")) { $location="."; }
406 open CONF,"$location/settings" or dupe_control("die",$modname,$error);
407 while (<CONF>) {
408 chomp;
409 next if $_ eq "";
410 my ($important,$comment)=split /#/;
411 if ((defined $important) && ( index($important,"=") >= 0)) {
412 push @config,$important
413 }
414 }
415 close CONF;
416 
417 return @config;
418 }
419 
420 
421######################################################################
422#
423# sanity check config-item
424#
425# Usage:
426#
427# $value=check_config_item($item_name,$type,$default_value,$unit,$description,%config_hash);
428#
429# $type:
430# "path" -> assume that value is a path -> check its existence.
431# "var" -> assume that value is a variable -> check if the value is set correctly.
432#
433# if a fatal config-error is detected, the program dies with an error.
434#
435sub check_config_item {
436 my ($name,$type,$default,$unit,$description,%confhash)=@_;
437 
438 my $DAEMONDIR=$confhash{"DAEMONDIR"};
439 my $var=$confhash{$name};
440 
441 if (defined $var) { $var=~ s/\$DAEMONDIR/$DAEMONDIR/g; }
442 
443 if ($type eq "path") {
444 if ((! defined $var) || ($var eq "")) {
445 print $name," (",$description,") not configured.\n";
446 if ($default eq "") { print "no default value given.\n"; exit 1; }
447 else { print "using default value: ",$default," ",$unit,"\n"; ($var=$default)=~ s/\$DAEMONDIR/$DAEMONDIR/g; }
448 }
449 if ( ! -e $var) { print $name," (",$description,") does not exist.\n"; exit 1; }
450 }
451 
452 if ($type eq "var") {
453 if ((! defined $var) || ($var eq "")) {
454 print $name," (",$description,") not configured.\n";
455 if ($default eq "") { print "no default value given.\n"; exit 1; }
456 else { print "using default value: ",$default," ",$unit,"\n"; $var=$default; }
457 }
458 }
459 return $var;
460 }
461 
462 
463######################################################################
464#
465# identify OS type
466#
467# Usage:
468#
469# $ostype=identify_os_type();
470#
471sub identify_os_type {
472 my $os=`uname`;
473 chomp $os;
474 return $os;
475 }
476 
477######################################################################
478#
479# convert - converts GB/MB/KB into Bytes
480#
481# Usage:
482#
483# @out=convert_units(@in);
484#
485# all values in @in will be checked against existance of a SI-multiplier
486# (K, M or G) and the value stored in @out are multiplied accordingly.
487#
488sub convert_units {
489 my @in = @_;
490 my @out = ();
491 
492 foreach $i (@in) {
493 $i =~ s/(^\d+)K/$1 * 1024/;
494 $i =~ s/(^\d+)M/$1 * 1024 * 1024/;
495 $i =~ s/(^\d+)G/$1 * 1024 * 1024 * 1024/;
496 #print "$i\n";
497 $bytes = (eval "$i");
498 #print "$bytes\n";
499 push @out, $bytes;
500 }
501 return @out;
502}
503 
5041;
505 

Powered by WebSVN 2.2.1