Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

Find error message starting at line after last error

by dirtdog (Monk)
on Oct 05, 2011 at 01:43 UTC ( #929699=perlquestion: print w/replies, xml ) Need Help??
dirtdog has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I'm hoping someone can assist with the following problem. I have a log file that has output written to it all day. I need to check it for a specific error: "OutOfMemory". Once the word "OutOfMemory" is found, I email the line to the necessary parties and then resume looking for the error again. The caveat is that I need to resume checking the log file starting from the line after the last error found. This way I will only page out on new errors found. This is the part i'm struggling with

Below is a code snippet..i only need help with the requirement of how to resume looking for the next error in a file. Any help is greatly appreciated

sub resetFilePos { my $fileno = shift; my $mtime_curr = (stat($fileno))[9]; my $mtime_new = (stat($file_name))[9]; if ($mtime_curr + 5 <= $mtime_new) { close($fileno); open($fileno, "<",$file_name ) or die "Can't open file + $file_name"; } else { seek($fileno,0,1); } return $fileno; } sub process { my $file = "/$ENV{HOME}/Error.log"; eval { open ($tail,"<",$file_name) or die "Can't open file $f +ile_name"; for(;;) { for $line (<$tail>) { if ( /OutOfMemoryError/) { send_mail($_,$.); } } $tail = resetFilePos($tail); } close($tail); } } process();

Replies are listed 'Best First'.
Re: Find error message starting at line after last error
by armstd (Friar) on Oct 05, 2011 at 02:40 UTC

    I must be missing something here...

    You're slurping it line-by-line with <$tail>, and emailing the lines containing the error. What are you resetting file position for? The loop will just proceed to the next line automatically. Why close and reopen? I guess the log is being rotated underneath?

    For this sort of thing I'd probably read from a 'tail -F' pipe instead and keep the perl part trivial. Or use any of the multitude of CPAN tail modules, rather than trying to reimplement tail all over again.


Re: Find error message starting at line after last error
by i5513 (Pilgrim) on Oct 05, 2011 at 07:01 UTC

    See logtail2(and its manpage), which save an offset and allow you to read the file only from the last line which was read.

    You can modify it to get your goal, or pipe it to a simple perl script

Re: Find error message starting at line after last error
by roboticus (Chancellor) on Oct 05, 2011 at 10:40 UTC


    Like armstd mentioned, part of the problem is that you're rewinding the file to the beginning. I'd suggest tracking the last line of the file you examined each time with a log tailing module (as described to by i5513) or something like this (untested):

    sub saveFilePos { my ($fileno, $filename) = @_; my $filepos = tell($fileno); open my $FH, '>', $filename or die "Can't open $fname: $!"; print $FH $filepos; close $FH; } sub process { my $file = "/$ENV{HOME}/Error.log"; my $file_last = "/$ENV{HOME}/Error.log.lastpos"; my $file_pos = 0; # Default to beginning of file eval { # Get last position in file (if any) open my $FH, '<', $file_last; if ($FH) { $file_pos = <$FH>; close $FH; } open ($tail,"<",$file_name) or die "Can't open file $file_name +"; seek($tail, $file_pos, 0); for(;;) { for $line (<$tail>) { if ( /OutOfMemoryError/) { send_mail($_,$.); } } } # Save last position examined saveFilePos($tail, $file_last); close($tail); } }


    When your only tool is a hammer, all problems look like your thumb.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://929699]
Approved by blue_cowdawg
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2018-05-22 18:40 GMT
Find Nodes?
    Voting Booth?