【问题标题】:How to rename label within a metric in Prometheus如何在 Prometheus 的指标中重命名标签
【发布时间】:2019-01-17 12:18:32
【问题描述】:

我有一个问题:

node_systemd_unit_state{instance="server-01",job="node-exporters",name="kubelet.service",state="active"} 1

我希望标签 name 仅在 node_systemd_unit_state 指标内重命名(或替换)为 unit_name。所以,期望的结果是:

node_systemd_unit_state{instance="server-01",job="node-exporters",unit_name="kubelet.service",state="active"} 1

node-exporters 作业中还有许多其他带有标签名称 name 的指标。这就是为什么我不能在整个工作中使用重新标记配置。

【问题讨论】:

    标签: monitoring prometheus


    【解决方案1】:

    你可以在promQL中使用label_replace函数,但它也会添加标签,不要替换它

    label_replace(
      <vector_expr>, "<desired_label>", "$1", "<existing_label>", "(.+)"
    )
    
    label_replace(
    node_systemd_unit_state{instance="server-01",job="node-exporters",name="kubelet.service",state="active"},
    "unit_name","$1","name", "(.+)"
    )
    

    因此,为避免重复,您可以添加:

    sum(label_replace(
        node_systemd_unit_state{instance="server-01",job="node-exporters",name="kubelet.service",state="active"},
        "unit_name","$1","name", "(.+)"
        )
    )by(unit_name)
    

    【讨论】:

    • 这是不做任何配置更改的方法!
    【解决方案2】:

    我厌倦了所有零散的文档,我觉得我在这篇文章中提供了更好的答案: https://medium.com/@texasdave2/replace-and-remove-a-label-in-a-prometheus-query-9500faa302f0

    替换不是真正的替换

    您的目标是简单地将旧标签名称“old_job_id”替换为新标签名称“new_task_id”。 Prometheus label_replace 将真正“添加”新标签名称。它也会保留旧的标签名称……所以,这可能是个问题,它不是真正的“就地替换”。

    因此,如果您想“添加”新标签名称并“删除”旧标签名称,您需要这样做:

    sum without (old_job_id) (label_replace(metric, "new_task_id", "$1", "old_job_id", "(.*)"))
    

    这是这样写的:

    • sum without (old_job_id) 将从 查询输出

    • metric 是您的指标,例如“node_filesystem_avail_bytes”

    • “new_task_id”是您放置新标签名称的位置

    • “$1”是正则表达式,用于在新标签名称中使用字符串,不要更改 这个

    • “old_job_id”是您放置旧标签的位置,即您想要的标签 摆脱 (.*……. 那个烂摊子是正则表达式,它将取代整个 标签名称

    【讨论】:

      【解决方案3】:

      你可以有多个来源标签,所以:

      - source_labels: [__name__, name]
        regex: "node_systemd_unit_state;(.+)"
        target_label: unit_name
      

      如果标签名称与其他指标/导出器不匹配,您应该向他们提交错误。像这样重新标记应该只是一个临时解决方案,同时正在寻求适当的修复。

      【讨论】:

      • 太棒了!但在这种情况下,我将始终有两个标签:nameunit_name,它们的值每次都相同。我想避免这种重复。
      • 似乎没有办法做到这一点,除了将name 的值临时存储在__tmp_name 标签中,将其从所有指标中删除,然后将其添加回所有指标node_systemd_unit_state 以外的指标。但是编写正则表达式以匹配除node_systemd_unit_state 之外的所有内容将是一个 PITA,整个过程可能不会那么高效。
      【解决方案4】:

      Prometheus 允许在以下位置重命名标签:

      • 公制抓取期间。在这种情况下,您需要在对应的scrape_config 处将以下relabeling rules 添加到metric_relabel_configs 部分:
      metric_relabel_configs:
      - source_labels: [__name__, name]
        regex: "node_systemd_unit_state;(.+)"
        target_label: unit_name
      - source_labels: [__name__, name]
        regex: "node_systemd_unit_state;(.+)"
        target_label: name
        replacement: ""
      

      第一条规则将 name 标签值复制到 unit_name 标签中,用于名称为 node_systemd_unit_state 的指标。对于名称为 node_systemd_unit_state 的指标,第二条规则将 name 标签值设置为空字符串(例如,删除 name 标签)。

      label_join(
        label_join(node_systemd_unit_state, "unit_name", "", "name"),
        "name", "", "non_existing_label"
      )
      

      内部label_join()name 标签复制到unit_name 标签中。外部 label_join() 用空字符串替换原始 name 标签(例如,删除 name 标签)。

      如您所见,label_join() 并不是标签重命名的最佳功能。 label_replace() 也不是标签重命名的最佳功能。虽然 Prometheus 没有为标签重命名提供更好的解决方案,但此类解决方案存在于类似 Prometheus 的系统中,例如 VictoriaMetrics。提供label_move()功能:

      label_move(node_systemd_unit_state, "name", "unit_name")
      

      此外,VictoriaMetrics 还为有条件的重新标记规则提供了if 选项。比如下面的重标注规则和上面的规则是等价的,但是更容易理解和维护:

      metric_relabel_configs:
      - if: 'node_systemd_unit_state{name!=""}'
        source_labels: [name]
        target_label: unit_name
      - if: 'node_systemd_unit_state{name!=""}'
        target_label: name
        replacement: ""
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-02
        • 2022-01-02
        • 1970-01-01
        • 2010-11-04
        • 2020-11-09
        • 1970-01-01
        相关资源
        最近更新 更多