【问题标题】:awk: Counting errors in tomcat logsawk:计算tomcat日志中的错误
【发布时间】:2012-07-17 09:14:04
【问题描述】:

我的 Tomcat 日志是以这种格式构建的:

[<DATE>] [<COMPONENT>] ERROR_TYPE <ERROR_NAME> - <Rest of line>

其中ERROR_TYPEa log4j value,例如DEBUGERROR

例如,

[18/Jul/2012:08:53:39 +0000] [component1] ERROR ConnectionTimeOut - ...
[18/Jul/2012:09:54:32 +0000] [component2] DEBUG IPNotFound - ...
[18/Jul/2012:09:54:32 +0000] [component1] TRACE Connected - ...
[18/Jul/2012:08:53:39 +0000] [component1] ERROR ConnectionTimeOut - ...

我想创建一个从元组(ERROR_TYPE, ERROR_NAME) 到出现次数的映射,例如

ERROR ConnectionTimeOut       2
DEBUG IPNotFound              1
TRACE Connected               1

我该如何匹配:

_anything_ (ERROR|DEBUG|TRACE|WARN|FATAL_spaces_ _another_word_)_anything_

在 AWK 中,只返回括号中的部分?

【问题讨论】:

    标签: regex tomcat logging awk


    【解决方案1】:
    awk '/ERROR|DEBUG|TRACE|WARN|FATAL/ {count[$4,$5]++} END {for (i in count) {split(i, a, SUBSEP); print a[1], a[2], count[i]}}' inputfile
    

    选择包含错误类型的行。 count 数组元素对于类型和名称一起作为索引递增。逗号表示SUBSEP 变量的内容,默认为\034。在END 块中,遍历count 数组,使用SUBSEP 变量拆分索引。打印类型、名称和计数。

    编辑:

    这使用正则表达式来处理非结构化日志条目:

    awk 'match($0, /(ERROR|DEBUG|TRACE|WARN|FATAL) +[^ ]+/) {s = substr($0, RSTART, RLENGTH); split(s, a); count[a[1],a[2]]++} END {for (i in count) {split(i, a, SUBSEP); print a[1], a[2], count[i]}}' inputfile
    

    【讨论】:

    • 日志通常是非结构化的,所以我不能使用像$4这样的表达式。我只想匹配两个单词,无论之前或之后发生什么。
    • split 函数应该是 split(i, a, SUBSEP) 来获取索引,而不是值。
    • @AdamMatan:对于非结构化数据,它有点复杂。见this answer。取决于 AWK 的风格。如果可以的话,使用 Ruby 或 Perl 可能会更好。
    • 谢谢!日志确实是非结构化的,所以我转向了 Python。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    • 2018-07-26
    相关资源
    最近更新 更多