Prometheus 查询:缺少标签时如何给出默认标签?

问题描述 投票:0回答:4

我正在尝试使用 Prometheus 的

hwmon
和 Grafana 绘制服务器的温度图表。

与此相关的是

prometheus-node-exporter
提供的 2 个时间序列:

  • node_hwmon_temp_celsius
    有实际温度;它有这样的标签:
    • {chip="platform_coretemp_0",sensor="temp1"}
  • node_hwmon_sensor_label
    ,它是具有名称的温度传感器的辅助时间序列(Prometheus 标签称为
    label
    ):
    • {chip="platform_coretemp_0",sensor="temp1",label="core_0"}

https://github.com/prometheus/node_exporter/issues/631 上有这样的解释:

标签并非适用于所有传感器。如果所有传感器都有标签,您可以执行以下操作来加入它们:

node_hwmon_temp_celsius{...} * ignoring(label) group_left(label) node_hwmon_sensor_label

但我的一些传感器没有标签。在这种情况下,上面的 PromQL 查询没有帮助;在这种情况下,

group_left(label)
不会返回任何结果。

相反,我想编写一个始终存在

label
标签的温度查询,如果缺少 unknown-sensor-name 标签,则
defaults
label

如何使用 PromQL 做到这一点?

prometheus prometheus-node-exporter
4个回答
4
投票

我终于找到了一个解决方案(不确定是否是最佳的):

(
    # For all sensors that have a name (label "label"), join them with `node_hwmon_sensor_label` to get that name.
    (node_hwmon_temp_celsius * ignoring(label) group_left(label) node_hwmon_sensor_label)
  or
    # For all sensors that do NOT a name (label "label") in `node_hwmon_sensor_label`, assign them `label="unknown-sensor-name"`.
    # `label_replace()` only adds the new label, it does not remove the old one.
    (label_replace((node_hwmon_temp_celsius unless ignoring(label) node_hwmon_sensor_label), "label", "unknown-sensor-name", "", ".*"))
)

我是如何到达那里的:

  • 查找所有没有标签
    label
    的时间序列本质上相当于 SQL 中的
    OUTER JOIN
    ;在 Google 上搜索 PromQL,我发现了问题 有没有办法在 PromQL 中执行“左外连接”之类的查询? 这解释了这是 PromQL 中的
    unless
  • 现在我们需要添加常数
    label="unknown-sensor-name"
    。我们可以使用
    label_replace()
    来做到这一点,这可能会令人困惑,它只是真正添加了一个新标签,而不会删除旧标签(如here所述)。我们可以将最后 2 个参数保留为
    ""
    ,因为我们只添加一个常量字符串,因此我们可以匹配任何现有标签。
  • 最后,我们可以使用
    or
    将其与“如果所有传感器都有标签”系列联合起来。

完成。


如果需要,我们还可以通过添加以下内容将其与计算机的主机名连接起来:

* on(instance) group_left(nodename) node_uname_info

这在 https://blog.ruanbekker.com/cheatsheets/prometheus/在 Prometheus 中将实例重新标记为主机名中进行了描述。

这样,在 Grafana 中,我们可以使用

{{nodename}} {{chip}} {{label}}
作为图表的图例。


Grafana 中的示例(显示

instance
而不是
nodename
):


3
投票

只需将推荐的查询包装到 label_replace() 函数中即可:

label_replace(
  node_hwmon_temp_celsius
    * ignoring(label) group_left(label)
  node_hwmon_sensor_label,
  "label",
  "unknown-sensor-name",
  "label",
  ""
)

label_replace()
搜索缺失的
label
值,然后用
label="unknown-sensor-name"
替换它们。它不会更改现有的
label
值,因为它们与
label_replace()
最后一个参数中提供的空正则表达式不匹配。 Prometheus 自动将正则表达式锚定到字符串的开头和结尾,例如实际上它使用
^$
正则表达式,它只匹配空字符串。


1
投票

您可以利用

label_replace
允许您提供正则表达式匹配作为替换的要求,并且仅当它与空字符串匹配(即不存在标签)时才进行替换:

label_replace(
  <your metric>,
  <label>,
  <default value>,
  <label>,
  "^$"
)

或者具体针对您的情况:

label_replace(
  <your metric>,
  "label",
  "unknown-sensor-name",
  "label",
  "^$"
)

其中

^
是正则表达式中使用的特殊字符,表示字符串的开头,
$
与字符串的结尾相同。


0
投票

通过为缺失的标签添加“默认”值来处理此问题的更好方法。

      relabelings
        - sourceLabels:[__meta_xx_name]
          targetLabel: label_name   
        - sourceLabels:[__meta_xx_name]
          targetLabel: label_name
          replacement: unknown
          regex: ^$

如果面板变量因缺少此标签而受到影响,这也会很有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.