0
点赞
收藏
分享

微信扫一扫

Loki--LogQL学习

小北的爹 2022-09-01 阅读 105

Loki有自己的PromQL-inspired的语言,称为LogQL。LogQL可以看作是grep聚集日志源的分布式,LogQL使用标签和运算符进行过滤。

LogQL查询有两种类型:

1.日志查询返回日志行的内容。- 度量查询扩展了日志查询并根据来自日志查询的日志计数来计算值。
2.基本的日志查询由两部分组成:- 日志流选择器 - 过滤器表达式 由于Loki的设计,所有LogQL查询都必须包含一个日志流选择器。

为避免转义特殊字符,您可以使用​​`代替"。例如`\w+`与"\\w+"相同​​。这在编写包含多个需要转义的反斜杠的正则表达式时特别有用

1.日志流选择器

日志流选择器确定哪些日志流应包含在查询结果中。流选择器由一个或多个键值对组成,其中每个键是一个日志标签,而值是该标签的值。

日志流选择器通过将键值对包装在一对花括号中来编写:

{app="mysql",name="mysql-backup"}

支持以下标签匹配运算符:

=:完全相等。
!=:不相等。
=~:正则表达式匹配。
!~:正则表达式不匹配。

例子:

{name=~"mysql.+"}
{name!~"mysql.+"}
{name!~`mysql-\d+`}

注:适用于Prometheus标签选择器的相同规则也适用 于Loki日志流选择器。

2.过滤器表达式

写入日志流选择器后,可以使用搜索表达式进一步过滤生成的日志集。搜索表达式可以只是文本或正则表达式:

{job="mysql"} |= "error"
{name="kafka"} |~ "tsdb-ops.*io:2003"
{name="cassandra"} |~ `error=\w+`
{instance=~"kafka-[23]",name="kafka"} != "kafka.server:type=ReplicaManager"

在前面的示例中,|=,| ~,和!=充当过滤运算符,支持以下过滤运算符:

|=:日志行包含字符串。
!=:日志行不包含字符串。
|~:日志行匹配正则表达式。
!~:日志行与正则表达式不匹配。

Loki--LogQL学习_运算符

过滤器运算符可以被链接,并将顺序过滤表达式-结果日志行必须满足每个过滤器:

{job="varlogs"} |="0.33" != "0.27"

Loki--LogQL学习_mysql_02

使用|和时!, 可以使用Go RE2语法 regex。默认情况下,该匹配区分大小写,并且可以将regex切换为不区分大小写的前缀(?i)

3.指标查询

LogQL还支持使用允许对每个流计数条目的功能来包装日志查询。

指标查询可用于计算错误消息率或最近3个小时内日志数量最多的N个日志源之类的信息。

4.范围向量聚合

LogQL 与Prometheus 具有相同的范围向量概念,不同之处在于所选的样本范围包括每个日志条目的值1。可以在所选范围内应用聚合,以将其转换为实例向量。

当前支持的操作功能为:

rate:计算每秒的条目数
count_over_time:计算给定范围内每个日志流的条目。
bytes_rate:计算每个流每秒的字节数。
bytes_over_time:计算给定范围内每个日志流使用的字节数。

例子1,本示例对varlogs作业在最近五分钟内的所有日志行进行计数。

count_over_time({job="varlogs"}[5m])

Loki--LogQL学习_运算符_03

例子2,此示例说明,可以使用聚合语法(包括过滤器表达式)包装完整的LogQL查询。本示例获取MySQL作业在过去十秒内所有非超时错误的每秒速率。

rate({job="mysql"} |= "error" != "timeout" [10s] )

应当注意,[5m]可以将范围标记放在日志流过滤器的末尾或日志流匹配器之后。例如,以下两种语法是等效的:

rate({job="mysql"} |= "error" != "timeout" [5m])
rate({job="mysql"}[5m] |= "error" != "timeout")

5.集合运算符

像PromQL一样,LogQL支持内置聚合运算符的子集,可用于聚合单个向量的元素,从而产生一个具有较少元素但具有集合值的新向量:

sum:计算标签上的总和
min:选择最少的标签
max:选择标签上方的最大值
avg:计算标签上的平均值
stddev:计算标签上的总体标准差
stdvar:计算标签上的总体标准方差
count:计算向量中元素的数量
bottomk:通过样本值选择最小的k个元素
topk:通过样本值选择最大的k个元素

聚合运算符可通过包含a without或 by子句用于聚合所有标签值或一组不同的标签值:

<aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]

parameter仅在使用topk和时才需要bottomk。topk与 bottomk其他聚合器的不同之处在于,将输入样本的一个子集(包括原始标签)返回到结果向量中。by 并且without仅用于对输入向量进行分组。

该without子句从结果向量中删除列出的标签,并保留所有其他标签。该by子句执行相反的操作,即删除该子句中未列出的标签,即使它们的标签值在向量的所有元素之间都相同。

例子:

以最高的日志吞吐量获得排名前十的应用程序:

topk(10,sum(rate({region="us-east1"}[5m])) by (name))

获取最近五分钟的日志计数,按级别分组:

sum(count_over_time({job="varlogs"}[5m])) by (level)

从NGINX日志中获取HTTP GET请求的速率:

avg(rate(({job="nginx"} |= "GET")[10s])) by (region)

6.二元运算符

(1).算术二元运算符

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

+ (加成)
- (减法)
* (乘法)
/ (师)
% (取模)
^ (幂/幂)

在两个文字(标量),文字和向量以及两个向量之间定义了二进制算术运算符。

在两个文字之间,其行为是显而易见的:它们求值另一个文字,这是将运算符应用于两个标量操作数(1 +1 = 2)的结果。

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

在两个向量之间,将二进制算术运算符应用于左侧向量中的每个条目,并将其应用于右侧向量中的匹配元素。结果被传播到结果向量中,并且分组标签成为输出标签集。在右侧向量中找不到匹配条目的条目不属于结果。

例子:

通过一个简单的查询实现运行状况检查:

1 + 1

将日志流条目的速率提高一倍:

sum(rate({app="foo"})) * 2

获取该foo应用的警告日志与错误日志的比例:

sum(rate({app="foo", level="warn"}[1m])) / sum(rate({app="foo", level="error"}[1m]))

优先级相同的运算符是左关联的(为简单起见,此处将查询替换为数字)。例如,2 * 3%2等效于(2 * 3)%2。但是,某些运算符具有不同的优先级:1 + 2/3仍将是1 +(2/3)。这些功能与数学惯例相同。

(2).逻辑/集合二元运算符

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

and 
or
unless

例子,返回交集 rate({app="bar"})

rate({app=~"foo|bar"}[1m]) and rate({app="bar"}[1m])

(3).比较运算符

== (平等)
!= (不等式)
> (比...更棒)
>= (大于或等于)
< (少于)
<= (小于或等于)

参考地址:​​https://github.com/grafana/loki/blob/master/docs/logql.md#filter-expression​​

问题故障处理:​​https://github.com/grafana/loki/blob/master/docs/getting-started/troubleshooting.md​​

最佳实践:​https://github.com/grafana/loki/blob/master/docs/best-practices/current-best-practices.md​​


举报

相关推荐

0 条评论