如何解析perl中的特定行?

时间:2015-02-06 15:11:36

标签: perl parsing logging

我已经从应用程序服务器调用了,我需要获得带有“E”标志或“W”的行,如果在扩展行之后有一条线我也需要它。

我试图找出一个脚本:

#!/usr/bin/perl
use strict;
use warnings;

my $msg;
my $line;
my $line2;
main(@ARGV);

sub rec {
    #$msg= $line;
    print $line;
    while ( $line2 = <FH>) {
        if ( $line2 !~ m/^\[/ ){
            #$msg = $msg.$line2;
            print $line2;
        } else {
            if($line2 =~ m/ E | W /) { rec(); }
            last;
        }

    }
    #print $msg;
}
sub main {
    open(FH,'SystemOut_15.02.05_17.00.02.log') or die "Error openong file : $!";
    while ( $line = <FH>) {
        if($line =~ m/ E | W / and $line =~ m/^\[/){
                rec();
        }
    }
    close FH;
  }

提前致谢。

日志样本:

[2/5/15 14:55:18:025 UTC] 0000003a JDBCException W org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, S
QLState: null
*********************************************************** Start Server *******************************
 0000003a JDBCException O OK
 0000003a JDBCException O OK
********************************************************** End Server *******************************
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException W org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, S
QLState: null
                                                    org.hibernate.util.JDBCExceptionReporter
                                                    org.hibernate.util.JDBCExceptionReporter
                                                    org.hibernate.util.JDBCExceptionReporter
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException E org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, S
QLState: null
                                                    org.hibernate.util.JDBCExceptionReporter
                                                    org.hibernate.util.JDBCExceptionReporter
                                                    org.hibernate.util.JDBCExceptionReporter
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException W org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, S
QLState: null
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException E org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, S
QLState: null
                                                    org.hibernate.util.JDBCExceptionReporter
                                                    org.hibernate.util.JDBCExceptionReporter
                                                    org.hibernate.util.JDBCExceptionReporter
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException O OK

我需要得到什么:

    [2/5/15 14:55:18:025 UTC] 0000003a JDBCException W org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, S
QLState: null
[2/5/15 14:55:18:025 UTC] 0000003a JDBCException W org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, SQLState: null
                                                        org.hibernate.util.JDBCExceptionReporter
                                                        org.hibernate.util.JDBCExceptionReporter
                                                        org.hibernate.util.JDBCExceptionReporter
    [2/5/15 14:55:18:025 UTC] 0000003a JDBCException E org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, SQLState: null
                                                        org.hibernate.util.JDBCExceptionReporter
                                                        org.hibernate.util.JDBCExceptionReporter
                                                        org.hibernate.util.JDBCExceptionReporter
    [2/5/15 14:55:18:025 UTC] 0000003a JDBCException W org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, SQLState: null
    [2/5/15 14:55:18:025 UTC] 0000003a JDBCException E org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 17006, SQLState: null
                                                        org.hibernate.util.JDBCExceptionReporter
                                                        org.hibernate.util.JDBCExceptionReporter
                                                        org.hibernate.util.JDBCExceptionReporter

忽略开始和停止之间的线的一种强有力的方法是使用触发器,如ysth所示;其他(弱)方法:

open(my $fh, '<', 'test2.log') or die "Error opening file : $!";
my $match = 0;
while ( my $line = <$fh> ) {
    if ( $line =~ /^\*+/ ){
        $match = 0;  ## initialize match if line start with star
    }
    if ( $line =~ /^\[/ ) {
          $match = $line =~ m/ E | W /;
    }
    print $line if $match;
}
close $fh;

2 个答案:

答案 0 :(得分:2)

非常简单;您只需要跟踪您当前是否处于匹配的多行记录的一部分,并使用flipflop operator (scalar context ..)排除行的开始/结束服务器范围:

open(my $fh, '<', 'SystemOut_15.02.05_17.00.02.log') or die "Error opening file : $!";
my $match = 0;
while ( my $line = <$fh> ) {
    unless ( $line =~ /^\*+ Start Server \*+$/ .. $line =~ /^\*+ End Server \*+$/ ) { 
        if ( $line =~ /^\[/ ) {
            $match = $line =~ m/ E | W /;
        }
        print $line if $match;
    }
}
close $fh;

答案 1 :(得分:1)

您可能会从阅读Watching LogsTail following web server上提供的优秀POE :: Wheel :: FollowTail人员提供的优秀代码示例中受益。

由于您的日志文件包含多行记录,因此您的任务并不像最初猜测的那么简单。你需要创建一个模式来识别记录的开头([2/5/15 14:55:18:025 UTC] 0000003a JDBCException O),我测试一下 DateTime字符串其次是 HEX 数字和括号内的 JDBCException 可以是一个安全的选择,如果以空格开头的所有行都在继续相同的记录(这需要测试)。

您应该只捕获每条记录并将其发送给另一个事件进行处理,或者甚至使用类似POE::Wheel::Run之类的内容发送要在子进程上处理的每条记录,假设您需要同时使用这两条记录词法解析器(log taillor)和语义解析器(解释日志记录)。

我不知道多行filter,但您可能会因阅读POE::Filter::RecordBlock的代码而受益。