App-loggrep

 view release on metacpan or  search on metacpan

lib/App/loggrep.pm  view on Meta::CPAN

      $i -= $before;
      $i = 0 if $i < 0;
   }
   while ( my $line = $lines->[$i] ) {
      my $lineno = $i++;
      if ($time_filter) {
         my $t = $gd->($line) // 0;
         unless ($t) {
            $buffer->( $line, $lineno );
            next;
         }
         if ( $t > $end ) {
            if ( $abuf-- ) {
               print $code->( $line, $lineno ), "\n";
               next;
            }
            else {
               last;
            }
         }
         if ( $t < $start ) {
            $buffer->( $line, $lineno );
            next;
         }
      }
      my $good = !@include;
      for (@include) {
         if ( $line =~ $_ ) {
            $good = 1;
            last;
         }
      }
      if ($good) {
         for (@exclude) {
            if ( $line =~ $_ ) {
               undef $good;
               last;
            }
         }
      }
      if ($good) {
         $printline->(@$_) for @bbuf;
         $printline->( $line, $lineno, 1 );
         splice @bbuf, 0, scalar @bbuf if $before;
         $abuf = $after;
      }
      else {
         $buffer->( $line, $lineno );
      }
   }
}

# find the log line to begin grepping at
sub _get_start {
   my ( $lines, $start, $t1, $t2, $gd ) = @_;
   return 0 if $start <= $t1;
   my $lim = $#$lines;
   my ( $s, $e ) = ( [ 0, $t1 ], [ $lim, $t2 ] );
   my ( $last, $revcount ) = ( -1, 0 );
   {
      my $i = _guess( $s, $e, $start );
      return $i if $i == $s->[0];
      my $rev = $last == $i;
      $last = $i;
      if ($rev) {    # if we find ourselves looping; bail out
         $revcount++;
         if ( $revcount > 1 ) {
            --$i if $i;
            return $i;
         }
      }
      else {
         $revcount = 0;
      }
      my $t;
      {
         $t = $gd->( $lines->[$i] );
         unless ($t) {
            $i += $rev ? -1 : 1;
            return 0 unless $i;
            return $lim if $i > $lim;
            redo;
         }
      }
      return $i if $t == $start;
      if ( $t < $start ) {
         $s = [ $i, $t ];
      }
      else {
         $e = [ $i, $t ];
      }
      if ( $s->[0] == $e->[0] ) {
         --$i if $i;
         return $i;
      }
      redo;
   }
}

# estimate the next log line to try
sub _guess {
   my ( $s, $e, $start ) = @_;
   my $delta = $start - $s->[1];
   return $s->[0] unless $delta;
   my $diff = $e->[1] - $s->[1];
   my $offset = int( ( $e->[0] - $s->[0] ) * $delta / $diff );
   return $s->[0] + $offset;
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

App::loggrep - quickly find relevant lines in a log searching by date

=head1 VERSION

version 0.002

=head1 METHODS

=head2 new

  App::loggrep->new( $log, $opt );

Constructs an uninitialized grepper. The C<$log> file is a file name and the
C<$opt> parameter a L<Getopt::Long::Descriptive::Opts> object.

=head2 init

Validates all parameters and compiles regexes, returning a list of error
messages.

=head2 grep

Perform the actual grep. Lines are printed to STDOUT.

=head1 AUTHOR

David F. Houghton <dfhoughton@gmail.com>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2014 by David F. Houghton.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut



( run in 1.104 second using v1.01-cache-2.11-cpan-39bf76dae61 )