onegative has asked for the wisdom of the Perl Monks concerning the following question:

Howdy Monks,

I am using the File::Tail module to watch a busy log file and pipe the results to a fifo. But I am having trouble keeping it running. The following error occurs sporatically and I am not sure why seeing the code is fairly simple. The negative time value is the only thing changing in the error message. Any ideas?

Time::HiRes::sleep(-0.13635): negative time not invented yet at /usr/l +ocal/lib/perl5/site_perl/5.8.2/File/Tail.pm line 529.
#!/usr/local/bin/perl ## ### ### This script reads the page.log file, formats the data, and sends i +t ### to the nco_p_data FIFO for use by the pmgrd process. ### ### April 2, 2004 ### Added space for message and date to be seperate # # use File::Tail; # Preset variables my $LogFile="/opt/app/bmc/PATROL3.5/lib/psl/EMProg/CEM/page.log"; # my $PipeName="/opt/app/PatrolAdmin/docs/eventmgr/pipes/nco_p_data"; # my $fi=tie *FH,"File::Tail",(name=>$LogFile,reset_tail=>0); ### If told to stop kill process and not restart if ($ARGV[0] eq "stop"){ @procs=`ps -ef \| grep eventFIFO \| grep -v grep | gre +p -v $$`; foreach $line (@procs){ $line =~ /\w+\s+(\d+)\s/; $pid = $1; system(`kill $pid`); } exit 0; } unless( -p $PipeName) { unlink $PipeName; system("mkfifo -m 644 $PipeName") && die "Can't mkfifo $PipeNa +me: $!"; } while (FH) { $line = $fi->read; if($line =~ /(.*)\|~\|(.*)\|~\|([\W\w]+)\|~\|(.*)/) { $contline=""; $PagerID=$1; $Message=$2." ".$3; $Status=$4; } else { $contline=$contline.$line; if($contline =~ /(.*)\|~\|(.*)\|~\|([\w\W]+)\|~\|(.*)/ +) { $contline=""; $PagerID=$1; $Message=$2." ".$3; $Status=$4; $contline=""; } else { next; } } open(FIFO,">$PipeName") || die "Couldn't open file $PipeName - $!\n"; print FIFO "NEW|TODAY|NOW|\"\"|$PagerID|$Message|$Status\n"; close(FIFO); }

Replies are listed 'Best First'.
Re: File::Tail or Time::HiRes
by BrowserUk (Pope) on Jul 21, 2004 at 19:16 UTC

    File::Tail does some math with time intervals in an attempt to predict how long it shoudl sleep before the next line of data will be available to be read. It seems from your error message that under some circumstances, the calculation can results in a negative number.

    You could try modifying line 529 of File::Tail thus:

    sleep($object->interval > 0 ? $object->interval : 1 );

    where 1 is some arbitrary number of milliseconds (or seconds if Time::HiRes is not available), used as a default when the math goes wrong.

    If that fixes your problem you could suggest it to the module author.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
Re: File::Tail or Time::HiRes
by pbeckingham (Parson) on Jul 21, 2004 at 19:14 UTC

    Is your file located on some kind of network-shared drive? Are the system clocks on the two boxes off by some small amount?

    If so, I've seen something similar in a non-Perl environment, whereby one machine applies a timestamp to the mtime field, and another machine compares that time with the time it last displayed new lines, then boom.

      That is a very real possibility, because this log file does in fact reside on a NFS share. I will definately check that now and let everyone know. Man that was a great catch, if in fact it does pan out that way. Thanks for your insight. Also I may limit the File::Tail module to a specific time period. But thanks to all that replied.

        I'll save you some time--NFS is completely irrelevant.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon