【问题标题】:How can I capture Java exceptions, including the stack trace, from a log file using grep?如何使用 grep 从日志文件中捕获 Java 异常,包括堆栈跟踪?
【发布时间】:2016-01-14 11:18:20
【问题描述】:

总结

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

知道如何实现吗?

【问题讨论】:

  • grep 不是提取文本块的正确工具。您可能会发现 awk 更容易完成这项任务。
  • 如果我错了,有人纠正我,但 grep 不可能,因为 grep 是在每行的基础上工作的?并且堆栈跟踪具有多行签名。

标签: java unix exception grep stack-trace


【解决方案1】:

(来自我的回答:https://stackoverflow.com/a/16064081/430128)

这是一个简单粗暴的 grep 表达式...如果您使用诸如 log4j 之类的记录器,则异常的第一行通常包含 WARN 或 ERROR,下一行将包含异常名称和可选的消息,然后后续的堆栈跟踪将以下列之一开始:

  1. "\tat" (tab + at)
  2. "Caused by: "
  3. "\t... <some number> more"(这些行表示堆栈中未显示在“由”异常中的帧数)
  4. 堆栈前的异常名称(可能还有消息)

我们要获取上面所有的行,所以 grep 表达式为:

grep -P "(WARN|ERROR|^\tat |Exception|^Caused by: |\t... \d+ more)"

它假定 Exception 类始终包含单词 Exception,这可能是真的,也可能不是,但这毕竟是快速和肮脏的。

根据您的具体情况进行调整。

【讨论】:

  • 是的,它是逐行操作的,所以可以随意通过这个表达式来输出tail的输出......
【解决方案2】:

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

在您的原始帖子中,您显示了一个三行条目。如果您知道每个带有堆栈跟踪的异常消息正好是三行,那么您可以使用 --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 -PM 或 pcregrep -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 以过滤特定的时间戳。

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

【讨论】:

    猜你喜欢
    • 2021-09-10
    • 1970-01-01
    • 2015-03-17
    • 2018-11-25
    • 2021-09-10
    • 1970-01-01
    • 2021-03-18
    • 2010-12-20
    • 2013-02-21
    相关资源
    最近更新 更多