LogQL 中的正则表达式 JSON 过滤

Posted

技术标签:

【中文标题】LogQL 中的正则表达式 JSON 过滤【英文标题】:Regexp JSON filtering in LogQL 【发布时间】:2022-01-15 06:23:28 【问题描述】:

我想将 Kibana 查询(like to follow)翻译成 LogQL:

host:("test1-myservice-*") AND level:ERROR 
AND NOT logger_name:"com.example.ExampleClass" 
AND _exists_:stack_trace 
AND NOT stack_trace:(
    "interrupted"
    OR "Read timed out"
    OR "java.lang.InterruptedException"
)

我在 Grafana Explore 中尝试了以下操作,但它没有为我们的 JSON 日志消息返回任何记录:

host=~"test1-myservice-.*" | json 
| logger_name != "com.example.ExampleClass" 
| stack_trace !="" 
| stack_trace =~ ".*InterruptedException.*"

当使用!= 而不是=~ 时,它会返回所有记录:

host=~"test1-myservice-.*" | json 
| logger_name != "com.example.ExampleClass" 
| stack_trace !="" 
| stack_trace !~ ".*InterruptedException.*"

如果我是对的,以下内容适用于文档中的 JSON 日志行的 stack_trace 字段:

字符串类型的工作方式与日志流选择器中使用的 Prometheus 标签匹配器完全相同。这意味着您可以使用相同的操作 (=,!=,=~,!~)。

来源:Label filter expression

以下似乎可行,但似乎很尴尬:

host=~"test1-myservice-.*" | json 
| logger_name != "com.example.ExampleClass" 
| stack_trace !="" 
!~ ".*InterruptedException.*|.*Read timed out.*"
| json

此外,如果我是对的,它会在完整的 JSON 字符串中搜索 InterruptedExceptionRead timed out 子字符串,而不是仅在其 stack_trace 字段中搜索。

是否有更类似于 LogQL 的方式将上面的 Kibana 查询转换为 LogQL? !~ 操作符是否应该在这种情况下工作?

环境:Grafana 7.5.4 / 8.2.3,Loki:2.4.1

【问题讨论】:

【参考方案1】:

不确定您的日志行看起来如何,但我认为您不需要提取标签(通过使用| json

这是一篇关于如何编写查询的非常有用的文章。 how-to-create-fast-queries-with-lokis-logql-to-filter-terabytes-of-logs-in-seconds 如果您想让查询更具可读性,您还可以使用新的Pattern parser 而不是正则表达式。

所以在不知道你的日志行看起来如何的情况下,我认为这应该很好用:

host=~"test1-myservice-.*"
!= "com.example.ExampleClass" 
!~ ".*InterruptedException.*|.*Read timed out.*"

根据您的需要,您还可以使用我之前提到的模式解析器。

【讨论】:

感谢您的回答!第一个链接有一个很好的概述,我还没有完全意识到。我们的日志文件在每一行都包含 JSON 对象。在我的示例中,ExampleClass 仅在 logger_name 字段中搜索,如果我们不隐藏 ExampleClass(如果它出现在另一个字段中,例如冗长的 stack_trace 或与性能相关的 JSON 字段),它看起来更可靠。对与!~ 运算符相关的问题有任何猜测吗?我也稍微更新了问题。 是的 !~json 之后工作,如果这就是你要问的吗? 是的,我已经问过了。感谢支持,终于搞明白了(看我的回答)。 太棒了!很高兴你现在拥有它:)【参考方案2】:

这行得通:

host=~"test1-myservice-.*" | json 
| logger_name != "com.example.ExampleClass" 
| stack_trace !="" 
| stack_trace !~ "(?s).*InterruptedException.*"

注意(?s),它可以匹配正则表达式. 字符的新行。 (JSON 日志消息的stack_trace 字段通常包含多行。)

Log stream selector part of the documentation中也提到了这一点:

注意:=~ 正则表达式运算符是完全锚定的,这意味着正则表达式必须匹配整个字符串,包括换行符。默认情况下,正则表达式 . 字符不匹配换行符。如果您希望正则表达式点字符匹配换行符,您可以使用单行标志,如下所示:(?s)search_term.+ 匹配 search_term\n

【讨论】:

以上是关于LogQL 中的正则表达式 JSON 过滤的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式过滤掉json字符串中的部分键值

正则表达式匹配 C# 中的 Json 数组元素

js正则表达式过滤以指定字符开头以指定字符结尾的文本内容

正则表达式怎么提取json中的value?

javascript-如何在 json 字符串上使用正则表达式来搜索 JQuery 中的数据表列?

请问正则表达式如何过滤超链接和提取链接