如何用Logstash的Grok或正则将Java堆栈跟踪日志合并为单个文档?
合并Java堆栈跟踪日志的Grok模式与正则方案
正则表达式方案
Java堆栈跟踪的核心特征是:首行是异常类型+消息,后续行均以空格开头,且以at、Caused by:或Suppressed:标识。针对这个特征,可以用以下正则捕获完整的堆栈跟踪:
^(?:\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3})?\s*(.*Exception.*)(?:\n\s+(?:at|Caused by:|Suppressed:).*)*
各部分说明:
(?:\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3})?:匹配可选的日志时间戳(可根据你的实际日志格式调整)\s*(.*Exception.*):捕获异常起始行,包含完整的异常类型和错误消息(?:\n\s+(?:at|Caused by:|Suppressed:).*)*:匹配所有后续堆栈行,包括调用栈、根异常(Caused by)和抑制异常(Suppressed)
Grok模式方案
如果使用Logstash这类支持Grok的工具,可以结合预定义模式和自定义逻辑实现:
基础Grok模式
%{TIMESTAMP_ISO8601:log_timestamp}?\s*%{DATA:exception}(?:\n\s+(?:at|Caused by:|Suppressed:)\s*%{DATA:stack_frame})*
结合Multiline插件的完整配置
要先将分散的堆栈行合并为单个文档,需要配合multiline插件(以Logstash为例):
filter { multiline { pattern => "^%{TIMESTAMP_ISO8601}" negate => true what => "previous" } grok { match => { "message" => "%{TIMESTAMP_ISO8601:log_timestamp}%{SPACE}%{JAVA_EXCEPTION:exception}(?:\n%{SPACE}%{JAVA_STACKTRACE_LINE:stack_lines})*" } } }
multiline插件:将不以时间戳开头的行(堆栈后续行)合并到前一行,形成完整的单条堆栈事件grok部分:利用预定义的JAVA_EXCEPTION和JAVA_STACKTRACE_LINE模式,快速解析异常信息和堆栈内容
注意事项
- 如果你的日志时间戳格式与
TIMESTAMP_ISO8601不匹配,需自定义时间戳的Grok模式或正则 - 堆栈中的
... n more缩写行也会被上述模式自动覆盖 - 多层嵌套的
Caused by异常也能被完整捕获
内容的提问来源于stack exchange,提问作者Gelder Das Geld
相关产品推荐
相关产品推荐

