Grafana Loki 中的指标查询(Metric Queries)详解
什么是指标查询
在 Grafana Loki 中,指标查询(Metric Queries)是一种强大的功能,它通过对日志查询结果应用特定函数来生成指标数据。这种机制使得我们可以直接从日志数据中提取有价值的指标信息,为监控和分析提供了更多可能性。
指标查询的核心概念
范围向量聚合(Range Vector Aggregation)
范围向量聚合是 LogQL(Log Query Language)中的一个重要概念,它借鉴了 Prometheus 的设计理念。在 Loki 中,范围向量表示在特定时间范围内选择的日志或标签值集合。
Loki 支持两种类型的范围向量聚合:
- 日志范围聚合(Log Range Aggregations)
- 解包范围聚合(Unwrapped Range Aggregations)
日志范围聚合
日志范围聚合由一个查询语句后跟一个时间范围组成,然后对这个时间范围内的查询结果应用聚合函数。时间范围可以放在日志流选择器之后,也可以放在日志管道的末尾。
常用的日志范围聚合函数包括:
rate(log-range):计算每秒的日志条目数count_over_time(log-range):统计给定时间范围内每个日志流的条目数bytes_rate(log-range):计算每个日志流每秒的字节数bytes_over_time(log-range):统计给定时间范围内每个日志流使用的字节总数absent_over_time(log-range):当指定标签组合在特定时间内不存在任何时间序列和日志流时返回1,否则返回空向量(常用于告警)
示例1:统计 MySQL 作业在过去5分钟内的所有日志行数
count_over_time({job="mysql"}[5m])
示例2:计算 MySQL 作业中过去1分钟内每个主机非超时错误(持续时间超过10秒)的每秒发生率
sum by (host) (rate({job="mysql"} |= "error" != "timeout" | json | duration > 10s [1m]))
偏移修饰符(Offset Modifier)
偏移修饰符允许修改查询中单个范围向量的时间偏移量。
正确用法:
count_over_time({job="mysql"}[5m] offset 5m) // 正确
错误用法:
count_over_time({job="mysql"}[5m]) offset 5m // 错误
解包范围聚合
解包范围聚合使用提取的标签作为样本值,而不是日志行本身。要进行解包范围聚合,日志查询必须以解包表达式结束,并可选择性地添加标签过滤器表达式来排除错误。
解包表达式格式为:| unwrap label_identifier,其中 label_identifier 是用于提取样本值的标签名称。
Loki 支持的解包转换函数:
duration_seconds(label_identifier)(或简写为duration):将标签值从 Go 持续时间格式转换为秒bytes(label_identifier):将标签值转换为原始字节
解包范围聚合支持的函数:
rate(unwrapped-range):计算指定间隔内所有值的每秒总和率sum_over_time(unwrapped-range):计算指定间隔内所有值的总和avg_over_time(unwrapped-range):计算指定间隔内所有值的平均值max_over_time(unwrapped-range):获取指定间隔内的最大值min_over_time(unwrapped-range):获取指定间隔内的最小值- 其他统计函数如标准差、方差、分位数等
解包范围聚合支持分组操作(除 sum_over_time、absent_over_time、rate 和 rate_counter 外):
<aggr-op>([parameter,] <unwrapped-range>) [without|by (<label list>)]
内置聚合运算符
LogQL 支持以下内置聚合运算符:
sum:计算标签值的总和avg:计算标签值的平均值min:获取标签值的最小值max:获取标签值的最大值stddev:计算标签值的总体标准差stdvar:计算标签值的总体方差count:统计向量中的元素数量topk:选择样本值最大的k个元素bottomk:选择样本值最小的k个元素sort:按样本值升序排序sort_desc:按样本值降序排序
聚合运算符可以通过 without 或 by 子句对所有标签值或一组不同的标签值进行聚合:
<aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]
特殊函数
LogQL 提供了一些特殊函数:
vector(s scalar):将标量s作为没有标签的向量返回。主要用于为原本不返回任何内容的序列返回一个值,这在用LogQL定义告警时特别有用。
示例:统计 traefik 命名空间过去5分钟内的所有日志行数,如果没有数据则返回0
sum(count_over_time({namespace="traefik"}[5m])) # 如果没有数据将不返回任何内容
or
vector(0) # 如果没有数据则返回0
概率聚合(实验性功能)
LogQL 的 approx_topk 函数提供了 topk 的概率近似实现。它是 topk 的替代方案,特别适用于以下场景:
topk查询超时或达到最大序列限制时- 排序值列表非常大时
- 需要快速获得近似结果而非精确但较慢的结果时
函数格式:
approx_topk(k, <vector expression>)
实现原理: approx_topk 使用分片实现,底层采用 count-min sketch 算法和堆来近似计算每个分片的计数。近似精度取决于堆的大小(由 max_count_min_sketch_heap_size 参数定义)。当 k 接近堆大小时,精度会降低(默认堆大小为10,000)。
总结
Grafana Loki 的指标查询功能通过将日志数据转化为指标,极大地扩展了日志分析的可能性。无论是简单的计数统计,还是复杂的聚合分析,LogQL 都提供了丰富的语法和函数来满足各种场景的需求。理解这些查询类型和函数的使用方法,将帮助你更高效地从日志数据中提取有价值的信息。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



