如何在Prometheus中重命名指标中的标签

29

我有一个问题:

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

我希望将标签namenode_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的其他度量标准。这就是为什么我不能在整个作业中使用重新标记配置。

5个回答

34

您可以在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)

3
这是一种不需要进行任何配置更改的方法! - Deepak Deore
如果我想要更改指标的实际名称(例如__name__),而不是常规标签,该怎么办? - jayarjo

17

我厌倦了所有零散的文档,感觉在这篇文章中提供了更好的答案:

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", "(.*)"))

以下是翻译:

  • 没有(old_job_id)的求和将从查询输出中删除旧标签名称

  • 度量值是您的度量,例如“node_filesystem_avail_bytes”

  • “new_task_id” 是您要放置新标签名称的地方

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

  • “old_job_id” 是您要去掉的旧标签的位置(.*……. 这个混乱的东西是正则表达式,将替换整个标签名称


7
您可以拥有多个来源标签,因此:
- source_labels: [__name__, name]
  regex: "node_systemd_unit_state;(.+)"
  target_label: unit_name

如果标签名称与其他指标/导出工具不匹配,您应该向它们报告错误。这样的重新标记只应该是在寻求适当解决方案的同时的临时解决方案。

1
太好了!但是在这种情况下,我总是会有两个标签:nameunit_name,而它们的值每次都相同。我想避免这种重复。 - Konstantin Vustin
除了暂时将“name”的值存储在“__tmp_name”标签中,从所有指标中删除它,然后将其添加回除“node_systemd_unit_state”之外的所有指标之外,似乎没有其他方法来实现这一点。但编写匹配除“node_systemd_unit_state”之外的所有内容的正则表达式可能会很麻烦,整个过程可能并不是非常高效。 - Alin Sînpălean

2
Prometheus允许在以下位置重命名标签:
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标签的值复制到具有node_systemd_unit_state名称的指标的unit_name标签中。第二条规则将name标签的值设置为空字符串(例如,删除name标签)对于具有node_systemd_unit_state名称的指标。
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: ""

2
你应该声明一下你是VictoriaMetrics的CTO。 - nouney
谢谢,已经相应地更新了答案。 - valyala

0

https://demo.promlens.com/?q=label_replace(up%2C%20%22hostname%22%2C%20%22%241%22%2C%20%22instance%22%2C%20%22(.%2B)%3A(%5C%5Cd%2B)%22)

假设您有一个名为up的度量标准。
up{instance="cadvisor:8080", job="cadvisor"}    
up{instance="demo-service-0:10000", job="demo"} 
up{instance="demo-service-1:10001", job="demo"} 
up{instance="demo-service-2:10002", job="demo"} 
up{instance="docker-hub-exporter:9170", job="docker-hub-exporter"}  
up{instance="node-exporter:9100", job="node"}   
up{instance="prometheus:9090", job="prometheus"}

现在查询
label_replace(up, "hostname", "$1", "instance", "(.+)-(.+)-(\\d+):(\\d+)")
将返回带有第一个匹配组("$1")的新标签 hostname。

up{instance="cadvisor:8080", job="cadvisor"}    
up{hostname="demo", instance="demo-service-0:10000", job="demo"}
up{hostname="demo", instance="demo-service-1:10001", job="demo"}
up{hostname="demo", instance="demo-service-2:10002", job="demo"}
up{instance="docker-hub-exporter:9170", job="docker-hub-exporter"}
up{instance="node-exporter:9100", job="node"}
up{instance="prometheus:9090", job="prometheus"}

查询
label_replace(up, "hostname", "$2", "instance", "(.+)-(.+)-(\\d+):(\\d+)")
将返回一个新的标签主机名,其中包含正则表达式的第二个匹配组("$2")。

up{instance="cadvisor:8080", job="cadvisor"}    
up{hostname="service", instance="demo-service-0:10000", job="demo"} 
up{hostname="service", instance="demo-service-1:10001", job="demo"} 
up{hostname="service", instance="demo-service-2:10002", job="demo"} 
up{instance="docker-hub-exporter:9170", job="docker-hub-exporter"}  
up{instance="node-exporter:9100", job="node"}   
up{instance="prometheus:9090", job="prometheus"}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接