PromQL如何统计标签值并将结果用于后续查询(金丝雀部署场景)
问题背景
搭建Grafana仪表盘展示金丝雀应用性能时,需识别当前运行的金丝雀实例所属的Blue/Green部署栈。已知金丝雀发布规则为同一时间仅启动Blue或Green其中一类实例,现有计数查询可判断运行中的栈类型,但无法提取对应标签值供后续查询复用:
(count(bound(cfstack=".*Blue.*")) == 1) or ( count(bound(cfstack=".*Green.*")) == 1)
目标实现逻辑:先通过计数判断当前生效的栈,再自动匹配对应cfstack标签值查询bound指标,对应伪代码如下:
if ( count(bound(cfstack=".*Blue.*")) == 1 ) cfstack_val=".*Blue.*" else if ( count(bound(cfstack=".*Green.*")) == 1 ) cfstack_val=".*Green.*" bound(cfstack="${cfstack_val}")
实现方案
无需编写嵌套判断逻辑,直接通过PromQL的标签分组计数+集合匹配算子即可实现,查询语句如下:
bound(cfstack=~".*Blue.*|.*Green.*") and on(cfstack) (count by (cfstack) (bound(cfstack=~".*Blue.*|.*Green.*")) == 1)
逻辑说明
- 第一部分
bound(cfstack=~".*Blue.*|.*Green.*")会先拉取所有Blue、Green栈对应的bound指标序列 - 第二部分
count by (cfstack) (bound(cfstack=~".*Blue.*|.*Green.*")) == 1会按cfstack标签分组统计实例数,仅保留实例数为1的栈对应的序列 and on(cfstack)算子会按cfstack标签做两侧序列的关联匹配,最终仅返回实例数为1的那个Blue/Green栈对应的bound指标结果,完全满足自动识别当前生效栈的需求。
Grafana多面板复用优化
如果需要在仪表盘多个面板中复用识别出的栈值,可以创建一个Prometheus类型的Grafana变量,变量查询语句填写:
label_values( bound(cfstack=~".*Blue.*|.*Green.*") and on(cfstack) (count by (cfstack) (bound(cfstack=~".*Blue.*|.*Green.*")) == 1), cfstack )
后续所有面板直接通过bound(cfstack="${cfstack}")引用该变量即可,无需重复编写过滤逻辑。
内容的提问来源于stack exchange,提问作者Roopchand
相关产品推荐
相关产品推荐

