如何使用grep从日志文件中捕获Java异常,包括堆栈跟踪?

时间:2016-01-14 11:18:20

标签: java unix exception grep stack-trace

摘要

我正在尝试使用grep命令从日志文件中获取日志。但是,我可以匹配时间戳,但是没有获得我需要的完整堆栈跟踪。

日志文件样本

[1/10/16 23:55:33:018 PST] 00000057 ServerObj E   SECJ0373E: Exception message
at com.own.ws.wim.util.UniqueNameHelper.formatUniqueName(UniqueNameHelper.java:102)
at com.own.ws.wim.ProfileManager.getImpl(ProfileManager.java:1569)

我尝试过什么

我可以获取日志条目,但我也想要堆栈跟踪。我试过了:

$ grep -i '^[[:space:]]*at' --before-context=2 SystemOut.log |
    grep "1/13/16 7:[1-60]" 
[1/10/16 23:55:33:018 PST] 00000057 ServerObj E   SECJ0373E: Exception message

知道如何实现这一目标吗?

2 个答案:

答案 0 :(得分:6)

(从我的答案:https://stackoverflow.com/a/16064081/430128

这是一个快速而又脏的grep表达式...如果你使用log4j这样的记录器,那么异常的第一行通常会包含<link rel="icon" type="image/x-icon" href="favicon.ico"> WARN,下一行将包含Exception名称和可选的消息,然后后续堆栈跟踪将以下列之一开头:

  1. ERROR(tab + at)
  2. "\tat"
  3. "Caused by: "(这些行表示堆栈中的帧数未在“由...引起”异常中显示)
  4. 堆栈前的异常名称(可能是消息)
  5. 我们希望获得上述所有行,因此grep表达式为:

    "\t... <some number> more"

    它假设一个Exception类总是包含单词 grep -P "(WARN|ERROR|^\tat |Exception|^Caused by: |\t... \d+ more)" ,这可能是也可能不是,但毕竟这是快速而又脏的。

    根据具体情况进行调整。

答案 1 :(得分:1)

使用固定长度跟踪的上下文

在原始帖子中,您会显示一个三行条目。如果您知道每个带有堆栈跟踪的异常消息正好是三行,那么您可以使用--after-context标志之一(如果您的grep支持)来获取所有三行。例如,要将所有异常与堆栈跟踪一起提取:

$ fgrep -A2 'Exception message' SystemOut.log
[1/10/16 23:55:33:018 PST] 00000057 ServerObj E   SECJ0373E: Exception message
at com.own.ws.wim.util.UniqueNameHelper.formatUniqueName(UniqueNameHelper.java:102)
at com.own.ws.wim.ProfileManager.getImpl(ProfileManager.java:1569)

对可变长度堆栈跟踪使用多行表达式

但是,如果您不知道堆栈跟踪中有多少行,那么您需要一个带有停止模式的多行正则表达式。为此,您需要一个grep,其中编译了与Perl兼容的正则表达式(PCRE)库。例如,使用grep -PMpcregrep -M

$ pcregrep -M 'Exception message[^\[]+' SystemOut.log
[1/10/16 23:55:33:018 PST] 00000057 ServerObj E   SECJ0373E: Exception message
at com.own.ws.wim.util.UniqueNameHelper.formatUniqueName(UniqueNameHelper.java:102)
at com.own.ws.wim.ProfileManager.getImpl(ProfileManager.java:1569)

这将打印每一行有异常,使用方括号启动新时间戳作为停止模式。您当然可以调整正则表达式以满足您的需要,或者将结果传递给另一个grep以过滤或删除特定的时间戳。

根据您最初发布的语料库,这对我有用。您的里程可能会有所不同。