使用 group_left 将不同的 node_exporter 内存类型除以总内存

Divide different node_exporter memory types by the total memory using group_left

我想为给定的 instance 创建以下各项消耗的总内存比例的图表:

我知道我可以从 4 个单独的查询创建一个图表,其中每个指标除以 node_memory_MemTotal_bytes{instance="$instance"}:

我觉得 group_left 应该有一种更简洁的方法,因为每个查询的右侧都是相同的,而左侧可以简化为单个查询:

如果我对 the "Operators" docs and this blog post 的理解正确,我应该能够使用 group_left 在单个查询中执行此操作。但是,我一直做不到。

我的理由是,由于等式的左侧和右侧具有完全相同的标签,但不包括 __name__,因此我不需要使用 ignoringon 作为 group_left 运算符:

{__name__=~"node_memory_(MemFree|MemAvailable|Buffers|Cached)_bytes",instance="$instance"}
/
on() group_left node_memory_MemTotal_bytes{instance="$instance"}

这个查询给我一个错误:

"multiple matches for labels: grouping labels must ensure unique matches"

如果我使用 ignoring()on(<labels>)ignoring(<labels>) 的任何其他组合,情况也是如此。我无法理解我在这里缺少的东西,左右不相同 __name__ 是个问题吗?我是否错误地处理了这个问题?

在使用 divideSeries(dividendSeriesList, divisorSeries) function 的 Graphite 中,这个操作非常简单,我当然可以用 PromQL 做同样的事情。

如有任何帮助,我们将不胜感激。

PromQL 在二元运算符的左右两侧匹配时间序列之前去除指标名称,例如 / - 参见 these docs. In your case time series on the left side differ only by metric names, so PromQL sees series with identical sets of labels on the left side. The solution is to copy metric names for left-hand side time series into another label before applying the / operator and then ignoring this label during the / operation. This can be done with label_join or label_replace 函数:

label_join({__name__=~"node_memory_(MemFree|MemAvailable|Buffers|Cached)_bytes",instance="$instance"}, "metric_name", "", "__name__")
/
ignoring(metric_name) group_left() node_memory_MemTotal_bytes{instance="$instance"}