my $logfile = "logfile"; open( LOG, "<$logfile" ) or die "$logfile: $!"; while (!$end_condition) { while ( my $line = ) { print $line; } sleep(1); # do something usefull seek( LOG, 0, 1 ); } close(LOG); #### tie *LOG, "Tie::Tailrotate", "$logfile"; open ... #### package Tie::Tailrotate; use strict; # ;-) learned that use Carp; sub TIEHANDLE { my $class = shift; my $fname = shift; # need $fname to open file and initialize filehandle if ( $fname =~ /[>+|]/) { croak "Only read support for $fname\n"; } open my $self, $fname or croak "Open $fname failed:$!"; # $self is filehandle, # but created is $$$self, @$$self and %$$self # see Camel Book: 14.4. Tying Filehandles $$self->{filename} = $fname; $$self->{curpos} = 0; return bless $self, $class; # $self is a glob ref } sub OPEN { # needs to be covered my $self = shift; my $fname = shift; $self->CLOSE; if ( $fname =~ /[>+|]/) { croak "Only read support for $fname\n"; } open $self, $fname or croak "Open $fname failed:$!"; $$self->{curpos} = 0; $$self->{filename} = $fname; close($self); return 1; } sub READLINE { my $self = shift; my $line; my $size = (stat $$self->{filename} )[7]; # if the last position I read from is bigger than # actual file size, the file rotated. Continue # reading from last file, last position. my $use_active_file = ($$self->{curpos} <= $size ); if ($use_active_file) { # continue with active logfile open $self, $$self->{filename} or croak "Open $$self->{filename} failed:$!"; seek ($self, $$self->{curpos}, 0 ); $line = <$self>; # undef if eof $$self->{curpos} = tell($self) if ($line); } else { # File rotated, Log::Agent naming convention my $rot_fname = "$$self->{filename}.0"; $size = (stat $rot_fname )[7]; open $self, $rot_fname or croak "Open $rot_fname failed:$!"; seek ($self, $$self->{curpos}, 0 ); $line = <$self>; # undef if eof if ($line) { $$self->{curpos} = tell($self); } else { # reset position, to continue with active file $$self->{curpos} = 0; } } close($self); # unlock file return $line; }