解析日志文件并查找堆栈跟踪的正则表达式

9
我正在处理一款古老的Java应用程序,它没有日志记录,并且只将所有信息打印到控制台。大多数异常也通过调用printStackTrace()来“处理”。
简而言之,我刚刚将System.out和System.error流重定向到日志文件中,现在我需要解析该日志文件。到目前为止,一切都好,但我在尝试解析堆栈跟踪时遇到了问题。
部分代码也被混淆了,因此我需要通过一个实用程序来解除堆栈跟踪的混淆。我正在尝试自动化所有这些操作。
到目前为止,我最接近的方法是使用以下内容获取初始异常行:
.+Exception[^\n]+

使用以下方法查找“at ..(..)”行:

(\t+\Qat \E.+\s+)+

但是我不知道如何将它们组合在一起以获取完整的堆栈跟踪。

基本上,日志文件看起来像以下内容。没有固定的结构,堆栈跟踪之前和之后的行完全随机:

Modem ERROR (AT
Owner: CoreTalk
) - TIMEOUT
IN []
Try Open: COM3


javax.comm.PortInUseException: Port currently owned by CoreTalk
    at javax.comm.CommPortIdentifier.open(CommPortIdentifier.java:337)
...
    at UniPort.modemService.run(modemService.java:103)
Handling file: C:\Program Files\BackBone Technologies\CoreTalk 2006\InputXML\notify
java.io.FileNotFoundException: C:\Program Files\BackBone Technologies\CoreTalk 2006\InputXML\notify (The system cannot find the file specified)
    at java.io.FileInputStream.open(Native Method)
...
    at com.gobackbone.Store.a.a.handle(Unknown Source)
    at com.jniwrapper.win32.io.FileSystemWatcher.fireFileSystemEvent(FileSystemWatcher.java:223)
...
    at java.lang.Thread.run(Unknown Source)
Load Additional Ports
... Lots of random stuff
IN []

[Fatal Error] .xml:6:114: The entity name must immediately follow the '&' in the entity reference.
org.xml.sax.SAXParseException: The entity name must immediately follow the '&' in the entity reference.
    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
...
    at com.gobackbone.Store.a.a.run(Unknown Source)
3个回答

8
看起来你只需要把它们粘在一起(并使用换行符作为粘合剂):
.+Exception[^\n]+\n(\t+\Qat \E.+\s+)+

但是我会稍微修改您的正则表达式:
^.+Exception[^\n]++(\s+at .++)+

这个方法会合并at...行之间的空格,并使用所有格量词以避免回溯。


实际上,刚才说的不算数...我有点困惑,但是去掉开头的^符号就可以工作了。异常行肯定在行首,但是没有也能正常工作... - Riaan Cornelius
有时候,堆栈跟踪中会混杂其他行,但我不会费心去处理它。如果需要手动检查这些内容,我们将处理它。堆栈跟踪有时会有前导空格,有时会有制表符。看起来在应用程序中有一些地方是手动打印堆栈跟踪... - Riaan Cornelius
1
@AhmedAkhtar:Regexr的正则表达式引擎不支持占有量词。使用regex101.com进行测试,它更好。 - Tim Pietzcker
谢谢,现在它可以工作了。请问您能否告诉我何时使用所有格量词,何时不使用?即使用 +++ 有什么区别? - Ahmed Akhtar
查看占有量词。一些语言使用原子组代替,它们具有相同的功能(告诉正则表达式引擎不要回溯到匹配的特定部分)。 - Tim Pietzcker
显示剩余4条评论

3

我们一直在使用ANTLR来处理日志文件的解析(在不同的应用领域)。这并不是一项简单的任务,但如果这对您来说是一个关键任务,那么使用ANTLR会比使用正则表达式更好。


这并不是特别关键,只是我在空闲时间做的一些工作,以便我们在需要支持客户时更轻松地阅读日志文件。ANTLR似乎有点过头了。 - Riaan Cornelius
1
@peter.murray.rust 你可能有没有例子可以展示如何在使用ANTLR时解析日志中的堆栈跟踪? - kuldarim

0

我使用它得到了不错的结果

perl -n -e 'm/(Exception)|(\tat )/ && print' /var/log/jboss4.2/debian/server.log 

它会转储所有包含异常或 \tat 的行。由于匹配是同时进行的,因此顺序保持不变。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接