从管道

时间:2015-08-05 14:37:24

标签: regex perl

我想从日志文件中提取数据。 该数据跨越多行。 起始行包含时间戳,线程ID和一些其他相关属性。 结束行包含线程id和线程工作繁忙时间的经过时间。 结果应写入CVS文件进行统计分析。 每个结果行应如下所示:起始行的时间戳,线程ID,其他相关属性和已用时间。

A'重新排列' log snipped如下所示:

2015-08-01 12:23:21.123 | DEBUG | Thread-10 | Received message with id 1234 - com.example.product.module.Receiver#123
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | some log message #1 - com.example.product.module.Helper1#123
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | some log message #2 - com.example.product.module.Helper2#123
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | some log message #3 - com.example.product.module.Helper3#123
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | some log message #4 - com.example.product.module.Helper4#123
2015-08-01 12:23:21.224 | DEBUG | Thread-10 | Message processed in 101ms - com.example.product.module.Receiver#130

2015-08-01 12:24:21.123 | DEBUG | Thread-11 | Received message with id 2345 - com.example.product.module.Receiver#123
2015-08-01 12:24:21.123 | DEBUG | Thread-11 | some log message #1 - com.example.product.module.Helper1#123
2015-08-01 12:24:21.123 | DEBUG | Thread-11 | some log message #2 - com.example.product.module.Helper2#123
2015-08-01 12:24:21.123 | DEBUG | Thread-11 | some log message #3 - com.example.product.module.Helper3#123
2015-08-01 12:24:21.123 | DEBUG | Thread-11 | some log message #4 - com.example.product.module.Helper4#123
2015-08-01 12:24:21.225 | DEBUG | Thread-11 | Message processed in 102ms - com.example.product.module.Receiver#130

2015-08-01 12:25:21.123 | DEBUG | Thread-12 | Received message with id 3456 - com.example.product.module.Receiver#123
2015-08-01 12:25:21.123 | DEBUG | Thread-12 | some log message #1 - com.example.product.module.Helper1#123
2015-08-01 12:25:21.123 | DEBUG | Thread-12 | some log message #2 - com.example.product.module.Helper2#123
2015-08-01 12:25:21.123 | DEBUG | Thread-12 | some log message #3 - com.example.product.module.Helper3#123
2015-08-01 12:25:21.123 | DEBUG | Thread-12 | some log message #4 - com.example.product.module.Helper4#123
2015-08-01 12:25:21.226 | DEBUG | Thread-12 | Message processed in 103ms - com.example.product.module.Receiver#130

但实际上这些日志消息是混合的,因为应用程序同时运行多个线程。所以真正的日志看起来像:

2015-08-01 12:23:21.123 | DEBUG | Thread-10 | Received message with id 1234 - com.example.product.module.Receiver#123
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | some log message #1 - com.example.product.module.Helper1#123
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | some log message #2 - com.example.product.module.Helper2#123
2015-08-01 12:24:21.123 | DEBUG | Thread-11 | Received message with id 2345 - com.example.product.module.Receiver#123
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | some log message #3 - com.example.product.module.Helper3#123
2015-08-01 12:24:21.123 | DEBUG | Thread-11 | some log message #1 - com.example.product.module.Helper1#123
2015-08-01 12:25:21.123 | DEBUG | Thread-12 | Received message with id 3456 - com.example.product.module.Receiver#123
2015-08-01 12:25:21.123 | DEBUG | Thread-12 | some log message #1 - com.example.product.module.Helper1#123
2015-08-01 12:24:21.123 | DEBUG | Thread-11 | some log message #2 - com.example.product.module.Helper2#123
2015-08-01 12:25:21.123 | DEBUG | Thread-12 | some log message #2 - com.example.product.module.Helper2#123
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | some log message #4 - com.example.product.module.Helper4#123
2015-08-01 12:24:21.123 | DEBUG | Thread-11 | some log message #3 - com.example.product.module.Helper3#123
2015-08-01 12:23:21.224 | DEBUG | Thread-10 | Message processed in 101ms - com.example.product.module.Receiver#130
2015-08-01 12:24:21.224 | DEBUG | Thread-11 | some log message #4 - com.example.product.module.Helper4#123
2015-08-01 12:25:21.224 | DEBUG | Thread-12 | some log message #3 - com.example.product.module.Helper3#123
2015-08-01 12:25:21.224 | DEBUG | Thread-12 | some log message #4 - com.example.product.module.Helper4#123
2015-08-01 12:24:21.225 | DEBUG | Thread-11 | Message processed in 102ms - com.example.product.module.Receiver#130
2015-08-01 12:25:21.226 | DEBUG | Thread-12 | Message processed in 103ms - com.example.product.module.Receiver#130

我精心制作了一个正则表达式,可以对重新排列的'进行匹配。记录:

/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}).*(Thread-\d+).*Received message with id (\d+) [\s\S]+?\2.*Message processed in (\d+)ms/g

打印捕获的组(print "$1;$2;$3;$4\n";)时所需的结果是:

2015-08-01 12:23:21.123;Thread-10;1234;101
2015-08-01 12:24:21.123;Thread-11;2345;102
2015-08-01 12:25:21.123;Thread-12;3456;103

当我使用www.regexr.com尝试这些示例时,重新排列的日志剪辑上的运行会给出三个匹配。

我现在的第一个问题是:当我想在Perl单行中使用正则表达式时,我无法在多行上执行匹配。我认为它与-n开关有关,它导致在perl代码周围添加循环,并且perl代码分别在每一行上执行。

cat files.log | perl -ne 'next LINE unless /(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}).*(Thread-\d+).*Received message with id (\d+) [\s\S]+?\2.*Message processed in (\d+)ms/gm; print "$1;$2;$3;$4\n";'

我面临的第二个问题是,在日志文件排列不当的真实日志文件中,我无法提取所有可能的匹配项。在给定的剪切中,只能匹配一个结果,而不是所有三个结果。

我尝试过将Perl命令中的记录分隔符设置为undef $\=undef;,删除next LINE unless ...

有人能指出我可能有帮助的方向吗?

日志文件可以变得相当大(~200mb),所以将所有行合并为一个巨大的字符串似乎不是一个好方法,虽然我还没有尝试过。

1 个答案:

答案 0 :(得分:0)

哈希通常用于分组。

my %buf;
while (<>) {
   chomp;
   my @fields = split / \| /;
   my $id = $fields[2];
   push @{ $buf{$id} }, \@fields;
   process(@{ delete($buf{$id}) })
      if $fields[3] =~ /^Message processed in /;
}
为每组行调用

process。每个process的参数都是一行,作为对字段数组的引用。