LINUX.ORG.RU

tail -f и perl


0

0

Подскажите пожайлуста как на перле реализовать функциональность tail -f т.е. нужно открыть файл и читать только его изминения. Нужно все это для разбора логов squid, пробовол использовать пайпы, но при бальших нагрузках они рвутся (broken pipe).

Заранее спасибо!

anonymous

Этот скрипт (демон, который висит у меня сервером на 
конкретном порту) на порт 1234 валит все, что добавляется в файл 
socket_demo.log по анологии tail -f  

работает уже 1 год без сучка и задоринки, будучи прописанным в 
автозагрузку в /etc/rc.d/rc.local

#!/usr/bin/perl -w

use File::Tail;
use IO::Socket;
use Symbol;
use POSIX;

$l = 'socket_demo.log';
$PORT=1234;

$server = IO::Socket::INET->new( Proto => 'tcp',
   LocalPort => $PORT, Listen => SOMAXCONN,
   Type => SOCK_STREAM, Reuse => 1) or die " making socket: $@";

$PREFORK =5;
$MAX_CLIENTS_PER_CHILD = 5;
%children=();
$children=0;
make_new_child() for(1 .. $PREFORK);
$SIG{CHLD}=\&REAPER;
$SIG{INT}=\&HUNTSMAN;
while(1){
  sleep;
  for($i=$children; $i<$PREFORK; $i++){make_new_child()}
}

sub tail_socket{
  return $fi = File::Tail->new(
    name => $l,
    maxinterval => 0.1,
    adjustafter => 1000000000,
    interval => 4,
    tail => 0)
}

sub make_new_child{
  my $pid;
  my $sigset;
  $sigset=POSIX::SigSet->new(SIGINT);
  sigprocmask(SIG_BLOCK, $sigset) or die "can't block SIGINT for fork: $!\n";
  die "fork: $!" unless defined($pid = fork);
  if($pid){
    sigprocmask(SIG_UNBLOCK, $sigset) or die "can't unblock SIGINT for fork: $!\n";
    $children{$pid}=1;
    $children++;
    return;
  } else {
    $SIG{INT} = 'DEFAULT';
    $SIG{CHLD}='IGNORE';
    sigprocmask(SIG_UNBLOCK, $sigset) or die "can't unblock SIGINT for fork: $!\n";
    for($i=0;  $i<$MAX_CLIENTS_PER_CHILD; $i++){
      $client = $server->accept() or last;
      &tail_socket();
      while(1){
        print $client $_ while($_=$fi->read);
      }
    } exit;
  }
}

sub HUNTSMAN{
  local($SIG{CHLD})='IGNORE';
  kill 'INT' => keys %children;
  exit;
}

sub REAPER{
  $SIG{CHLD}=\&REAPER;
  my $pid = wait;
  $children--;
  delete $children{$pid};
}

vilfred ☆☆
()
Ответ на: комментарий от vilfred

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

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

vilfred ☆☆
()
Ответ на: комментарий от vilfred

вобщем, имхо, вот это вот IPC - самая о%уенная вещь в перле... такие вещи делать так просто... я когда прошарил - офигел вообще...

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