#!/usr/bin/env perl # $Id: rrdtimer.pl,v 1.17 2004/07/11 22:39:38 bernisys Exp $ # include PERL libraries use strict; use warnings; use diagnostics; use FindBin; use lib $FindBin::RealBin; # use Getopt::Long; # include HotSaNIC libraries use lib "./lib"; use HotSaNICparser; use HotSaNIClog; # let all outputs be flushed directly $|=1; # set commandline correctly $0="rrdtimer"; HotSaNIClog::set_modulename("rrdtimer"); (my $CALLDIR=$FindBin::RealBin) =~ s/\/rrdtimer//g; (my $VERSION = '$Revision: 1.17 $') =~ s/.*(\d+\.\d+).*/$1/; (my $IDENTIFIER = '$Id: rrdtimer.pl,v 1.17 2004/07/11 22:39:38 bernisys Exp $') =~ s/.*,v (.*) \$/$1/; HotSaNIClog::info("reading & checking config ($CALLDIR/settings) ..."); my %CONFIG=HotSaNICparser::get_config($CALLDIR); $CONFIG{MODULEDIR}=$CONFIG{DAEMONDIR}."/modules"; $CONFIG{SCHEDULED}=1; HotSaNIClog::set_timestamping($CONFIG{TIMESTAMPING}); my ($debuglevel,$runmode)=check_for_args(@ARGV); $CONFIG{DEBUGLEVEL}=HotSaNIClog::get_debuglevel($CONFIG{DEBUGLEVEL}); $CONFIG{DEBUGLEVEL} |= $debuglevel; HotSaNIClog::set_debuglevel($CONFIG{DEBUGLEVEL}); if (HotSaNIClog::check_debuglevel("MAIN_CONFIG")) { foreach my $k (keys %CONFIG) { HotSaNIClog::info("configuration -> $k=$CONFIG{$k}"); }} if ($runmode < 128) { exit 0; } my $PID=HotSaNICparser::get_pid($CONFIG{PIDFILE},"rrdtimer"); if ( $PID>0 ) { HotSaNIClog::error("Another process is running on PID $PID - daemon stopped."); exit 1; } my $debug=""; if (($runmode&1)>0) { HotSaNIClog::info("Debug mode enabled!"); HotSaNIClog::info("Identifier: $IDENTIFIER"); HotSaNIClog::info("Logdir: $CONFIG{LOGDIR}"); HotSaNIClog::info("PID-file: $CONFIG{PIDFILE}"); $debug="d"; } my @PIDs=(); daemonize(); $SIG{TERM} = \&signalhandler; $SIG{HUP} = \&signalhandler; $SIG{USR1} = \&signalhandler; $SIG{USR2} = \&signalhandler; main_loop(); ###################################################################### # # # SUBROUTINES BEGIN HERE # # # ###################################################################### ###################################################################### # # signal-handler # TERM -> terminate daemon and modules # HUP -> re-configure # USR1 -> kill daemon only # USR2 -> kill modules only # sub signalhandler { my ($sig)=@_; HotSaNIClog::info("$sig received."); if (defined $sig) { if (($sig eq "TERM") || ($sig eq "USR2")) { HotSaNIClog::info("Stopping all running modules."); if (@PIDs) { kill "TERM", @PIDs; @PIDs=(); } } if (($sig eq "TERM") || ($sig eq "USR1")) { HotSaNIClog::info("Daemon exiting normally."); if (-e $CONFIG{PIDFILE}) { unlink $CONFIG{PIDFILE}; HotSaNIClog::info("PID-file removed."); } close STDIN; close STDOUT; close STDERR; exit 0; } if ($sig eq "HUP") { HotSaNIClog::info("reconfiguring myself..."); %CONFIG=HotSaNICparser::get_config($CALLDIR); $CONFIG{MODULEDIR}=$CONFIG{DAEMONDIR}."/modules"; $CONFIG{SCHEDULED}=1; # TODO: # # - kill unused modules # - start configured modules (if necessary) # - re-configure all modules # } } } ###################################################################### # # the main loop executes all timed scripts: # # signal modules/*/read-data every 10 sec. (hardcoded) # modules/*/diagrams every $DTIME # convert() every $CTIME if $CONVERTMETHOD is other than "HTML" # scan_for_modules() every $STIME # sub main_loop { my @modules=(); my %MODULES=(); my $now=time; my $lastscan=0; # scan for modules directly after being started my $lastdiagram=$now-$CONFIG{DTIME}+30; # generate all diagrams 30 sec. after start my $lastconvert=$now-$CONFIG{CTIME}+300; # build thumbnails 5 minutes after start call_script($CONFIG{DAEMONDIR},"makeindex.pl",0,$CONFIG{LOGDIR}."/makeindex.log",0); while () { $now=time; # BUG: sometimes after HUP'ing the @PIDs array contains undefined values if (HotSaNIClog::check_debuglevel("MAIN_HEARTBEAT")) { HotSaNIClog::info("main loop running"); } # Tell modules to sample data. We do this BEFORE starting any module to avoid # too small sample intervals. At start time @PIDs is empty so this code won't # be executed until some modules are started. # if (@PIDs) { if (HotSaNIClog::check_debuglevel("MAIN_SIGNAL")) { HotSaNIClog::info("signaling PIDs: ".join(" ",@PIDs)); } # When no schedule time was configured, signal ALL modules in PARALLEL (may produce high load!) # Otherwhise serialize the signalling a bit. # if ($CONFIG{SCHEDULED} == 0) { kill "SIGUSR1", @PIDs; } else { foreach (@PIDs) { if (defined $_) { kill "SIGUSR1", $_; my $wait=int($CONFIG{SCHEDULE_MIN}+rand($CONFIG{SCHEDULE_MAX}-$CONFIG{SCHEDULE_MIN}))/1000; if (HotSaNIClog::check_debuglevel("MAIN_SIGNAL_VERBOSE")) { HotSaNIClog::info("\"$MODULES{$_}\" called, sleeping $wait sec."); } select(undef,undef,undef,$wait); } } } } # scan for modules and (re-)start them if necessary # if ($lastscan+$CONFIG{STIME} <= $now) { @modules=HotSaNICparser::scan_for_modules($CONFIG{MODULEDIR},$CONFIG{RUN}); %MODULES=call_modules(@modules); @PIDs=keys(%MODULES); $lastscan=int($now/$CONFIG{STIME})*$CONFIG{STIME}; if ($debug ne "d") { logrotate(); } } # check if diagrams have to be built. # if ($lastdiagram+$CONFIG{DTIME} <= $now) { my $append; if ($CONFIG{DIAGRAMLOG} eq "all") { $append=1; } call_script($CONFIG{DAEMONDIR},"diagrams.pl",5,$CONFIG{LOGDIR}."/diagram.log",$append); $lastdiagram=int($now/$CONFIG{DTIME})*$CONFIG{DTIME}; } # check if thumbnails have to be generated. # if (($lastconvert+$CONFIG{CTIME} <= $now) && ($CONFIG{CONVERTMETHOD} ne "HTML")) { call_script($CONFIG{DAEMONDIR},"convert.pl",0,$CONFIG{LOGDIR}."/convert.log",0); $lastconvert=int($now/$CONFIG{CTIME})*$CONFIG{CTIME}; } # sleep until system time's next full 10 seconds # my $sleeptime=10-(time % 10); sleep $sleeptime; } } ###################################################################### # # start read-data.pl script in each module # sub call_modules { my (@modules)=@_; my %MODULES; my $nicelevel="0"; my $have_started=0; if (HotSaNIClog::check_debuglevel("MAIN_SCAN_MODULES")) { HotSaNIClog::info("Checking modules..."); } # iterate through all configured modules... # for my $module (@modules) { my $verbose=0; if (HotSaNIClog::check_debuglevel("MAIN_SCAN_MODULES_VERBOSE")) { $verbose=1; } chdir $CONFIG{MODULEDIR}."/$module"; my $PID=HotSaNICparser::get_pid(); # if not running, start the module and wait for PID-file to be generated # if ($PID == 0) { if (HotSaNIClog::check_debuglevel("MAIN_SCAN_MODULES")) { HotSaNIClog::info("starting module \"$module\""); } if (HotSaNIClog::check_debuglevel("MAIN_SCAN_MODULES_VERBOSE")) { HotSaNIClog::info("----- begin start module \"$module\" -----"); } $verbose=1; if (-e "./running.pid") { if (HotSaNIClog::check_debuglevel("MAIN_SCAN_MODULES_VERBOSE")) { HotSaNIClog::info("removing old PID-file"); } unlink "./running.pid"; } my $EXEC=""; if (-e "./read-data-wrapper.pl") { $EXEC="nice -$nicelevel ./read-data-wrapper.pl start $module"; } elsif (-e "./read-data.pl") { $EXEC="nice -$nicelevel ./read-data.pl start $module"; } else { HotSaNIClog::error("cannot find read-data script for module \"$module\""); next; } system "$EXEC"; # wait for module writing its PID-file # my $count=0; while ( ($count<80) && (! -s "./running.pid") ) { if ($count == 0) { HotSaNIClog::info("waiting for module's PID-file"); } $count++; print "." if ($count%5 == 0); select(undef,undef,undef,0.25); } print "\r" if ($count > 0); $PID=HotSaNICparser::get_pid(); #if PID is valid -> sample for the first time after startup if ($PID > 0) { kill "SIGUSR1",$PID; } HotSaNIClog::info("----- end start module \"$module\" -----"); $have_started++; } if ($PID >0) { if ($verbose>0) { HotSaNIClog::info("\"$module\" running on PID $PID"); } $MODULES{$PID}=$module; } else { HotSaNIClog::error("PID for \"$module\" could not be determined"); } } if ($have_started>0) { HotSaNIClog::info("-" x 75); } return %MODULES; } ###################################################################### # # call external script (incl. sanity checking etc) # sub call_script { my ($path,$script,$nicelevel,$output,$append)=@_; if (! defined $append) { $append=0; } if (! defined $output) { $output=""; } if (! defined $nicelevel) { $nicelevel=0; } if ( (defined $path) && (defined $script) ) { if (HotSaNIClog::check_debuglevel("MAIN_CALL_SCRIPT")) { HotSaNIClog::info("executing \"$path/$script\" with nice $nicelevel"); } if ( -e "$path/$script") { if ($output ne "") { my $logaction="appending"; if (index("1 yes true",lc $append) < 0) { rename $output,"$output.old"; $logaction="logging"; } if (HotSaNIClog::check_debuglevel("MAIN_CALL_SCRIPT")) { HotSaNIClog::info("$logaction output to $output"); } if ($nicelevel ne 0) {system ("cd \"$path\"; nice -$nicelevel ./$script >$output 2>&1 &"); } else {system ("cd \"$path\"; ./$script >$output 2>&1 &"); } } else { if ($nicelevel ne 0) {system ("cd \"$path\"; nice -$nicelevel ./$script &"); } else {system ("cd \"$path\"; ./$script &"); } } } else { HotSaNIClog::error("script \"$path/$script\" not found! Check your installation."); } } } ###################################################################### # # fork into background # sub daemonize { use POSIX qw(setsid); HotSaNIClog::info("entering daemon mode..."); if ($debug eq "") { close STDIN; close STDOUT; close STDERR; if (open(DEVTTY, "/dev/tty")) { ioctl(DEVTTY,0x20007471,0); close DEVTTY; } open STDIN,"/dev/null"; open STDOUT,">>".$CONFIG{LOGDIR}."/HotSaNIC.log"; open STDERR,">&STDOUT"; setpgrp(0,$$); chdir "/"; fork && exit 0; setsid; HotSaNIClog::info("archiver successfully forked into background and running on PID $$"); } else { HotSaNIClog::info("archiver running in debug-mode on PID $$"); } HotSaNIClog::info("-" x 75); open FILE,">".$CONFIG{PIDFILE}; print FILE $$; close FILE; } ###################################################################### # # rotate logfiles # sub logrotate { my ($size,$file); if ($debug ne "d") { $file=$CONFIG{LOGDIR}."/HotSaNIC.log"; (undef,undef,undef,undef,undef,undef,undef,$size,undef,undef,undef,undef,undef) = stat($file); if (defined $size) { if ($size > $CONFIG{LOGSIZE}) { HotSaNIClog::info("$file exceeding $CONFIG{LOGSIZE} bytes - rotating - keeping $CONFIG{LOGBACKUPS} backups."); for (my $nn=$CONFIG{LOGBACKUPS};$nn>1;$nn--) { if ( -e "$file.$nn" ) { unlink "$file.$nn"; } if ( -e "$file.".($nn-1) ) { rename "$file.".($nn-1),"$file.".$nn; } } close STDOUT; rename $file,"$file.1"; open STDOUT,">>$file"; close STDERR; rename $file,"$file.1"; open STDERR,">>$file"; } } } } ###################################################################### # # evaluate commandline arguments # sub check_for_args { HotSaNIClog::info("evaluating cmdline arguments..."); my @args=@_; # set initial values # my $debuglevel=0; my $runmode=0; # Check if we were called with any options # foreach my $arg (@args) { if (index($arg,"d") >= 0) { $runmode|=1; } if (index($arg,"D") >= 0) { $runmode|=128; } if (index($arg,"h") >= 0) { $runmode|=256; } if (index($arg,"?") >= 0) { $runmode|=256; } $arg=~ s/[a-zA-Z]//g; if ($arg =~ /[0-9]/) { if ($arg > 0) { $debuglevel=$arg; } } } if (($runmode == 0) || ($runmode > 255)) { print "rrdtimer - CVS version $VERSION ($IDENTIFIER) - OS: $^O\n"; print "usage:\nrrdtimer [options[debuglevel]]\n options:\n"; print " D - enter daemon-mode (i.e. start the main loop)\n"; print " d - enter debugging mode (don't fork into background)\n"; print "\n"; exit 0; } return ($debuglevel,$runmode); } WebSVN - hotsanic - Blame - Rev 29 - /branches/HotSaNIC-0.5.0-pre6/rrdtimer.pl
  jablonka.czprosek.czf

hotsanic

Subversion Repositories:
[/] [branches/] [HotSaNIC-0.5.0-pre6/] [rrdtimer.pl] - Blame information for rev 29

 

Line No. Rev Author Line

Powered by WebSVN 2.2.1