如何在Grafana单图表展示多组自定义配对指标?
我有大量成对的自定义指标,格式如下:
Request_GetData_XXXX_duration_seconds_sum Request_GetData_XXXX_duration_seconds_count Request_GetData_YYYY_duration_seconds_sum Request_GetData_YYYY_duration_seconds_count
其中XXXX、YYYY是可变标识,指标始终以_sum和_count成对出现。
目前在Grafana里,单指标的平均请求时长查询能正常运行:
sum by (container) ( rate(Request_GetData_XXXX_duration_seconds_sum{}[5m]) / rate(Request_GetData_XXXX_duration_seconds_count{}[5m]) )
我还创建了变量myVar_metrics,通过表达式{name=~"Request_GetData_.*_seconds_count$"}和正则/(.+)_count{/提取出指标前缀列表:
- Request_GetData_XXXX_duration_seconds
- Request_GetData_YYYY_duration_seconds
用这个变量的单指标查询也没问题:
sum by (container) (rate(${myVar_metrics}_sum{}[5m]) / rate(${myVar_metrics}_count{}[5m]))
但开启变量的「多值」和「全选」选项后图表就失效了,需要实现单个图表展示所有这类指标的曲线。
方法一:直接用PromQL匹配所有指标(无需变量多值)
不用依赖变量的多值选择,直接写一条PromQL就能一次性处理所有成对指标,同时给每个系列加上标识区分:
sum by (container, metric_name) ( label_replace(rate({name=~"Request_GetData_.*_seconds_sum$"}[5m]), "metric_name", "$1", "name", "(Request_GetData_.+_duration_seconds)_sum") / label_replace(rate({name=~"Request_GetData_.*_seconds_count$"}[5m]), "metric_name", "$1", "name", "(Request_GetData_.+_duration_seconds)_count") )
这条语句的逻辑:
- 用
name=~匹配所有_sum和_count结尾的目标指标 - 通过
label_replace从指标名里提取出前缀(比如Request_GetData_XXXX_duration_seconds)作为metric_name标签 - 最后按
container和metric_name聚合,不同指标的曲线会自动分开显示在图表里
方法二:适配变量多值的查询语句
如果一定要用变量的多值全选功能,需要调整查询语句适配Grafana的多值展开逻辑:
先确认变量的正则提取逻辑,比如可以把正则改成
/Request_GetData_(.+)_duration_seconds_count/,让变量值直接是XXXX、YYYY(保留原前缀也不影响)。修改查询语句,用
${myVar_metrics:regex}把多值转成正则匹配,同时保留指标标识:
sum by (container, metric_name) ( label_replace( rate({name=~"${myVar_metrics:regex}_sum$"}[5m]), "metric_name", "$1", "name", "(Request_GetData_.+_duration_seconds)_sum" ) / label_replace( rate({name=~"${myVar_metrics:regex}_count$"}[5m]), "metric_name", "$1", "name", "(Request_GetData_.+_duration_seconds)_count" ) )
${myVar_metrics:regex}会把选中的多值变量转换成正则表达式,匹配所有对应的_sum和_count指标,再通过label_replace给每个系列加上metric_name标签区分。
如果你的Prometheus版本在v2.47以上,还可以用更简洁的foreach语法:
foreach ${myVar_metrics} as $metric ( sum by (container) (rate(${metric}_sum{}[5m]) / rate(${metric}_count{}[5m])) )
这条语句会自动遍历变量选中的所有指标前缀,分别计算平均值并生成对应曲线。
内容的提问来源于stack exchange,提问作者b166ir in the matrix

