[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