Parsing 统计日志文件中错误发生次数的工具或语言

Parsing 统计日志文件中错误发生次数的工具或语言,parsing,logging,text,Parsing,Logging,Text,我试图确定解析日志文件的最佳方式,并按类型获取其中所有错误的计数。目前,我在文本编辑器中打开日志,去掉日期和线程ID,然后对文件进行排序。这会按类型将所有错误放在一起,然后我可以对其进行计数(使用编辑器中的count函数,而不是手动)。我正在寻找一种自动完成这项任务的方法,并可能以此作为学习一种新语言的机会(我知道最少的Perl和Ruby,它们似乎可以完成这项任务)。日志文件如下所示(尖括号中的项目对于每行都是可变的,而管道是日志中的实际字符): 理想情况下,最好同时计算平均事务时间: Foo.

我试图确定解析日志文件的最佳方式,并按类型获取其中所有错误的计数。目前,我在文本编辑器中打开日志,去掉日期和线程ID,然后对文件进行排序。这会按类型将所有错误放在一起,然后我可以对其进行计数(使用编辑器中的count函数,而不是手动)。我正在寻找一种自动完成这项任务的方法,并可能以此作为学习一种新语言的机会(我知道最少的Perl和Ruby,它们似乎可以完成这项任务)。日志文件如下所示(尖括号中的项目对于每行都是可变的,而管道是日志中的实际字符):

理想情况下,最好同时计算平均事务时间:

Foo.Bar: Login Transaction: 3 occurrences with an average of 466 milliseconds
Biz.Dee: Logout Transaction: 1 occurrence with an average of 630 milliseconds

我在其他SO线程(、、和)中看到了一些工具,但我也想学习一些新的东西,而不必不必要地复制现有的工具。Perl或Ruby是完成此任务的好选择吗?我不是在寻找一个可以工作的脚本,而是一些指向正确方向的指针或一个好的工具来使用。

Perl将是我进行字符串解析的第一选择。使用正则表达式,您可以立即解析该日志文件。从我看到的情况来看,您处理的似乎是一个计算机可读的文件。您可以使用Perl哈希来进行平均


如果您更熟悉C#和它们的正则表达式,您可能也可以做同样的事情,但是Perl就是为了做这样的事情而构建的。

我会使用正则表达式并计算出现的次数。您可以在多种语言中实现这一点,即使是一个简单的shell脚本也可以做到,例如

grep -E ".*ERROR.*\n" logfile | wc -l

如果你知道/喜欢.NET,Marc Gravell和我开发的框架将是实现这一目标的理想选择。基本上,您可以预先设置所有需要的聚合(分组、求和等),然后“推送”日志文件,最后询问结果。这将允许您在几乎恒定的内存消耗和一次数据传递的情况下执行所有操作

如果您想了解更多详细信息,请告诉我。

这里有一种unix(或)命令行方法,可以通过以下方式执行此操作:

  • 一个命令(解析出第四个字段,其中字段由管道“|”)分隔)
  • 用于替换上面的事务([584])的命令,以简化分组(使用[tid])
  • 排序和uniq以查找和计数重复行:
以下是命令行:

awk "FS=\"^|\";{print $4}" logfile.txt | sed -e "s/\[[0-9]*\]/[tid]/g" \
| sort | uniq -c | sort
以下是输出:

   1  Biz.Dee: Logout Transaction [id] executed in [id] milliseconds
   1  Foo.Bar: Backend error
   1  Foo.Bar: InvalidUserException
   1  Foo.Com: Timeout error
   3  Foo.Bar: Login Transaction [id] executed in [id] milliseconds

这里有一个可能的Perl起点:

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

my %unique_messages;
while (<>)
{
  my ($timestamp, $thread, $type, $message) = $_ =~
    /^
      ([^|]+) \|
      ([^|]+) \|
      ([^|]+) \|
      (.+)
     $/x;

  $unique_messages{$message}++ if $type =~ /ERROR/;
}

print $unique_messages{$_}, ' -> ', $_, "\n" for keys %unique_messages;
exit 0;
#/usr/bin/perl
严格使用;
使用警告;
我的%unique_消息;
而()
{
我的($timestamp,$thread,$type,$message)=$\u=~
/^
([^|]+) \|
([^|]+) \|
([^|]+) \|
(.+)
美元/x;
$unique_messages{$message}++if$type=~/ERROR/;
}
为键%unique\u messages打印$unique\u messages{$\u},'->',$\u,“\n”;
出口0;
产生:

% ec.pl < err.log
1 ->  Foo.Com: Timeout error
1 ->  Foo.Bar: InvalidUserException
2 ->  Foo.Bar: Backend error
%ec.plFoo.Com:超时错误
1->Foo.Bar:InvalidUserException
2->Foo.Bar:后端错误

使用awk的另一种可能性:

grep ERROR filename.log | awk -F'|' '{ print $4 }' | awk -FS=':' '{count[$1]++}END{for(j in count) print j,": "count[j]" occurence(s)"}'

您可以使用像Monar这样的程序为平面数据提供结构。我用它来获取文本文件,并用它们制作表格,以便在数据库中使用。

如果您对SQL还满意,请使用microsoft日志解析器。以及使用Windows。免费而且非常方便。很容易包装在HTA中,然后您可以使用VBS或(?)JS以交互方式构建查询字符串。相信它会为你做小计。当然可以进行排序和分组。

在vim中,您可以执行以下操作:%s/pattern//n其中pattern是搜索字符串。

如何对所有相同的错误进行分组和计数?我知道正则表达式会给出所有匹配项的计数,但我需要在不知道完整错误文本的情况下对它们进行分组。我可以在“ERROR |”上进行匹配,但这太宽泛了,在特定错误上进行匹配可能会导致新错误的丢失。这只会给出所有错误的计数,而不是我需要的每个类型的错误计数。错过了,抱歉。为此,我将编写一个C#程序来打开文件,获取正则表达式“*ERROR.*\n”的所有匹配项,然后使用regex.Split(“ERROR”)并使用哈希表来计算错误的发生率。太棒了!2021年,它可以在不修改Tomcat日志的情况下工作。非常感谢。
% ec.pl < err.log
1 ->  Foo.Com: Timeout error
1 ->  Foo.Bar: InvalidUserException
2 ->  Foo.Bar: Backend error
grep ERROR filename.log | awk -F'|' '{ print $4 }' | awk -FS=':' '{count[$1]++}END{for(j in count) print j,": "count[j]" occurence(s)"}'