我有一个疑问:
node_systemd_unit_state{instance="server-01",job="node-exporters",name="kubelet.service",state="active"} 1
我希望仅在
name
指标内将标签 unit_name
重命名(或替换)为 node_systemd_unit_state
。所以,期望的结果是:
node_systemd_unit_state{instance="server-01",job="node-exporters",unit_name="kubelet.service",state="active"} 1
在
name
作业中还有许多其他带有标签名称 node-exporters
的指标。这就是为什么我不能在整个工作中使用重新标记配置。
你可以使用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)
我厌倦了所有零散的文档,我觉得我在这篇文章中提供了更好的答案: 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) 的 sum 将从中删除旧标签名称 查询输出
metric 是您的指标,例如“node_filesystem_avail_bytes”
“new_task_id”是您放置新标签名称的位置
“$1”是在新标签名称中使用字符串的正则表达式,不要更改 这个
“old_job_id”是您放置旧标签的地方,即您想要的标签 摆脱 (.*……. 这个混乱是正则表达式,它将取代整个 标签名称
您可以拥有多个源标签,因此:
- source_labels: [__name__, name]
regex: "node_systemd_unit_state;(.+)"
target_label: unit_name
如果标签名称与其他指标/导出器不匹配,您应该向他们提交错误。像这样重新标记应该只是一个临时解决方案,同时正在寻求适当的解决方案。
Prometheus 允许在以下位置重命名标签:
scrape_config的
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
标签中。第二条规则将具有 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: ""
假设您有指标
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+)")
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+)")
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"}