PromQL 入门:选择、速率与聚合
从简单的指标选择器逐步构建出一个真实的查询:按路径计算的错误率,实时计算。
PromQL 是 Prometheus 中每个读取数据的部分,仪表板、告警规则、即席调试,所构建于其上的查询语言。本指南逐步构建一个真实的查询:给定一个按路径、方法和状态拆分的请求计数器,找出每个错误率高于 5% 的路径。
选择时间序列
最简单的 PromQL 表达式就是一个指标名称,它返回具有该名称的每个时间序列的当前值:
http_requests_total
在花括号中添加标签匹配器,把它缩小到一个特定的子集:
http_requests_total{status="500"}
这会返回名为 http_requests_total 且 status 标签恰好为 "500" 的每个序列,无论路径或方法如何。匹配器还可以进行正则匹配(status=~"5.." 匹配任何 5xx 状态)和否定(status!="200"),以及其他操作符。
从计数器到速率
http_requests_total 是一个计数器:它只会增加,所以它的原始值(自进程启动以来某个很大的、不断增长的数字)并不是你真正想看的。你想要的是它增长得有多快,而这正是 rate() 函数所计算的:在给定时间窗口内的每秒平均增长速率。
rate(http_requests_total{status="500"}[5m])
对于每个匹配的序列,这会返回过去 5 分钟内 500 错误的每秒平均速率。一个相关的函数 irate() 只使用范围内最后两个数据点计算瞬时速率,而不是在整个窗口上取平均。irate() 对突然的尖峰反应更快,但也更嘈杂,对单次不寻常的抓取更敏感;rate() 是仪表板、尤其是告警的推荐默认选择,因为在告警中你通常想要的是更平滑、不那么容易被尖峰影响的信号。当你在短时间尺度上观察变化很快的计数器,并希望看到瞬时变化而不是平滑趋势时,才专门使用 irate()。
聚合掉你不关心的标签
rate() 仍然是每个原始时间序列返回一个结果,即路径、方法和状态的每种唯一组合一条线。要得到每个路径一个数字,对存在的任何方法和状态求和,请使用聚合操作符:
sum by (path) (rate(http_requests_total{status="500"}[5m]))
sum by (path) (...) 将速率加总,按 path 标签分组,并丢弃结果中的所有其他标签。这就是 PromQL 聚合的一般形态:挑选一个操作符(sum、avg、max、min、count 等),以及一个指明哪些标签保留到结果中的 by (...) 子句。
用二元操作符组合查询
要把错误率算作百分比,你需要两个聚合查询,错误请求和总请求,彼此相除:
sum by (path) (rate(http_requests_total{status="500"}[5m]))
/
sum by (path) (rate(http_requests_total[5m]))
* 100
PromQL 通过剩余的标签,这里是 path,来匹配二元运算的两侧,为每个匹配的配对计算除法,而不要求你手工对齐它们。乘以 100 把得到的比值变成百分比。
过滤结果本身
包裹整个表达式,只保留真正越过阈值的结果:
(
sum by (path) (rate(http_requests_total{status="500"}[5m]))
/
sum by (path) (rate(http_requests_total[5m]))
* 100
) > 5
这只返回其计算出的错误百分比当前高于 5 的路径,这正是你会把它包进告警规则、在它为真时呼叫某人的那种查询形态。
把查询变成告警
告警规则是一个 PromQL 表达式,加上描述当它求值得到某个结果时该做什么的元数据:
groups:
- name: example-alerts
rules:
- alert: HighErrorRatePerPath
expr: |
(
sum by (path) (rate(http_requests_total{status="500"}[5m]))
/
sum by (path) (rate(http_requests_total[5m]))
* 100
) > 5
for: 10m
labels:
severity: page
annotations:
summary: "Error rate above 5% on {{ $labels.path }}"
for: 10m 要求条件持续为真 10 分钟,告警才真正触发,这避免了为一次短暂的、自行消失的波动而呼叫人。Prometheus 持续评估这样的规则,并把当前触发的任何东西交给 Alertmanager,这与你本会直接放入 Grafana 面板的 PromQL 是同一个,只是包上了名称、持续时间和路由元数据。
接下来去哪里
这涵盖了即时向量、速率计算、聚合和二元操作符,足以阅读和编写你在现有仪表板和告警中遇到的绝大多数查询。PromQL 还有更多内容(除 rate 之外的范围向量函数、子查询、更多聚合操作符),Prometheus 自己的查询参考有很好的文档,在你编写最初几个真实查询时值得一直开着它。