Log-Unrotate

 view release on metacpan or  search on metacpan

lib/Log/Unrotate.pm  view on Meta::CPAN


I.e., if there are I<foo.log>, I<foo.log.1>, and I<foo.log.2>, C<begin> will start from the top of I<foo.log>, C<end> will skip to the bottom of I<foo.log>, while C<first> will start from the top of I<foo.log.2>.

=item I<end>

Describes the reading behavior when we reach the end of a log. Allowed values: C<fixed> (default), C<future>.

=over 4

=item *

When I<end> is C<fixed>, the log is read up to the position where it ended when the reader object was created. This is the default, so you don't wait in a reading loop indefinitely because somebody keeps adding new lines to the log.

=item *

When I<end> is C<future>, it allows the reading of the part of the log that was appended after the reader was created (useful for reading from stdin).

=back

=item I<lock>

Describes the locking behaviour. Allowed values: C<none> (default), C<blocking>, C<nonblocking>.

=over 4

=item *

When I<lock> is C<blocking>, lock named I<pos>.lock will be acquired in the blocking mode.

=item *

When I<lock> is C<nonblocking>, lock named I<pos>.lock will be acquired in the nonblocking mode; if lock file is already locked, exception will be raised.

=back

=item I<check_lastline>

This flag is set by default. It enables content checks when detecting log rotations. There is actually no reason to disable this option.

=item I<check_inode>

Enable inode checks when detecting log rotations. This option should not be enabled when retrieving logs via rsync or some other way which modifies inodes.

This flag is disabled by default, because I<check_lastline> is superior and should be enough for finding the right file.

=back

=cut
sub new ($$)
{
    my ($class, $args) = @_;
    my $self = {
        %{$class->_defaults()},
        %$args,
    };

    croak "unknown start value: '$self->{start}'" unless $_start_values{$self->{start}};
    croak "unknown end value: '$self->{end}'" unless $_end_values{$self->{end}};
    croak "either check_inode or check_lastline should be on" unless $self->{check_inode} or $self->{check_lastline};

    bless $self => $class;

    if ($self->{pos} and $self->{cursor}) {
        croak "only one of 'pos' and 'cursor' should be specified";
    }
    unless ($self->{pos} or $self->{cursor}) {
        croak "one of 'pos' and 'cursor' should be specified";
    }

    my $posfile = delete $self->{pos};
    if ($posfile) {
        if ($posfile eq '-') {
            croak "Log not specified and posfile is '-'" if not defined $self->{log};
            $self->{cursor} = Log::Unrotate::Cursor::Null->new();
        }
        else {
            croak "Log not specified and posfile is not found" if not defined $self->{log} and not -e $posfile;
            $self->{cursor} = Log::Unrotate::Cursor::File->new($posfile, { lock => $self->{lock}, rollback_period => $self->{rollback_period} });
        }
    }

    my $pos = $self->{cursor}->read();
    if ($pos) {
        my $logfile = delete $pos->{LogFile};
        if ($self->{log}) {
            die "logfile mismatch: $logfile ne $self->{log}" if $self->{check_log} and $logfile and $self->{log} ne $logfile;
        } else {
            $self->{log} = $logfile or die "'logfile:' not found in cursor $self->{cursor} and log not specified";
        }
    }

    $self->_set_last_log_number();
    $self->_set_eof();

    if ($pos) {
        my $error;
        while () {
            eval {
                $self->_find_log($pos);
            };
            $error = $@;
            last unless $error;
            last unless $self->{cursor}->rollback();
            $pos = $self->{cursor}->read();
        }
        if ($error) {
            if ($self->{autofix_cursor}) {
                warn $error;
                warn "autofix_cursor is enabled, cleaning $self->{cursor}";
                $self->{cursor}->clean();
                $self->_start();
            }
            else {
                die $error;
            }
        }
    } else {
        $self->_start();
    }

    return $self;

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 0.468 second using v1.00-cache-2.02-grep-82fe00e-cpan-1925d2aa809 )