[Cascavel-pm] Simulando tail -f

Arthur Renato Mello farinha.ufpr em gmail.com
Segunda Outubro 8 13:30:45 PDT 2007


Ola Monges,

tenho o seguinte problema: Preciso simular um tail -f em um arquivo de
log. Mas com uma funcionalidade a mais, o arquivo pode mudar de nome
durante o processo (logrotate). Ou seja, eu comeco a monitorar o
arquivo "log.txt", apos um tempo o logrotate executa e o arquivo eh
renomeado para  "log-old.txt", e um novo log.txt eh criado. O script
precisa esquecer o "log-old.txt" (antigo log.txt que ja esta aberto) e
comecar a monitorar o novo log.txt.

Um agravante eh que quem solicitou nao gostaria de utilizar nenhum
modulo do CPAN, apenas o que for built in da linguagem.

Eu utilizei um codigo do perl FAQ que mostra como simular tail -f, e
acrescentei uma verificacao de inode (usando stat). Caso o inode do
arquivo com mesmo nome, seja diferente do que eu estou usando eu
preciso reabrir o arquivo.

O codigo funciona (esta colado no final). Porem eu estou perdendo as
primeiras linhas do "arquivo novo", a impressao eh que o comando tell,
utilizado no for de leitura soh comeca a fazer efeito quando o tamanho
do arquivo novo, passa o tamanaho do antigo. Algo como se o fdescritor
de arquivo estivesse apontando para uma posicao em bytes qqr e so
fosse comecara ler dali pra frente. Se isto estiver certo gostaria de
alguma ideia de como fazer esse apontador voltar pro comeco do
arquivo.

Espero ter me feito entender :). Desde jah agradeco sugestoes de
solucoes ou novas abordagens:

==============================================
#!/usr/bin/perl

use strict;
use warnings;
#use Fcntl qw(:seek);

sub usage{
    print("USAGE: $0 <LOGFILE>\n");
    exit(1);
}

(@ARGV != 1) and usage();

(my $filename) = @ARGV;

open(LOG, $filename) or die "Unable to open $filename: $!";

my @old_file;
my @new_file;

@old_file = stat($filename);

my $w_time = 1;
my $pos;

my $count = 0;
my $changed = 0;
my $test_file_interval = 10;

while(1){
    $pos = 0;

    for($pos = tell(LOG); $_ = <LOG>; $pos = tell(LOG)){
        print;
    }

    if($changed){
        $changed = 0;

        close(LOG);

        while(! -r $filename){
            sleep($w_time);
        }

        open(LOG, $filename);
    }

    if($count == $test_file_interval){
        $count = 0;

        @new_file = stat($filename);
        if(!defined($new_file[1]) or $old_file[1] != $new_file[1]){
            $changed = 1;
        }
    }

    sleep($w_time);
    seek(LOG, $pos, 0);

    $count++;
}
 ==============================================

[]s
Arthur


Mais detalhes sobre a lista de discussão Cascavel-pm