Почему inotify проигрывает события? - PullRequest
4 голосов
/ 10 декабря 2011

Мне нужно обрабатывать большие (~ 100 с) сообщения системного журнала, используя Perl и Linux :: Inotify2 .

Я написал тестовый скрипт, который непрерывно генерирует сообщения журнала.Для обработки событий мой Perl-скрипт выглядит следующим образом:

#!/usr/bin/perl
use Linux::Inotify2 ;
use Time::HiRes qw(usleep nanosleep);
# create a new object
 my $inotify = new Linux::Inotify2
    or die "Unable to create new inotify object: $!" ;

 # create watch
 $inotify->watch ("/var/log/messages",  IN_ACCESS|IN_OPEN|IN_CLOSE|IN_MODIFY|IN_Q_OVERFLOW)
    or die "watch creation failed" ;
my $count=0;
 while () {
   my @events = $inotify->read;
   unless (@events > 0) {
     print "read error: $!";
     last ;
   }
   #printf "mask\t%d\n", $_->mask foreach @events ; 
   $count++;
   print $count."\n";
   usleep(100000);
 }

Если я откомментирую функцию usleep для имитации обработки, я замечу, что при остановке скрипта генератора журнала скрипт inotify не догоняетс этим.Другими словами, скрипт inotify Perl теряет события.

Также не отображается сообщение о переполнении.

Как мне убедиться, что даже если моя обработка идет медленно, я не теряю сообщения.Другими словами, как мне определить «буфер», в котором сообщения могут временно храниться?

Ответы [ 2 ]

1 голос
/ 02 апреля 2012

Я попытаюсь решить вашу корневую проблему, даже если она не дает точного ответа на ваш вопрос.

Я думаю, что использование inotify - слишком низкоуровневый способ решения этой проблемы.На вашем месте я бы искал решение более высокого уровня, которое освобождает вас от подробностей поиска новых событий и позволяет вам сосредоточиться на обработке событий журнала.Не нужно изобретать велосипед, когда уже есть куча хороших.

Мой первый выбор - использовать современный демон syslog (лично я предпочитаю Syslog-NG, но rsyslog тоже будет работать достаточно хорошо)и свяжите это непосредственно с вашим сценарием.Вместо того, чтобы ваш скрипт выполнял всю работу по отслеживанию появления новых событий, ваш скрипт просто обрабатывает stdin, и демон syslog автоматически отправляет новые журналы в ваш скрипт по мере их поступления. Я успешно использовал этот метод на многочисленныхслучаи.

Мой второй выбор - позволить высокоуровневому модулю Perl выполнять как можно больше тяжелой работы.Первое место, которое я искал бы, было бы File::Tail.Как и раньше, это освобождает вас от проблем с просмотром самого файла и позволяет сосредоточиться на обработке.

0 голосов
/ 01 апреля 2012

Глядя на Inotify на CPAN и пытались ли вы с помощью обратного вызова проверить все ошибки:

 $inotify->watch ("/etc/passwd", IN_ACCESS | IN_MODIFY, sub {
      my $e = shift;
      print "$e->{w}{name} was accessed\n" if $e->IN_ACCESS;
      print "$e->{w}{name} was modified\n" if $e->IN_MODIFY;
      print "$e->{w}{name} is no longer mounted\n" if $e->IN_UNMOUNT;
      print "events for $e->{w}{name} have been lost\n" if $e->IN_Q_OVERFLOW;
  });

Кроме того, вы наблюдаете почти за каждым событием в файле.Я бы только следил за событиями модификации или меньшим подмножеством событий, чтобы увидеть, существует ли проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...