ねもぷらす

ふぁいんでぃんぐねもの日記。プログラミングとか育児とか

ログ解析ツール

スケルトンメモ。ハッシュのハッシュが面白いだけorz

#!/usr/bin/perl -w
use strict;
use warnings;
use Getopt::Std;
use Time::Local;
use Term::ANSIColor qw(:constants);
$Term::ANSIColor::AUTORESET = 1;

use lib qw( ./lib );
use Log::Analyze;

#my $self = Log::Analyze->new;

eval{

  my %arg;
  return unless( &checkArg(\%arg) );

  my($start,$end,$pid,$host,$execDate,$execLine);
  my @error;
  my %result;

  open(READ_FH, "< $arg{f}") or die "$! : $arg{f}";
  while(<READ_FH>){
    chomp;

    # start
    if( m/OFFSET 0/ ){
      ($start, $pid, $execDate)
        = /^\[.*?\s+(\D+\s+\d+\s+\d{2,2}:\d{2,2}:\d{2,2}) \d+\]\s+(\d+)\s+.*?DATE=\s+(\d+-\d+-\d+ \d+:\d+:\d+).*?$/ or next;

      $execDate = &time_epoch( $execDate );
      $result{$execDate}{$pid}{start} = $start;
    }

    # end
    elsif( m/ last SELECT_DATE= / ){
      ($end, $pid, $execDate, $execLine)
        = /^\[.*? (\D+\s+\d+\s+\d{2,2}:\d{2,2}:\d{2,2}) \d+\] (\d+).*?\s+last\s+DATE=\s+(\d+-\d+-\d+ \d+:\d+:\d+)\s+TOTAL=\s+(\d+)$/
          or next;

      $execDate = &time_epoch( $execDate );
      $result{$execDate}{$pid}{end} = $end;
      $result{$execDate}{$pid}{record} = $execLine;
    }

    # error
    elsif( m/error/ ){
      push @error, $_;
    }

  }
  close READ_FH or die "$! : $arg{f}";

  # OUTPUT
  my @keys = sort {
       length($b) <=> length($a) ||
       $a cmp $b
  } keys %result;

  foreach $execDate ( @keys ){
    foreach $pid (keys %{ $result{ $execDate }  } ){
      next unless($execDate);
      print &epoch_time( $execDate )."\t";

      unless( $result{$execDate}{$pid}{start} ){
        print BOLD RED "error start-$execDate\t";
      }else{
        print $result{ $execDate }{$pid}{start} ."\t";
      }

      unless( $result{ $execDate }{$pid}{end} ){
        print BOLD RED "error end-$execDate\t";
      }else{
        print $result{ $execDate }{$pid}{end} ."\t";
      }

      unless( $result{ $execDate }{$pid}{record} ){
        print BOLD RED "error record-$execDate\t";
      }else{
        print $result{ $execDate }{$pid}{record} ."\t";
      }
    }
    print "\n";
  }

  print &epoch_time()."\n";
  print BOLD RED &date_epoch( 'Dec  1 04:00:02' )."\n";

};if($@){
  print "Error:$@\n";
}

sub checkArg {
  my $ref_arg = shift;
  my $usage = << "USAGE";
usage : perl $0 [-f file path]

  [option]
  -f file path
  -u usage
  -v version

USAGE

  if( 0 == getopts("uvf:",$ref_arg) ){
    print "It is the inaccurate argument.\n$usage";
    return undef;
  }
  unless( $$ref_arg{f} ){
    print "It is insufficient or is a lot.\n$usage";
    return undef;
  }
  1;
}

sub time_epoch {
  my($time) = @_;
  my($year, $mon, $mday, $hour, $min, $sec) =
       ( $time =~ /^(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)$/ ) or return "error";
  my $epoch = timelocal($sec, $min, $hour, $mday, $mon-1, $year-1900);
  return $epoch;
}

sub epoch_time {
  my($epoch) = @_;
  $epoch = time unless($epoch);
  my($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
    = ( localtime($epoch) );
  return sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
}

{
  my %date = (
    jan =>  1, feb =>  2, mar =>  3, apr =>  4, may =>  5, jun =>  7,
    jul =>  7, aug =>  8, sep =>  9, oct => 10, nov => 11, dec => 12,
  );
  # Dec  1 04:00:02
  sub date_epoch {
    my $time = shift;
    my $year = shift || 2006;
    my($mon, $day, $hour, $min, $sec) =
      ( $time =~ /^(\w+)\s+(\d+)\s+(\d+):(\d+):(\d+)$/ ) or return "error";
    $mon = lc $mon;
    $mon = $date{ $mon } || 1;
    my $epoch = timelocal($sec, $min, $hour, $day, $mon-1, $year-1900);
    return $epoch;
  }
}

1;
__END__