;LogQL

LogQL:日志查询语言

LogQL是Grafana Loki的promql启发的查询语言。查询的行为就好像它们是分布式的grep聚合日志源。LogQL使用标签和操作符进行过滤。

LogQL查询有两种类型:

二元操作符

算术运算符

Loki中存在以下二进制算术运算符:

  • +(添加)
  • -(减法)
  • (乘法)
  • /(部门)
  • (模)
  • (能力/取幂)

二元算术运算符定义在两个字面量(标量)之间,一个字面量和一个向量,以及两个向量。

在两个字面量之间,行为是明显的:它们求值为另一个字面量,该字面量是操作符应用于两个标量操作数的结果(1 + 1 = 2).

在向量和字面量之间,操作符应用于向量中每个数据样本的值,例如,如果一个时间序列向量乘以2,结果是另一个向量,其中原始向量的每个样本值乘以2。

在两个向量之间,对左边向量中的每一项和右边向量中的匹配元素应用二进制算术运算符。结果被传播到结果向量中,分组标签成为输出标签集。在右向量中找不到匹配项的项不属于结果的一部分。

特别注意<一个href="#order-of-operations">操作顺序当链接算术运算符时。

算法的例子

使用一个简单的查询实现运行状况检查:

1 + 1

将日志流条目的速率翻倍:

Sum (rate({app="foo"}[1m])) * 2

的警告日志与错误日志的比例喷火应用程序

sum(率({应用= " foo ",水平=“警告”}[1 m])) /笔(率({应用=“foo”,水平=“错误”}[1 m]))

逻辑运算符和集合运算符

这些逻辑/集合二进制运算符只定义在两个向量之间:

  • 而且(十字路口)
  • (工会)
  • 除非(补充)

向量1和向量2结果生成一个由vector1的元素组成的向量,其中vector2中的元素具有完全匹配的标签集。其他元素被删除。

向量1或向量2结果生成一个向量,其中包含vector1的所有原始元素(标签集+值),以及vector2的所有在vector1中没有匹配标签集的元素。

除非vector2结果生成一个由vector1的元素组成的向量,而vector2中没有完全匹配标签集的元素。两个向量中的所有匹配元素都被删除。

二进制运算符示例

这个人工查询将有效地返回这些查询的交集率({应用= "栏"})

率({应用= ~“foo | bar”}[1])和速度({应用=“酒吧”}[1 m])

比较运算符

  • = =(平等)
  • ! =(不平等)
  • >(大于)
  • > =(大于或等于)
  • <(小于)
  • < =(小于或等于)

比较运算符定义在标量/标量、向量/标量和向量/向量值对之间。默认情况下,它们会进行过滤。他们的行为可以通过提供保龄球,它将为值返回0或1,而不是过滤。

在两个标量之间,这些操作符会得到另一个标量,该标量要么为0 (false),要么为1 (true),具体取决于比较结果。的保龄球修饰符必须被提供。

1 >= 1等于1

在向量和标量之间,这些操作符应用于向量中每个数据样本的值,比较结果为假的向量元素将从结果向量中删除。如果保龄球修改符,将被删除的向量元素的值为0,将被保留的向量元素的值为1。

过滤在最后一分钟内记录了至少10行的流:

Count_over_time ({foo="bar"}[1m]) > 10 .输出说明

附加值0/1对于日志记录少于/多于10行的流:

Count_over_time ({foo="bar"}[1m]) > bool 10

在两个向量之间,这些操作符默认情况下充当过滤器,应用于匹配项。表达式不为真或在表达式的另一侧找不到匹配项的向量元素将从结果中删除,而其他元素则传播到结果向量中。如果保龄球修饰符提供后,将被删除的向量元素的值为0,将被保留的向量元素的值为1,分组标签再次成为输出标签集。

返回匹配的流应用= foo没有应用标签在最后一分钟比他们的对手匹配更高的计数应用=酒吧没有应用程序标签:

Sum without(app) ({app="foo"}[1m])) > Sum without(app) (count_over_time({app="bar"}[1m]))

与上面相同,但是向量的值设置为1如果他们通过了比较或者0如果它们失败了/否则就会被过滤掉:

> bool Sum without(app) ({app="foo"}[1m]) (count_over_time({app="bar"}[1m]))

操作顺序

在链接或组合操作符时,必须考虑操作符的优先级:通常,可以假定是常规的<一个href="https://en.wikipedia.org/wiki/Order_of_operations" target="_blank" rel="noopener noreferrer">数学大会相同优先级的操作符是左关联的。

详情请参阅<一个href="https://golang.org/ref/spec" target="_blank" rel="noopener noreferrer">Golang语言文档

1 + 2 / 3等于1 + (2 / 3)

2 * 3% 2被评估为(2 * 3) % 2

关键字on和ignore

忽略关键字会导致在匹配时忽略指定的标签。语法:

 忽略() 

这个示例将返回在最近几分钟内总计数超过app平均值的机器喷火

Max by(machine) (count_over_time({app="foo"}[1m])) > bool忽略(machine) avg(count_over_time({app="foo"}[1m]))

on关键字将考虑的标签集减少到指定的列表中。语法:

  on() 

这个例子将返回应用程序中最后几分钟内的每台机器总数喷火

(机)和(count_over_time({应用=“foo”}[1 m])) /在()和(count_over_time({应用=“foo”}[1 m]))

多对一和一对多向量匹配

当“一”面上的每个向量元素都可以与“多”面上的多个元素匹配时,就会发生多对一和一对多的匹配。必须使用group_left或group_right修饰符显式请求匹配,其中左或右决定哪个向量具有更高的基数。语法:

  ignoring() group_left()    ignoring() group_right()    on() group_left()    on() group_right() 

组修饰符提供的标签列表包含结果度量中包含的来自“one”端的附加标签。所指定的列表中应该只出现一个标签而且group_x.结果向量的每个时间序列必须是唯一可识别的。分组修饰符只能用于比较和算术。缺省情况下,系统匹配而且除非,所有元素都在正确的向量中。

下面的示例返回按分区的速率请求应用程序而且状态占总请求的百分比。

总和(应用程序、地位)(率({工作=“http服务器”}| json(5米)))/ (app) group_left和上(app)(率({工作=“http服务器”}| json[5米 ] ) ) => [ { 应用= " foo "、状态= " 200 "}= > 0.8{应用=“foo”状态= " 400 "}= > 0.1{应用=“foo”状态= " 500 "}= > 0.1)

这个版本使用group_left(< >标签)包括<标识>从结果的右侧返回每个用户、组织和名称空间丢弃事件的代价:

(用户名称空间)和(率({工作=“事件”}| logfmt |丢弃= " true " [5 m])) *(用户)上group_left(组织)max_over_time({工作=“开销计算器”}| logfmt |打开成本[5 m]),(用户、组织)= >[{用户=“foo”,名称空间=“开发”,组织= " little-org "} = > 10{用户=“foo”,名称空间=“刺激”,组织= " little-org "} = > 50{用户=“酒吧”,名称空间=“开发”,组织= " big-org "} = > 70{用户=“酒吧”,名称空间=“刺激”,组织= " big-org "} = > 200)

评论

方法可以注释LogQL查询性格:

{app="foo"} #后面的任何东西都不会在你的查询中被解释

对于多行LogQL查询,查询解析器可以使用

{app="foo"} | json #这一行将被忽略| bar="baz" #检查bar="baz"

管道的错误

造成管道处理错误的原因有很多,比如:

  • 数字标签过滤器可能无法将标签值转换为数字
  • 标签的度量转换可能会失败。
  • 日志行不是有效的json文档。
  • 等等……

当这些故障发生时,洛基不会过滤掉这些日志线。相反,它们被传递到管道的下一个阶段,并带有一个名为的新系统标签__error__.过滤错误的唯一方法是使用标签过滤器表达式。的__error__标签不能通过语言重命名。

例如,要删除json错误:

{cluster="op -tools1",container=" ingess -nginx"} | json | __error__ != "JSONParserErr"

或者,您可以使用catch all匹配器来删除所有错误,例如__error__ = ""甚至只显示错误使用__error__ != ""

过滤器应该放在产生此错误的阶段之后。这意味着如果需要从展开表达式中删除错误,则需要将其放在展开表达式之后。

Quantile_over_time (0.99, {container="ingress-nginx",service=" hosting -grafana"} | json | unwrap response_latency_seconds | __error__=""[1m]) by (cluster)

Metric查询不能包含错误,如果在执行过程中发现错误,Loki将返回一个错误和适当的状态码。

功能

Loki支持对数据进行操作的函数。

label_replace ()

中的每个时间序列v

标签替换(v instant-vector, dst_label字符串,替换字符串,src_label字符串,regex字符串)

匹配正则表达式正则表达式违背标签src_label.如果匹配,则返回带有标签的时间序列dst_label取而代之的是膨胀更换

1美元替换为第一个匹配的子组,2美元第二个等等。如果正则表达式不匹配,则返回不变的时间序列。

本例将返回一个向量,其中每个时间序列都有一个喷火用值标记一个补充:

label_replace(率({工作= " api-server ",服务= " c:} | =“犯错”[1]),“foo”、“$ 1”、“服务 ", "(.*):.*")