use strict; use Getopt::Long; use IO::File; use Data::Dumper; GetOptions ( 'i|input=s' => \( my $INPUT = "./access.log" ), 'l|lastpos=s' => \( my $LASTPOS = "./lastpos.txt" ), 'f|feedback' => \( my $FEEDBACK = undef ), ); unless ( defined $INPUT && defined $LASTPOS ) { print <) { $begin_pos = $next_pos; $next_pos = tell; # process the log file here chomp($next_line); print "$next_line\n"; } # at here, begin pos is the position of the last line seek $f, $begin_pos, 0; chomp($next_line = <$f>); $lastinfo->{pos} = $begin_pos; $lastinfo->{text} = $next_line; print "Last Pos Info:\n", Dumper($lastinfo) if ($FEEDBACK); # ok, write the last info back to file WriteLastPosFile($LASTPOS, $lastinfo); exit(0); sub ReadLastPosFile { # last pos file format - | my $filename = shift; my $f = new IO::File $filename, "r" or die "Could not open lastpos file"; chomp(my $info = <$f>); my %lastinfo; ($lastinfo{pos}, $lastinfo{text}) = $info =~ /(\d+)\|(.*)/; return \%lastinfo; } sub WriteLastPosFile { my ($filename, $lastinfo) = @_; my $f = new IO::File $filename, "w" or die "Could not write to lastpos file"; printf $f "%s|%s\n", $lastinfo->{pos}, $lastinfo->{text}; } sub VerifyLastPosition { my ($logfile, $lastinfo) = @_; my $f = new IO::File $logfile, "r" or die "Could not open log file"; seek $f, 0, 2; # seek to the end of the file my $eof = tell $f; return 0 if $lastinfo->{pos} >= $eof; # ok, file has been trimmed seek $f, $lastinfo->{pos}, 0; chomp(my $line = <$f>); # retrieve what we believe was the last line return 0 if $line ne $lastinfo->{text}; # ok, file has been trimmed my $begin_pos = tell $f; # otherwise start from next line # -1 means the file has not been changed since # last time it was parsed. return $eof == $begin_pos ? -1 : $begin_pos; }