LINUX.ORG.RU

#perl Помогите разобраться с юникс сигналами


0

1

Привет. Использую HTTP::Daemon. Захотелось ротировать логи и пересоздавать лог фал по, например, USR1. Я обнаружил, что демон падает в ответ на любой сигнал, собственно это и есть вопрос. Вот пример:

 
#!/usr/local/bin/perl

use HTTP::Daemon;

my $d =  HTTP::Daemon->new( Reuse => 1,
			LocalAddr => '127.0.0.1',
			LocalPort => 8081) || die "Can't start server ($@)";

print "Please contact me at: <URL:", $d->url, ">\n";

while (my $c = $d->accept) {
  $r = $c->get_request;
  if ($r) {
    $c->send_basic_header;
    $c->print("Content-Type: text/plain");
    $c->send_crlf;
    $c->send_crlf;
    $c->print("Ok\n");

  }
  $c->close;
  undef($c);
}
exit;
Перерыл много документации, сам модуль, но так и не понял, почему так происходит.


И где у тебя определение обработчика сигнала? Обработчик по умолчанию завершает программу:

$ man 7 signal | awk '/       Signal/ {print} /SIGUSR1/ {print; exit}'
       Signal     Value     Action   Comment
       SIGUSR1   30,10,16    Term    User-defined signal 1
kim-roader ★★
()
Ответ на: комментарий от kim-roader

Забыл упомянуть, для логов использую log4perl, таким образом моя проблема выгляди так:

#!/usr/local/bin/perl
use Log::Log4perl qw();
use HTTP::Daemon;

my $log_conf = "
	log4perl.logger.Main                = INFO, FileApp

	log4perl.logger.Cat        = ALL, Screen
	log4perl.logger.Cat.Subcat = WARN, Screen

	log4perl.appender.Screen   = Log::Log4perl::Appender::Screen
	log4perl.appender.Screen.layout = SimpleLayout

	log4perl.appender.FileApp           = Log::Log4perl::Appender::File
	log4perl.appender.FileApp.filename  = /var/log/test.log
	log4perl.appender.FileApp.layout.ConversionPattern = %d;%m%n
	log4perl.appender.FileApp.layout    = PatternLayout
	log4perl.appender.FileApp.recreate = 1
	log4perl.appender.FileApp.recreate_check_signal  = USR1
";

my $logger="Main";

Log::Log4perl->init(\$log_conf);
$l = Log::Log4perl->get_logger($logger);


my $d =  HTTP::Daemon->new( Reuse => 1,
			LocalAddr => '127.0.0.1',
			LocalPort => 8081) || die "Can't start server ($@)";

$l->info("Please contact me at: <URL:", $d->url, ">\n");

while (my $c = $d->accept) {
  $r = $c->get_request;
  if ($r) {
    $l->info("Important Info!");
    $c->send_basic_header;
    $c->print("Content-Type: text/plain");
    $c->send_crlf;
    $c->send_crlf;
    $c->print("Ok\n");

  }
  $c->close;
  undef($c);
}
exit;
Т.е. сигнал должен обрабатывать log4perl, что он прекрасно делает без HTTP::Daemon.

BieZax
() автор топика
Ответ на: комментарий от gh0stwizard

Что-ж все такие умные... perldoc -v '%SIG' - это первое, что я сделал. Возможно я что-то не допонял ввиду слабого английского, но решения моей проблемы там не нашел. Даже если добавить $SIG{USR1} = 'IGNORE'; - сервер падает.

BieZax
() автор топика
Ответ на: комментарий от BieZax

Что любопытно, если убрать

log4perl.appender.FileApp.recreate = 1
log4perl.appender.FileApp.recreate_check_signal  = USR1
Из конфига log4perl, и оставить
local $SIG{'USR1'} = 'IGNORE';
, то хотя бы падать перестает на USR1

BieZax
() автор топика

Похоже что в каментах уже был правильный ответ - нет user-defined-хендлера для обработки сигнала. Если не силен в английском, то хотя бы на русском почитай, литературы более чем достаточно.

outtaspace ★★★
()
Ответ на: комментарий от outtaspace

На сколько я могу судить, он есть в Log::Log4perl, и работает, если выкинуть HTTP::Daemon. По отдельности эти два модуля вообще отлично работают, а вот вместе какая-то проблема...

BieZax
() автор топика
Ответ на: комментарий от BieZax

Есть мысль, что у твоего процесса просто нет прав на создание (открытие из-за отсутсвия) файла /var/log/test.log

recreate

Normally, if a file appender logs to a file and the file gets moved to a different location (e.g. via mv), the appender's open file handle will automatically follow the file to the new location.

This may be undesirable. When using an external logfile rotator, for example, the appender should create a new file under the old name and start logging into it. If the recreate option is set to a true value, Log::Log4perl::Appender::File will do exactly that. It defaults to false. Check the recreate_check_interval option for performance optimizations with this feature.

recreate_check_interval

In recreate mode, the appender has to continuously check if the file it is logging to is still in the same location. This check is fairly expensive, since it has to call stat on the file name and figure out if its inode has changed. Doing this with every call to log can be prohibitively expensive. Setting it to a positive integer value N will only check the file every N seconds. It defaults to 30.

This obviously means that the appender will continue writing to a moved file until the next check occurs, in the worst case this will happen recreate_check_interval seconds after the file has been moved or deleted. If this is undesirable, setting recreate_check_interval to 0 will have the appender check the file with every call to log().

Из документации неясно работает ли recreate_check_interval, когда указана опция recreate_check_signal или нет (вроде не должна).

Рекомендую сделать простую проверку: strace -s 256 -e open,read,write perl myprogramm.pl. Выплюнуть должна ошибку или что-то в этом духе.

gh0stwizard ★★★★★
()
Ответ на: комментарий от gh0stwizard

стрэйс тоже делал, ничего полезного( Скрипт из под рута

--- SIGUSR1 {si_signo=SIGUSR1, si_code=SI_USER, si_pid=12635, si_uid=0} ---
+++ exited with 0 +++

BieZax
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.