比较 Prometheus 中的 2 个指标

Compare 2 metrics in Prometheus

我是 prometheus 的新手,需要帮助。

我的 2 个服务器上有自定义指标(仅显示应用程序版本):

app_version{plant="dev",env="demo"} 55.119
app_version{plant="dev",env="live"} 55.211

我想比较这些指标,如果它们不相等,我会发送警报,尝试这样:

alert: Compare
expr: app_version{env="demo"} != app_version{env="live"}
for: 5s
labels:
  severity: page
annotations:
  summary: Compare

并且此警报为绿色。 比较 2 个指标的正确方法是什么?

env 标签的不同值意味着表达式的每一侧都没有匹配项,因此 returns 没有匹配项,也没有警报。您可以使用 ignoring:

调整此行为
app_version{env="demo"} != ignoring (env) app_version{env="live"}

Prometheus 通过以下方式执行 app_version{env="demo"} != app_version{env="live"} 查询:

  1. 它选择匹配 app_version{env="demo"} 的时间序列。根据 time series selector rules.
  2. ,所有这些时间序列都有名称 app_version 和标签 env="demo"
  3. 它选择匹配 app_version{env="live"} 的时间序列。所有这些时间序列都有名称 app_version 和标签 env="live".
  4. 根据these rules.
  5. 搜索!=算子左右两侧标签相同的时间序列对
  6. 它将找到的时间序列对与 != 运算符进行比较。

遗憾的是,对于查询 app_version{env="demo"} != app_version{env="live"},没有具有相同标签集的时间序列对,因为左侧的所有时间序列都有 env="demo" 标签,而左侧的所有时间序列右侧有 env="live" 标签。这可以通过指示 Prometheus 在根据 these docs 找到匹配的时间序列时忽略 env 标签来解决。有以下选项:

  1. 要枚举标签,在搜索具有相同标签集的时间序列对时必须忽略这些标签,通过 ignoring() 修饰符:
app_version{env="demo"} != ignoring(env) app_version{env="live"}

这个查询很可能也会 return 一个空结果,因为 app_version 时间序列可能因 instance 等其他标签而不同(参见 these docs 关于 instance标签)。虽然可以将 instance 标签添加到 ignoring() 列表中,但下一个选项可能效果更好。

  1. 枚举标签,在搜索具有相同标签集的时间序列对时必须考虑这些标签,通过 on() 修饰符。例如,在查找具有相同标签集的时间序列对时,以下查询将仅考虑 job 标签:
app_version{env="demo"} != on(job) app_version{env="live"}

如果 != 运算符一侧的多个时间序列具有来自 on() 列表的相同标签集,则此查询可能会导致 multiple matches for labelsmany-to-many matching not allowed 错误。例如,如果 Prometheus 从多个目标中抓取应用指标,那么 app_version{env="live"} 可能匹配多个时间序列,这些时间序列是从不同的目标中抓取的:

app_version{env="live",job="my-app",instance="host1"}
app_version{env="live",job="my-app",instance="host2"}

在这种情况下,aggregate functions可用于将多个时间序列转换为单个时间序列或一组时间序列。例如,以下查询将每个具有相同 job 标签的时间序列组的 env="demo" 处的最大版本与 env="live" 处的最小版本进行比较:

max(app_version{env="demo"}) by (job)
  !=
min(app_version{env="live"}) by (job)

另一种选择是使用 group_left()group_right() 修饰符,它们指示将运算符一侧的多个时间序列(例如 != 匹配到运算符一侧的单个时间序列运营商的另一边。有关详细信息,请参阅 these docs。请注意,many-to-many Prometheus 不支持时间序列匹配。

P.S。也可以使用 label_del function if MetricsQL 删除不需要的标签。例如:

label_del(app_version{env="demo"}, "env") != label_del(app_version{env="live"}, "env")