From: Kevin G. <ke...@go...> - 2003-08-05 18:07:02
|
That's a pretty neat idea, go for it, dude! msc...@ao... wrote: > Hey, > > just had an idea: How about if we add functionality to init_and_watch in Log::Log4perl to not only watch config files but to also be able to listen to (Unix) signals instead? Yeah, yeah, I know signals are unreliable and can cause all kinds of crazy stuff -- but how about if we have the signal handler just set a global variable, which is checked by the watcher code instead of calling time() all the time? > Please take a look at the patch below, and let me know what you think ... the addtl. syntax is: > > init_and_watch($file, 'HUP'); # will listen to SIGHUP > > I've also attached a test file. > > -- Mike > > ############################ > # Mike Schilli # > # log...@pe... # > # http://perlmeister.com # > # log4perl.sourceforge.net # > ############################ > > > ------------------------------------------------------------------------ > > Index: lib/Log/Log4perl/Config.pm > =================================================================== > RCS file: /cvsroot/log4perl/Log-Log4perl/lib/Log/Log4perl/Config.pm,v > retrieving revision 1.52 > diff -a -u -r1.52 Config.pm > --- lib/Log/Log4perl/Config.pm 20 Jul 2003 20:24:18 -0000 1.52 > +++ lib/Log/Log4perl/Config.pm 4 Aug 2003 04:47:28 -0000 > @@ -45,10 +45,16 @@ > sub init_and_watch { > ########################################### > my ($class, $config, $delay) = @_; > + # delay can be a signal name - in this case we're gonna > + # set up a signal handler. > > if(defined $WATCHER) { > $config = $WATCHER->file(); > - $delay = $WATCHER->check_interval(); > + if(defined $Log::Log4perl::Config::Watch::SIGNAL_CAUGHT) { > + $delay = $WATCHER->signal(); > + } else { > + $delay = $WATCHER->check_interval(); > + } > } > > print "init_and_watch ($config-$delay). Resetting.\n" if DEBUG; > @@ -57,8 +63,6 @@ > > defined ($delay) or $delay = $DEFAULT_WATCH_DELAY; > > - $delay =~ /\D/ && die "illegal non-numerical value for delay: $delay"; > - > if (ref $config) { > die "Log4perl can only watch a file, not a string of " . > "configuration information"; > @@ -66,10 +70,17 @@ > die "Log4perl can only watch a file, not a url like $config"; > } > > - $WATCHER = Log::Log4perl::Config::Watch->new( > - file => $config, > - check_interval => $delay, > - ); > + if($delay =~ /\D/) { > + $WATCHER = Log::Log4perl::Config::Watch->new( > + file => $config, > + signal => $delay, > + ); > + } else { > + $WATCHER = Log::Log4perl::Config::Watch->new( > + file => $config, > + check_interval => $delay, > + ); > + } > > _init($class, $config); > } > Index: lib/Log/Log4perl/Logger.pm > =================================================================== > RCS file: /cvsroot/log4perl/Log-Log4perl/lib/Log/Log4perl/Logger.pm,v > retrieving revision 1.55 > diff -a -u -r1.55 Logger.pm > --- lib/Log/Log4perl/Logger.pm 4 Aug 2003 02:37:35 -0000 1.55 > +++ lib/Log/Log4perl/Logger.pm 4 Aug 2003 04:47:30 -0000 > @@ -292,13 +292,14 @@ > > if (defined $Log::Log4perl::Config::WATCHER) { > > - $watch_code = <<'EOL'; > - my($logger, $subname) = @_; > - if(time() > $Log::Log4perl::Config::Watch::NEXT_CHECK_TIME and > - $Log::Log4perl::Config::WATCHER->change_detected()) { > + my $cond = generate_watch_conditional(); > + > + $watch_code = <<EOL; > + my(\$logger, \$subname) = \@_; > + if($cond) { > Log::Log4perl->init_and_watch(); > # Forward call to new configuration > - return $logger->$subname(); > + return \$logger->\$subname(); > } > EOL > } > @@ -317,20 +318,36 @@ > ################################################## > print "generate_watch_code:\n" if DEBUG; > > - return <<'EOL'; > + my $cond = generate_watch_conditional(); > + > + return <<EOL; > print "exe_watch_code:\n" if DEBUG; > > # more closures here > - if(time() > $Log::Log4perl::Config::Watch::NEXT_CHECK_TIME and > - $Log::Log4perl::Config::WATCHER->change_detected()) { > + if($cond) { > Log::Log4perl->init_and_watch(); > > - my $methodname = lc($level); > - $logger->$methodname(@_); # send the message > - # to the new configuration > + my \$methodname = lc(\$level); > + \$logger->\$methodname(\@_); # send the message > + # to the new configuration > return; #and return, we're done with this incarnation > } > EOL > +} > + > +################################################## > +sub generate_watch_conditional { > +################################################## > + > + if(defined $Log::Log4perl::Config::Watch::SIGNAL_CAUGHT) { > + # In this mode, we just check for the variable indicating > + # that the signal has been caught > + return q{$Log::Log4perl::Config::Watch::SIGNAL_CAUGHT}; > + } > + > + # In this mode, we check if the config file has been modified > + return q{time() > $Log::Log4perl::Config::Watch::NEXT_CHECK_TIME > + and $Log::Log4perl::Config::WATCHER->change_detected()}; > } > > ################################################## > Index: lib/Log/Log4perl/Config/Watch.pm > =================================================================== > RCS file: /cvsroot/log4perl/Log-Log4perl/lib/Log/Log4perl/Config/Watch.pm,v > retrieving revision 1.3 > diff -a -u -r1.3 Watch.pm > --- lib/Log/Log4perl/Config/Watch.pm 20 Jul 2003 20:24:01 -0000 1.3 > +++ lib/Log/Log4perl/Config/Watch.pm 4 Aug 2003 04:47:30 -0000 > @@ -8,6 +8,7 @@ > use constant DEBUG => 0; > > our $NEXT_CHECK_TIME; > +our $SIGNAL_CAUGHT; > > ########################################### > sub new { > @@ -16,6 +17,7 @@ > > my $self = { file => "", > check_interval => 30, > + signal => undef, > %options, > _last_checked_at => 0, > _last_timestamp => 0, > @@ -23,8 +25,15 @@ > > bless $self, $class; > > - # Just called to initialize > - $self->change_detected(); > + if($self->{signal}) { > + # We're in signal mode, set up the handler > + $SIG{$self->{signal}} = sub { $SIGNAL_CAUGHT = 1; }; > + # Reset the marker. The handler is going to modify it. > + $SIGNAL_CAUGHT = 0; > + } else { > + # Just called to initialize > + $self->change_detected(); > + } > > return $self; > } > @@ -35,6 +44,14 @@ > my($self) = @_; > > return $self->{file}; > +} > + > +########################################### > +sub signal { > +########################################### > + my($self) = @_; > + > + return $self->{signal}; > } > > ########################################### -- Happy Trails . . . Kevin M. Goess (and Anne and Frank) 904 Carmel Ave. Albany, CA 94706 (510) 525-5217 |