![]() ![]() |
hotsanic |
Subversion Repositories: |
Compare with Previous - Blame - Download
## $Id: HotSaNIC.pm,v 1.2 2002/11/24 18:50:06 tinheap Exp $#package HotSaNIC;use Exporter;# our ($VERSION, @ISA, @EXPORT);($VERSION = '$Revision: 1.2 $') =~ s/.*(\d+\.\d+).*/$1/;@ISA = qw(Exporter);@EXPORT = qw (snmp_sysbulksnmp_sysqueryget_module_nameget_configread_settingscheck_configstrip_unwantedidentify_os_typeparse_lineget_diagram_propertiesopt2argarg2optcheck_argsdupe_controlconvert_units);######################################################################## control function to make sure that a module is running only once## Usage:# dupe_control($what,$module-name,$message);## $what:# start -> call this method at the head of a module to touch the# dupe-detection checkfile.# stop -> remove checkfile and exit normally.# warn -> print $message as warning and continue execution.# die -> remove checkfile and stop process with error.## The given message will be preceded with a timestamp (in seconds# since 1970) and the module-name:## <time> MODULE:message\n#sub dupe_control {my ($what,$mod,$message)=@_;if (!defined $mod) { $mod=get_module_name(); }if (!defined $message) { $message="(unknown reason)"; }if ($what eq "start") {if (-e "running.dat") {open FILE,"running.dat";$pid=<FILE>;close FILE;chomp $pid;if ((defined $pid) && ($pid ne "") && (-e "/proc/$pid")) {open FILE,"/proc/$pid/stat";$line=<FILE>;close FILE;if( index($line,"read-data") >= 0) {@fileds=split / /,$line;$starttime=$fileds[21]/100;open FILE,"/proc/uptime";$line=<FILE>;close FILE;($uptime)=split / /,$line;$delta=int(($uptime-$starttime)*100)/100;if ( ($uptime-$starttime) > 3600) {print time," ",$mod,": process running >1 hour --> KILLING!\n";system "kill -9 $pid";}else {print time," ",$mod,": process already running on PID $pid for $delta seconds.\n";exit 1;}}}}open FILE,">running.dat";print FILE $$;close FILE;}elsif ($what eq "stop") {if (-e "running.dat") { unlink "running.dat"; }exit 0;}elsif ($what eq "die") {if (-e "running.dat") { unlink "running.dat"; }die time." ".$mod.": ".$message."\n";}elsif ($what eq "warn") {print time," ",$mod," warn: ",$message,"\n";}else { print time," ",$mod," method \"",$what,"\" not supported.\n"; }}######################################################################## checks if all necessary arguments are given in the corosponding# hash. If not, try to reconstruct them or to set defaults.## Usage:# %arguments=check_args(%arguments);#sub check_args {($check,%ARGS)=@_;foreach $value (split /,/,$check) {if ( (!defined $ARGS{$value}) || ($ARGS{$value} eq "") || ($ARGS{$value} eq "not configured") ) {if ($value eq "MODNAME") { $ARGS{$value}=get_module_name(); }if ($value eq "DEBUGLEVEL") { $ARGS{$value}=-1; }if ($value eq "OSTYPE") { $ARGS{$value}=identify_os_type(); }if ($value eq "SNMPWALK") {my @found=grep /snmpwalk$/, `locate bin\/snmpwalk`;if (@found) { $found=$found[0];chomp $found; $result=" Found: ".$found; $ARGS{$value}=$found; } else { $ARGS{$value}="echo >/dev/null"; }dupe_control("warn",$ARGS{"MODNAME"},"SNMPWALK not given on commandline! $result");}if ($value eq "SNMPGET") {my @found=grep /snmpget$/, `locate bin\/snmpget`;if (@found) { $found=$found[0];chomp $found; $result=" Found: ".$found; $ARGS{$value}=$found; } else { $ARGS{$value}="echo >/dev/null"; }dupe_control("warn",$ARGS{"MODNAME"},"SNMPGET not given on commandline! $result");}}}return %ARGS;}######################################################################## converts an option-hash to cmdline argument string which can be# passed to a module script## Usage:# $commandline_args=opt2arg(%options);#sub opt2arg {my $line="";my %opts=@_;foreach $var (keys(%opts)) {if (index("DEBUGLEVEL MODNAME OSTYPE SNMPWALK SNMPGET",$var) >= 0) {$line=$line." ".$var."=\"".$opts{$var}."\"";}}if ($opts{"DEBUGLEVEL"}>=0) { print "CLIENT-LINE: $line\n" };return $line;}######################################################################## converts cmdline arguments array to an options-hash## Usage:# %options=arg2opt($commandline_args)#sub arg2opt {my %HASH;foreach $pair (@_) {($var,$value)=split /=/, $pair;$HASH{$var}=$value;}if (! defined $HASH{"MODNAME"}) { $HASH{"MODNAME"}=get_module_name(); }if (! defined $HASH{"OSTYPE"}) { $HASH{"OSTYPE"}=`uname`; chomp $HASH{"OSTYPE"}; }if (! defined $HASH{"DEBUGLEVEL"}) { $HASH{"DEBUGLEVEL"}=-1; }if ($HASH{"DEBUGLEVEL"} >=6 ) {print "\n";foreach (keys %HASH) { printf " %-15s %s\n",$_,$HASH{$_}; }}return %HASH;}######################################################################## evaluates some diagram properties from the given range## Usage:# ($description,$file_description,$build_interval,$diagram_range)=get_diagram_properties($range);#sub get_diagram_properties {my ($range)=@_;my ($descr,$file,$build,$fullrange);if ($range eq "1h") { $descr="hour"; $file=$descr; $build=0; $fullrange=3600; }elsif ($range eq "6h") { $descr="6 hours"; $file="6h"; $build=30; $fullrange=21600; }elsif ($range eq "1day") { $descr="day"; $file=$descr; $build=120; $fullrange=86400; }elsif ($range eq "1week") { $descr="week"; $file=$descr; $build=1000; $fullrange=604800; }elsif ($range eq "1month") { $descr="month"; $file=$descr; $build=4300; $fullrange=2592000; }elsif ($range eq "1year") { $descr="year"; $file=$descr; $build=52500; $fullrange=31536000; }return ($descr,$file,$build,$fullrange);}######################################################################## Query remote host via SNMP and store data in tempfile# GetBulk method## Usage:## snmp_sysbulk($path_to_snmpbulkget,$host,$community,$OIDs,$nums);## syscall: snmpbulkget $host $community with all $OIDs permutated# with all $nums## $nums refers to the last part of the OIDs.## $OIDs and $nums have to be given space-separated.#sub snmp_sysbulk {my ($binpath,$host,$community,$OIDs,$nums)=@_;my $query="";my @OIDs=split / /,$OIDs;my @nums=split / /,$nums;my $OIDcount=(@OIDs);foreach $num (@nums) {foreach $OID (@OIDs) {$query=$query.$OID.".".$num." ";}}my @result=`$binpath $host $community $query`;$num=0;$count=0;foreach (@result) {chomp;s/.* = //;$num++;if ($num==1) { $line=$nums[$count]; $count++ }$line=$line." ".$_;if ($num>=$OIDcount) {$num=0; push @results,$line;}}return @results;}######################################################################## Query remote host via SNMP and store data in tempfile# snmpwalk method## Usage:## snmp_sysquery($path_to_snmpwalk,$host,$community,$item,@grep)## $item: refers to the MIB you want to query ommitting the last part# of the OID## @grep: an array of the OID's last parts you's like to query.#sub snmp_sysquery {my ($binpath,$host,$community,$item,@grep)=@_;@result=`$binpath $host $community $item`;foreach $contains (@grep) {foreach (grep /$contains/, @result) {chomp;if (/\.([0-9]*) = /, $num=$1) {($var,$value)=split / = /;if (defined $lines{$num}) { $lines{$num}=$lines{$num}." $value"; } else { $lines{$num}=$value; }}}}foreach $line (keys %lines) {push @results,$line." ".$lines{$line};}return @results;}######################################################################## evaluate name of module by its subdir## Usage:## $modname=get_module_name();#sub get_module_name {my $pwd=uc `pwd`;chomp $pwd;my (undef,$name)=split /MODULES\//,$pwd;return $name;}######################################################################## strip unwanted chars like " and multiple spaces at end / beginning# of each element and return the processed array.## Usage:## $stripped_string=strip_unwanted($raw_string);#sub strip_unwanted {foreach (@_) {$_ =~ s/ *= */=/g; # spaces near a =$_ =~ s/\"//g; # " chars$_ =~ s/ +/ /g; # multiple spaces to single$_ =~ s/^ *//g; # spaces at beginning$_ =~ s/ *$//g; # spaces at end}return @_;}######################################################################## Parse a line, strip all unwanted chars, split it by "=" into# a VAR and a VALUE part and make sure those parts are defined.## Usage:## ($var,$value,$comment)=parse_line($settings_line);#sub parse_line {my ($line)=@_;chomp $line;# remove leading spaces$line =~ s/^ *//g;# weed out comments (i.e. everything following a "#"my ($important,$comment)=split /#/,$line,2;if ((! defined $comment) || ( $comment eq "" )) {if (index($line,"#")>=0) { $comment=" "; }else { $comment=""; }}if ((! defined $important) || ($important eq "")) { return ("","",$comment); }# trim the edges ;)($important)=strip_unwanted($important);# separate the variable name from its assigned valuemy ($var,$value)=split /=/,$important,2;# avoid undefined variables$var="" if (! defined $var);$value="" if (! defined $value);# force varnames to be upcase$var=uc $var;return ($var,$value,$comment)}######################################################################## evaluate settings file and check config...## Usage:## %config=get_config($path_to_settings_file);#sub get_config {my ($location)=@_;my ($var,$value,$BINPATH,$DAEMONDIR,$LOGDIR,$PIDFILE,$DTIME,$CTIME,$STIME,$WEBDIR,$ORDER,$LOGSIZE,$LOGBACKUPS);my @lines=read_settings($location);foreach (@lines) {($var,$value)=parse_line($_);$config{$var}=$value;}# sanity check for all config variables#$config{"BINPATH"}=check_config_item("BINPATH","path","","","path to \"rrdtool\"",%config);$config{"DAEMONDIR"}=check_config_item("DAEMONDIR","path","","","path to \"HotSaNIC\"",%config);$config{"WEBDIR"}=check_config_item("WEBDIR","path","","","path to HotSaNIC's output directory",%config);$config{"LOGDIR"}=check_config_item("LOGDIR","path","\$DAEMONDIR/log","","path to HotSaNIC's logfiles",%config);$config{"PIDFILE"}=check_config_item("PIDFILE","var","\$DAEMONDIR/log/rrdtimer.pid","","path to HotSaNIC's PID file",%config);$config{"DTIME"}=60*check_config_item("DTIME","var","15","minutes","diagram rebuild time",%config);$config{"CTIME"}=3600*check_config_item("CTIME","var","12","hours","diagram conversion time",%config);$config{"STIME"}=check_config_item("STIME","var","120","seconds","module scan time",%config);$config{"LOGSIZE"}=check_config_item("LOGSIZE","var","500000","bytes","max. logfile size",%config);$config{"LOGBACKUPS"}=check_config_item("LOGBACKUPS","var","4","","logfiles to keep as backups",%config);$config{"IMAGEFORMAT"}=check_config_item("IMAGEFORMAT","var","gif","","format of generated pictures",%config);$config{"ORDER"}=check_config_item("ORDER","var","","","order of modules",%config);$config{"DEBUGLEVEL"}=check_config_item("DEBUGLEVEL","var","-1","","debug level",%config);return %config;}######################################################################## read settings-file and strip comments and empty entries## Usage:## @parsed_config=read_settings($path_to_settings_file,$module_name);## returns just the lines actually containing data - stripped by comments.#sub read_settings {my ($location,$modname)=@_;if (!defined $modname) {$modname="rrdtimer";$error="Configuration file \"settings\" missing in HotSaNIC's main directory. Probably you have to run setup.pl first.\n";}else { $error="Configuration file \"settings\" missing in module.\n"; }if ( (! defined $location) || ($location eq "")) { $location="."; }open CONF,"$location/settings" or dupe_control("die",$modname,$error);while (<CONF>) {chomp;next if $_ eq "";my ($important,$comment)=split /#/;if ((defined $important) && ( index($important,"=") >= 0)) {push @config,$important}}close CONF;return @config;}######################################################################## sanity check config-item## Usage:## $value=check_config_item($item_name,$type,$default_value,$unit,$description,%config_hash);## $type:# "path" -> assume that value is a path -> check its existence.# "var" -> assume that value is a variable -> check if the value is set correctly.## if a fatal config-error is detected, the program dies with an error.#sub check_config_item {my ($name,$type,$default,$unit,$description,%confhash)=@_;my $DAEMONDIR=$confhash{"DAEMONDIR"};my $var=$confhash{$name};if (defined $var) { $var=~ s/\$DAEMONDIR/$DAEMONDIR/g; }if ($type eq "path") {if ((! defined $var) || ($var eq "")) {print $name," (",$description,") not configured.\n";if ($default eq "") { print "no default value given.\n"; exit 1; }else { print "using default value: ",$default," ",$unit,"\n"; ($var=$default)=~ s/\$DAEMONDIR/$DAEMONDIR/g; }}if ( ! -e $var) { print $name," (",$description,") does not exist.\n"; exit 1; }}if ($type eq "var") {if ((! defined $var) || ($var eq "")) {print $name," (",$description,") not configured.\n";if ($default eq "") { print "no default value given.\n"; exit 1; }else { print "using default value: ",$default," ",$unit,"\n"; $var=$default; }}}return $var;}######################################################################## identify OS type## Usage:## $ostype=identify_os_type();#sub identify_os_type {my $os=`uname`;chomp $os;return $os;}######################################################################## convert - converts GB/MB/KB into Bytes## Usage:## @out=convert_units(@in);## all values in @in will be checked against existance of a SI-multiplier# (K, M or G) and the value stored in @out are multiplied accordingly.#sub convert_units {my @in = @_;my @out = ();foreach $i (@in) {$i =~ s/(^\d+)K/$1 * 1024/;$i =~ s/(^\d+)M/$1 * 1024 * 1024/;$i =~ s/(^\d+)G/$1 * 1024 * 1024 * 1024/;#print "$i\n";$bytes = (eval "$i");#print "$bytes\n";push @out, $bytes;}return @out;}1;