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

igsr9ssn  于 2022-11-23  发布在  Unix
关注(0)|答案(2)|浏览(182)

摘要

我正在尝试使用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

你知道怎么做到吗?

lnxxn5zx

lnxxn5zx1#

(From我回答是:(第10页)
下面是一个简单的grep表达式...如果您使用log4j之类的记录器,则异常的第一行通常会包含WARNERROR,下一行将包含异常名称和可选的消息,然后后续的堆栈跟踪将以下列内容之一开始:

  1. "\tat"(定位字符+ at
  2. "Caused by: "
  3. "\t... <some number> more"(这些行指示堆栈中未在“Caused by”异常中显示的帧数)
    1.堆栈前的异常名称(可能还有消息)
    我们想得到上面所有的行,所以grep表达式是:
grep -P "(WARN|ERROR|^\tat |Exception|^Caused by: |\t... \d+ more)"

它假设Exception类总是包含单词Exception,这可能是也可能不是真的,但这毕竟是快速和肮脏的。
根据具体情况进行必要的调整。

pn9klfpd

pn9klfpd2#

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

在你的原始文章中,你展示了一个三行的条目。如果你知道每个带有堆栈跟踪的异常消息正好是三行,那么你可以使用--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)

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

但是,如果您不知道堆栈跟踪中有多少行,那么您需要一个带有stop-pattern的多行正则表达式。为此,您需要一个带有编译的Perl兼容正则表达式(PCRE)库的grep。例如,对于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以过滤特定的时间戳。
考虑到你最初发布的语料库,这对我很有效。你的里程可能会有所不同。

相关问题