Splunk正则表达式换行器,将多个ERROR [stderr]行合并为一个事件

时间:2019-04-19 18:58:52

标签: java regex docker logging splunk

我正在显示splunk中来自docker json-file的日志。在大多数情况下,除了打印堆栈跟踪时,它都能正常工作。我知道e.printStackTrace()并不是最佳实践,但是我们希望在Splunk中提供一些服务。

我正在配置props.conf文件,并且props.conf中具有以下LINE_BREAKER正则表达式。 LINE_BREAKER=([\n\r]+)\s*{"log":"[0-9]+.*[0-9]\s+

这将匹配以下格式的时间戳记的结尾:{"log":"2019-04-18 15:18:18,796 ERROR [stderr] ...

问题是打印的堆栈跟踪像这样多行出现:

{"log":"2019-04-18 15:18:18,796 ERROR [stderr] (default-threads - 3) java.util.NoSuchElementException: No value present\n","stream":"stdout","time":"2019-04-18T19:18:18.800485539Z"}
{"log":"2019-04-18 15:18:18,804 ERROR [stderr] (default-threads - 3) at java.util.Optional.get(Optional.java:135)\n","stream":"stdout","time":"2019-04-18T19:18:18.806510971Z"}
{"log":"2019-04-18 15:18:19,259 ERROR [stderr] (default-threads - 3) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n","stream":"stdout","time":"2019-04-18T19:18:19.264689098Z"}
{"log":"2019-04-18 15:18:19,259 ERROR [stderr] (default-threads - 3) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n","stream":"stdout","time":"2019-04-18T19:18:19.281810119Z"}
{"log":"2019-04-18 15:18:19,274 ERROR [stderr] (default-threads - 3) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n","stream":"stdout","time":"2019-04-18T19:18:19.28185714Z"}
{"log":"2019-04-18 15:18:19,275 ERROR [stderr] (default-threads - 3) at java.lang.reflect.Method.invoke(Method.java:498)\n","stream":"stdout","time":"2019-04-18T19:18:19.281867696Z"}
{"log":"2019-04-18 15:18:19,275 ERROR [stderr] (default-threads - 3) at org.jboss.weld.interceptor.proxy.TerminalAroundInvokeInvocationContext.proceedInternal(TerminalAroundInvokeInvocationContext.java:49)\n","stream":"stdout","time":"2019-04-18T19:18:19.281875844Z"}
{"log":"2019-04-18 15:18:19,498 ERROR [org.apache.activemq.ActiveMQSession] (default-threads - 3) error dispatching message: : javax.ejb.EJBTransactionRolledbackException\n","stream":"stdout","time":"2019-04-18T19:18:19.523359025Z"}

...等等。直到堆栈跟踪结束。每行最后都是一个基于我的LINE_BREAKER的正则表达式的事件,该事件对于记录器中的INFO消息和单行ERROR消息是很好的,但不适用于上述堆栈跟踪。

我想将此错误[stderr]的堆栈跟踪组合到一个事件中。因此,我的换行符应该匹配,直到下一个不是[stderr]的时间戳记消息为止。

在我的示例中,它应与ERROR [stderr]的第一行匹配,直到:{"log":"2019-04-18 15:18:19,498(上面的最后一个日志行)。

我尝试添加否定的前瞻性,但是现在只能匹配1次。 ([\n\r]+)\s*{"log":"[0-9]+.*[0-9]\s+[\s\S]+\[(?!stderr])匹配到最后一行,但是如果该行下面没有任何一行,则不再匹配。

1 个答案:

答案 0 :(得分:1)

在模式{"log":"[0-9]+.*[0-9]\s+的这一部分中,您正在使用[0-9]+.*[0-9]\s+匹配时间戳部分,这是由于.*首先会匹配到字符串末尾而导致不必要的Bracktracking。 / p>

您可以使模式之类的时间戳更加具体,而不必像[0-9]{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d+

要获得匹配,一种选择是匹配包含stderr的行。然后,将以下各行与该模式的匹配次数重复0次以上,并从换行符开始进行合并。

要保持与其他行的匹配,您可以在ERRORalternation之后使用负前瞻。

^(?:{"log":"[0-9]{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d+ ERROR \[stderr\].*(?:\n{"log":"[0-9]{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d+ ERROR \[stderr\].*)*|{"log":"[0-9]{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d+ ERROR (?!\[stderr\]).*)
  • ^字符串的开头
  • (?:非捕获组
    • {"log":"[0-9]{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d+ ERROR \[stderr\].*
    • (?:非捕获组
      • \n{"log":"[0-9]{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d+ ERROR \[stderr\].*
    • )*关闭非捕获组并重复0次以上
    • |
    • {"log":"[0-9]{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d+ ERROR (?!\[stderr\]).*
  • )关闭非捕获组

Regex demo