LogQL 中的正则表达式 JSON 过滤
Regexp JSON filtering in LogQL
我想将 Kibana 查询转换为 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 中尝试了以下操作,但它没有 return 我们的 JSON 日志消息的任何记录:
{host=~"test1-myservice-.*"} | json
| logger_name != "com.example.ExampleClass"
| stack_trace !=""
| stack_trace =~ ".*InterruptedException.*"
虽然使用 !=
而不是 =~
它 return 所有记录:
{host=~"test1-myservice-.*"} | json
| logger_name != "com.example.ExampleClass"
| stack_trace !=""
| stack_trace !~ ".*InterruptedException.*"
如果我是对的,文档中的以下内容适用于 JSON 日志行的 stack_trace
字段:
String type work exactly like Prometheus label matchers use in log stream selector. This means you can use the same operations (=,!=,=~,!~).
以下似乎有效但看起来很尴尬:
{host=~"test1-myservice-.*"} | json
| logger_name != "com.example.ExampleClass"
| stack_trace !=""
!~ ".*InterruptedException.*|.*Read timed out.*"
| json
此外,如果我是对的,它会在完整的 JSON 字符串中搜索 InterruptedException
和 Read timed out
子字符串,而不是仅搜索其 stack_trace
字段。
是否有更类似 LogQL 的方法将上面的 Kibana 查询转换为 LogQL? !~
运算符在这种情况下应该工作吗?
环境:Grafana 7.5.4 / 8.2.3,Loki:2.4.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.*"
根据您的需要,您还可以使用我之前提到的模式解析器。
这个有效:
{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中也有提到:
Note: The =~
regex operator is fully anchored, meaning regex must match against the entire string, including newlines. The regex .
character does not match newlines by default. If you want the regex dot character to match newlines you can use the single-line flag, like so: (?s)search_term.+
matches search_term\n
.
我想将 Kibana 查询转换为 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 中尝试了以下操作,但它没有 return 我们的 JSON 日志消息的任何记录:
{host=~"test1-myservice-.*"} | json
| logger_name != "com.example.ExampleClass"
| stack_trace !=""
| stack_trace =~ ".*InterruptedException.*"
虽然使用 !=
而不是 =~
它 return 所有记录:
{host=~"test1-myservice-.*"} | json
| logger_name != "com.example.ExampleClass"
| stack_trace !=""
| stack_trace !~ ".*InterruptedException.*"
如果我是对的,文档中的以下内容适用于 JSON 日志行的 stack_trace
字段:
String type work exactly like Prometheus label matchers use in log stream selector. This means you can use the same operations (=,!=,=~,!~).
以下似乎有效但看起来很尴尬:
{host=~"test1-myservice-.*"} | json
| logger_name != "com.example.ExampleClass"
| stack_trace !=""
!~ ".*InterruptedException.*|.*Read timed out.*"
| json
此外,如果我是对的,它会在完整的 JSON 字符串中搜索 InterruptedException
和 Read timed out
子字符串,而不是仅搜索其 stack_trace
字段。
是否有更类似 LogQL 的方法将上面的 Kibana 查询转换为 LogQL? !~
运算符在这种情况下应该工作吗?
环境:Grafana 7.5.4 / 8.2.3,Loki:2.4.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.*"
根据您的需要,您还可以使用我之前提到的模式解析器。
这个有效:
{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中也有提到:
Note: The
=~
regex operator is fully anchored, meaning regex must match against the entire string, including newlines. The regex.
character does not match newlines by default. If you want the regex dot character to match newlines you can use the single-line flag, like so:(?s)search_term.+
matchessearch_term\n
.