【问题标题】:Grepping and grouping for errors in log files对日志文件中的错误进行筛选和分组
【发布时间】:2015-10-10 10:48:02
【问题描述】:

我在 Linux 上(有时也在 AIX 上)并且在一个文件夹中有一堆日志文件。我有一个 grep 命令,它会以如下格式过滤掉所有的错误。

CreateOrder_hostname_tee.log:2015-09-29 15:42:06,715:ERROR  :Thread-26_CreateOrder: [1443555726715] Error1  [system]: Class1
CreateOrder_hostname_tee.log:2015-09-29 15:42:06,715:ERROR  :Thread-15_CreateOrder: [1443555726715] Error1  [system]: Class1
CreateOrder_hostname_tee.log:2015-09-29 15:42:06,715:ERROR  :Thread-28_CreateOrder: [1443555726715] Error2  [system]: Class2
ScheduleOrder_hostname_tee.log:2015-09-30 03:55:05,011:ERROR  :Thread-5_ScheduleOrder: [1443599705009] Error3  [system]: Class3

是否可以使用 grep/awk/sed 的某种组合来获取上述格式的数据?

API: Error: Count
CreateOrder: Error1: 50
CreateOrder: Error2: 50
ScheduleOrder: Error3: 50

如果没有,是否有可能获得这样的格式?然后我可以使用 wc 或类似的方法来计算不同的错误。

API: Date: Error
CreateOrder: 2015-09-29 15:42:06,715: Error1
CreateOrder: 2015-09-29 15:42:06,715: Error2
ScheduleOrder: 2015-09-29 15:42:06,715: Error3

编辑 1:

错误可以是任何字符串(包括空格)。基本上,应该显示下面括号之间的任何内容。

[1443555726715] Error1: This is an error with description.  [system]: Class1

【问题讨论】:

  • 50s 来自哪里?我没有在输入中看到它们。
  • @Alfe:我认为是该错误类型的出现次数
  • 这只是错误发生次数的计数——我在编造虚拟数据。
  • 是否事先知道错误开始模式? (如 CreateOrder、ScheduleOrder 等)?

标签: linux unix awk sed grep


【解决方案1】:
input=$(your grep command)
formatted=$(
  echo "$input" |
    sed 's/^\([^_]*\).*[0-9]*\] \([^[]*[^\[ ]\).*/\1: \2/'
)
kinds=$(echo "$formatted" | sort -u)
while IFS= read kind
do
  count=$(echo "$formatted" | grep "$kind" | wc -l)
  echo "$kind: $count"
done <<< "$kinds"

对于您的问题中给出的输入,这给出了以下输出:

CreateOrder: Error1: 2
CreateOrder: Error2: 1
ScheduleOrder: Error3: 1

一切都在内存中完成,因此对于非常大的数据结构(数十或数百兆字节)可能不可行。但在这些情况下,您可以使用临时文件而不是 shell 变量(例如 echo "$input" | sed … &gt; formatted.tmpsort -u formatted.tmp &gt; kinds.tmp 等)。

【讨论】:

  • 感谢您的回复。这非常接近,但错误中可能有空格,我认为这不能处理,因为我只得到空格之前的错误字符串。是否有可能得到包括任何空格的完整错误?
  • 我的千里眼今天很低 :-} 意思:我猜不出你没有告诉我什么。然后你需要调整正则表达式。请给出更多示例来说明应该将什么输入转换为什么输出。我根据我现在了解的规范更改了答案。
  • 抱歉,我已经添加了一条声明,说明错误字符串可以是任何内容,应该从括号之间抓取。
  • 我更改了答案,将所有内容都放在下一个左括号之前的最后一个非空格处。
  • 感谢您的更新,这正是我想要的。我将研究您的示例并尝试在上面的问题中生成选项 2,如果需要,请提出一个新问题。
【解决方案2】:

以下是一个简单的 bash 脚本,您可以在其中轻松添加新模式,用法是:

myscript.sh logfile

脚本代码:

#!/bin/bash

PATTERN_1=(CreateOrder Error1)
PATTERN_2=(CreateOrder Error2)
PATTERN_3=(ScheduleOrder Error3)

function get_pattern_count {
    COUNT=$(grep -E ".+$1.+$2.+" $3 | wc -l)
    echo $1 " : " $2 : $COUNT
}

echo "API: Error: Count"
get_pattern_count ${PATTERN_1[0]} ${PATTERN_1[1]} $1
get_pattern_count ${PATTERN_2[0]} ${PATTERN_2[1]} $1
get_pattern_count ${PATTERN_3[0]} ${PATTERN_3[1]} $1

【讨论】:

  • 我假设 PO 不知道可能会出现哪些模式。
  • 您的意思是用户不知道以“CreateOrder”等开头的错误语法?所以这可能是什么?
  • 是的,我是这个意思。你真的应该开始使用"$x" 而不是$x。否则,一旦您的$x 包含空格或其他有趣的字符,您就会遇到麻烦。
  • 我不确定。我认为错误模式是事先知道的。
【解决方案3】:

此解决方案按 API 字母顺序对输出进行排序
在开始时,它会打印标题行
遍历每一行,它会搜索 / 正则表达式/
如果找到,它将结果存储到哈希中
最后,它对哈希的键进行排序,并打印结果

perl -lane 'BEGIN{print "API: Error: Count"} if(/^([^_]+).*\]\s*(Error[^\[]+)\[/){$h{"$1: $2:"}++} END{for $k (sort keys %h){ print "$k $h{$k}"}}' log

输入:

CreateOrder_hostname_tee.log:2015-09-29 15:42:06,715:ERROR  :Thread-26_CreateOrder: [1443555726715] Error1  [system]: Class1
CreateOrder_hostname_tee.log:2015-09-29 15:42:06,715:ERROR  :Thread-15_CreateOrder: [1443555726715] Error1  [system]: Class1
CreateOrder_hostname_tee.log:2015-09-29 15:42:06,715:ERROR  :Thread-28_CreateOrder: [1443555726715] Error2  [system]: Class2
ScheduleOrder_hostname_tee.log:2015-09-30 03:55:05,011:ERROR  :Thread-5_ScheduleOrder: [1443599705009] Error3  [system]: Class3
ScheduleOrder_hostname_tee.log:2015-09-30 03:55:05,011:ERROR  :Thread-5_ScheduleOrder: [1443555726715] Error1: This is an error with description.  [system]: Class1

输出:

API: Error: Count
CreateOrder: Error1  : 2
CreateOrder: Error2  : 1
ScheduleOrder: Error1: This is an error with description.  : 1
ScheduleOrder: Error3  : 1

【讨论】:

    猜你喜欢
    • 2014-12-19
    • 1970-01-01
    • 1970-01-01
    • 2019-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多