Why does USR1 seem to kill Perl, instead of recreating the logfile?
I have a Perl script that I've added logging to, courtesy of Log4perl.
The script itself is long-running, and we also need to do log-rotation/archiving on a daily basis.
I've opted to use the inbuilt Solaris logadm
, rather than using Log::Dispatch::FileRotate, because
- we're trying to reduce the number of Perl dependencies we need, and
- I get the impression that doing it at the OS level, outside your app is the preferred/most robust approach.
As part of rotation, I also need to get the Perl script to refresh its file handle. According to the Log4perl FAQ, you can configure it to listen for the USR1 signal, and recreate the file handles on that:
log4perl.rootLogger = DEBUG, INFOLOG, DEBUGLOG
log4perl.appender.INFOLOG = Log::Log4perl::Appender::File
log4perl.appender.INFOLOG.filename = myprogram.info.log
log4perl.appender.INFOLOG.mode = append
log4perl.appender.INFOLOG.recreate = 1
log4perl.appender.INFOLOG.recreate_check_signal = USR1
log4perl.appender.INFOLOG.layout = Log::Log4perl::Layout::PatternLayout
log4perl.appender.INFOLOG.layout开发者_如何学Python.ConversionPattern = %d [%p] (%F line %L) %m%n
log4perl.appender.INFOLOG.Threshold = INFO
log4perl.appender.DEBUGLOG = Log::Log4perl::Appender::File
log4perl.appender.DEBUGLOG.filename = myprogram.debug.log
log4perl.appender.DEBUGLOG.mode = append
log4perl.appender.INFOLOG.recreate = 1
log4perl.appender.INFOLOG.recreate_check_signal = USR1
log4perl.appender.DEBUGLOG.layout = Log::Log4perl::Layout::PatternLayout
log4perl.appender.DEBUGLOG.layout.ConversionPattern = %d [%p] (%F line %L) %m%n
However, for some reason, whenever I send the USR1 signal to the Perl process, my Perl script simply exits.
I'm sending it with:
kill -s USR1 <pid>
As soon as I do that, the Perl process seems to die. This happens whether I've configured Log4perl to capture USR1 or not.
I also tried using USR2, same effect.
Is there something obvious I'm missing here, either in Log4perl, or in Perl or Solaris?
In your second set of configuration for DEBUGLOG, you still have INFOLOG, but that shouldn't prevent the first from catching the signal. As suggested above, you may want to try a small example like below with your configuration:
# Your Log4perl config
Log::Log4perl::init( \$conf );
my $log = Log::Log4perl::get_logger("Foo::Bar");
while (1){
$log->info("Important Info!");
sleep 5;
}
If that works (did for me running on a Mac), then your system is sending the signals correctly and it's not Solaris. Then you can focus on what other code might be messing with the signal.
精彩评论