「译文」Prometheus 中的 relabel 是如何工作的?

本文涉及的产品
可观测监控 Prometheus 版,每月50GB免费额度
简介: 「译文」Prometheus 中的 relabel 是如何工作的?

👉️URL: https://grafana.com/blog/2022/03/21/how-relabeling-in-prometheus-works/

✍️Author: Paschalis Tsilias

📝Description:

Relabeling in Prometheus is a powerful tool that allows you to classify and filter targets and metrics.

Relabel(重新标记)是一个强大的工具,允许你通过重写标签集对 Prometheus 目标 (targets) 和指标 (Metrics) 进行分类和过滤。

这篇文章的目的是解释 Prometheus 的 relabel_config 块的价值,可以在 Prometheus 配置的不同地方找到它,以及它在驯服 Prometheus 指标方面的作用。这里的大部分内容也适用于 Grafana Agent 用户。

作为参考,这里是我们的 通过重新标记减少普罗米修斯指标的使用 指南。

因此,不再多说,让我们进入正题吧!

Prometheus labels

标签 (Label) 是一组键值对,允许我们描述和组织 Prometheus 指标中实际测量的内容。

例如,在测量 HTTP 延迟时,我们可以使用 label 来记录返回的 HTTP 方法和状态,哪个端点被调用,以及哪个服务器负责请求。

在 Prometheus 中,键值标签对的每个独特组合都被存储为一个新的时间序列,因此标签对于理解数据的 cardinality 至关重要,应避免将无界的值集作为标签。

内部 labels

但是没有标签的指标怎么办?普罗米修斯也为我们提供了一些 内部 的标签。这些标签以两个下划线开头,并在所有重新标记 (relabel) 步骤应用后被删除;这意味着除非我们明确配置它们,否则它们将不可用。

我们可以使用的这些特殊标签中的一些是

Label name Description
__name__ 被刮削(收集、采集)的 Metric 名称
__address__ 被刮削 target 的 host:port
__scheme__ 被刮削 target 的 URI scheme
__metrics_path__ 被刮削 target 的 Metrics endpoint
__param_<name> 是传递给目标的第一个 URL 参数的值
__scrape_interval__ 目标的刮削间隔(实验性的)。
__scrape_timeout__ 刮削目标超时时间 (实验性的)
__meta_ 由服务发现机制设置的特殊标签集
__tmp 特殊的前缀,用于在丢弃标签值之前临时存储它们

那么现在我们明白了各种 relabel_config 规则的输入是什么,我们如何创建一个 relabel 配置?它们到底能用来做什么?

申请 (Application) 的阶段

围绕重新标记规则的一个混乱来源是,它们可以在 Prometheus 配置文件的多个部分找到。

# 刮削配置列表
scrape_configs:
    - job_name: "some scrape job"
    ...
 
    # target relabel 配置列表。
    relabel_configs:
    [- <relabel_config> ... ]
    # metric relabel 配置列表。
    metric_relabel_configs:
    [- <relabel_config> ... ]
# 与远程写入有关的设置。
remote_write:
    url: https://remote-write-endpoint.com/api/v1/push 
    ...
    # 远程写 relabel 配置的列表。
    write_relabel_configs:
    [- <relabel_config> ... ]
YAML

原因是重新标记可以应用于指标生命周期的不同部分–从选择我们想搜刮的可用目标,到筛选我们想存储在 Prometheus 时序数据库中的内容,以及发送至一些远程存储的内容。

首先,relabel_configs 键可以作为刮削任务定义的一部分被找到。这些重新标记的步骤是在 刮削发生之前 应用的,并且只能访问由 Prometheus 的服务发现添加的标签。它们允许我们过滤由我们的 SD 机制返回的目标,以及操纵它设置的标签。

一旦目标被定义,metric_relabel_configs 步骤将在刮削后应用,并允许我们选择哪些系列 (series) 的数据被纳入 Prometheus 的存储中。

最后,write_relabel_configs 块在数据被发送到远程端点之前,对其应用重新标记规则。这可以用来过滤具有 high cardinality 的指标或将指标路由到特定的远程写入目标。

基本 <relabel_config>

一个 <relabel_config> 由七个字段组成。它们是

  • source_labels
  • separator (default = ;)
  • target_label
  • regex (default = (.*))
  • modulus
  • replacement (default = $1)
  • action (default = replace)

一个 Prometheus 配置可能包含一个重新标记的步骤阵列;它们按照定义的顺序应用于标签集。遗漏的字段采用其默认值,所以这些步骤通常会比较短。

source_labels(源标签列表) 和 separator(分离器)

让我们从 source_labels 开始。它期望值为一个或多个标签名称的数组,用来 选择 各自的标签值。如果我们在 source_labels 数组中提供一个以上的名字,结果将是它们的值的内容,使用提供的 `separator’连接起来。

作为一个例子,考虑以下两个指标

my_custom_counter_total{server="webserver01",subsystem="kata"} 192  1644075044000
my_custom_counter_total{server="sqldatabase",subsystem="kata"} 147  1644075044000
APACHE

下面的 relabel_config:

source_labels: [subsystem, server]
separator: "@"
AVRASM

将提取这些值:

kata@webserver01
kata@sqldatabase
ANGELSCRIPT

regex(正则)

regex字段期望一个有效的 RE2 正则表达式,用于 匹配 source_labelseparator 字段组合中提取的值。该正则表达式支持括号内的捕获组,可以在后面提到。

这个块将 匹配 我们之前提取的两个值

source_labels: [subsystem, server]
separator: "@"
regex: "kata@(.*)"
AVRASM

然而,下面这个区块将 与之前的标签相匹配,并将中止执行这个特定的重新标注步骤:

source_labels: [subsystem, server]
separator: "@"
regex: "(.*)@redis"
AVRASM

默认的 regex 值是(.*),所以如果不指定,它将匹配整个输入。

replacement(替换)

如果提取的值与给定的 regex 相匹配,那么 replacement 就会通过执行 regex 替换和利用任何先前定义的捕获组而得到填充。回到我们的提取值,以及像这样的一个块:

source_labels: [subsystem, server]
separator: "@"
regex: "(.*)@(.*)"
replacement: "${2}/${1}"
AVRASM

将导致捕获 @ 符号之前和之后的内容,将它们对调,并用斜线分开。

webserver01/kata
sqldatabase/kata
BASH

替换的默认值是 $1,所以它将匹配重合词中的第一个捕获组,如果没有指定重合词,则匹配整个提取的值。

target_label(目标 label)

如果 relabel 动作导致一个值被写入某个标签,target_label定义了替换值应该被写入 哪个标签。例如,下面的代码块将设置一个标签,如{env="production"}

replacement: "production"
target_label: "env"
action: "replace"
AVRASM

同时,接着前面的例子,下面这个重新标记的步骤将把 replacement 值设置为 my_new_label:

- source_labels: [subsystem, server]
  separator: "@"
  regex: "(.*)@(.*)"
  replacement: "${2}/${1}"
  target_label: "my_new_label"
  action: "replace"
DTS

结果是:

{my_new_label="webserver01/kata"}
{my_new_label="sqldatabase/kata"}
ABNF

modulus(模数)

最后,modulus 字段期望值是一个正整数。relabel_config 步骤将使用这个数字将 MD5(提取值) % modulus 表达式的结果填充到目标标签中。

可用的 actions(行为)

我们已经走了很长的路,好在我们终于有了进展。现在,我们能用这些积木做什么?它们如何在我们的日常工作中帮助我们?

有七个可供选择的行动,让我们仔细看看。

keep/drop (保留 / 丢弃)

保留和丢弃动作允许我们根据我们的标签值是否与所提供的 relabel 相匹配来过滤掉 目标 (targets) 和 指标 (Metrics)。

让我们回到我们之前的例子:

my_custom_counter_total{server="webserver01",subsystem="kata"} 192  1644075074000
my_custom_counter_total{server="sqldatabase",subsystem="kata"} 14700  1644075074000
APACHE

在连接了 subsystemserver 标签的内容后,我们可以通过使用下面的块丢弃暴露 webserver-01 的目标。

- source_labels: [subsystem, server]
  separator: "@"
  regex: "kata@webserver"
  action: "drop"
DTS

或者,如果我们在一个有多个子系统的环境中,但只想监控 kata,我们可以保留关于它的特定目标或指标,而放弃与其他服务有关的一切:

- source_labels: [subsystem, server]
  separator: "@"
  regex: "kata@(.*)"
  action: keep
DTS

在许多情况下,这里是内部标签发挥作用的地方。

例如,你可以只保留特定的 metric 名称:

- source_labels: [__name__]
  regex: “my_custom_counter_total|my_custom_counter_sum|my_custom_gauge”
  action: keep
YAML

或者如果你使用 Prometheus 的 Kubernetes 服务发现,你可能想从你的 testingstaging命名空间删除所有目标。

- source_labels: [__meta_kubernetes_namespace]
  regex: “testing|staging”
  action: drop
YAML

labelkeep/labeldrop(标签保留 / 标签丢弃)

labelkeep 和 labeldrop 动作允许对标签集本身进行过滤。

在前面的例子中,我们可能对跟踪特定的subsystem 标签不感兴趣了。

下面的重新标记将删除所有的{subsystem="<value>"} 标签,但保留其他标签。

- regex: "subsystem"
  action: labeldrop
DTS

当然,我们可以反其道而行之,只保留一套特定的标签,而放弃其他一切:

- regex: "subsystem|server|shard"
  action: labelkeep
DTS

我们必须确保在应用 labelkeep 和 labeldrop 规则后,所有的 metrics 仍然是唯一的标签。

replace(替换)

替换是重标规则的默认动作,如果我们没有指定的话;它允许我们用 replacement 字段的内容覆盖一个标签的值。

正如我们之前看到的,下面的块将把 env 标签设置为提供的 replacement,所以{env="production"} 将被添加到标签集:

- action: replace
  replacement: production
  target_label: env
NESTEDTEXT

当你把它和其他字段结合起来时,replace动作是最有用的。

下面是另一个例子:

- action: replace
  source_labels: [__meta_kubernetes_pod_name,__meta_kubernetes_pod_container_port_number]
  separator: ":"
  target_label: address
DTS

上面的片段将连接存储 __meta_kubernetes_pod_name__meta_kubernetes_pod_container_port_number的值。然后,提取的字符串将被设置为写入target_label,最终结果是{address="podname:8080}

hashmod(哈希取模)

hashmod 动作提供了一个横向扩展 Prometheus 的机制。

重新标记的步骤是计算连接的标签值的 MD5 哈希值,对一个正整数 N 进行取模,结果是一个范围为 [0, N-1] 的数字。

一个例子可能会使这一点更清楚。请看下面的度量和重新标记步骤:

my_custom_metric{name="node",val="42"} 100
- action: hashmod
  source_labels: [name, val]
  separator: "-"
  modulus: 8
  target_label: __tmp_hashmod
DTS

连接的结果是字符串 “node-42”,字符串模数 8 的 MD5 是5

$ python3
>>> import hashlib
>>> m = hashlib.md5(b"node-42")
>>> int(m.hexdigest(), 16) % 8
5
PYTHON-REPL

所以最终 {__tmp=5} 会被附加到指标的标签集上。

这最常用于将多个目标分散到 Prometheus 实例的集群中。下面的规则可以用来在 8 个 Prometheus 实例之间分配负载,每个实例负责刮取最终在 [0, 7] 范围内产生某个值的目标子集,而忽略其他所有目标。

- action: keep
  source_labels: [__tmp_hashmod]
  regex: 5
NESTEDTEXT

labelmap(标签映射)

labelmap 动作用于将一个或多个标签对映射到不同的标签名称。

任何标签对的名称与所提供的搜索结果相匹配的,将被复制到 replacement 字段中的新标签名称中,利用组引用(${1}${2},等等)。

replacement字段默认为只有$1,即第一个捕获的 relabel,所以它有时会被省略。

这里有一个例子。如果我们使用 Prometheus 的 Kubernetes SD,我们的目标将暂时暴露一些标签,如:

__meta_kubernetes_node_name: 节点对象的名称。
    __meta_kubernetes_node_provider_id: 节点对象的云提供商的名称。
    __meta_kubernetes_node_address_<address_type>: 每个节点地址类型的第一个地址,如果它存在的话。
    __meta_kubernetes_namespace: 服务对象的命名空间。
    __meta_kubernetes_service_external_name: 服务的 DNS 名称。(适用于 ExternalName 类型的服务)。
    __meta_kubernetes_service_name: 服务对象的名称。
    __meta_kubernetes_service_port_name: 目标的服务端口的名称。
    __meta_kubernetes_pod_name: Pod 对象的名称。
    __meta_kubernetes_pod_ip: Pod 对象的 IP。
    __meta_kubernetes_pod_container_init: 如果该容器是一个 InitContainer,则为 true。
    __meta_kubernetes_pod_container_name: 目标地址指向的容器的名称。
SQF

以双下划线开头的标签在应用重新标注步骤后会被普罗米修斯删除,所以我们可以使用 labelmap 通过将它们映射到不同的名称来保留它们。

- action: labelmap
  regex: "__meta_kubernetes_(.*)"
  replacement: "k8s_${1}"
DTS

Prometheus 中重新标记的常见用例

下面是一个关于重新标记的常见用例的小清单,以及在什么地方适合添加重新标记的步骤:

  • 当你想忽略一个子集的应用程序时;使用relabel_config
  • 当在多个 Prometheus 服务器之间分割目标时;使用relabel_config + hashmod
  • 当你想忽略一个高 cardinality 度量的子集时;使用metric_relabel_config
  • 当向不同的端点发送不同的度量时;使用write_relabel_config

Learn more

今天就到此为止吧!希望你学到了一两件关于重标规则的事情,并且你在使用它们时更加得心应手。欲了解更多信息,请查看我们的 文档,并在 Prometheus 文档 中阅读更多信息。

Grafana Cloud 是开始使用指标、日志、跟踪和仪表盘的最简单方法。我们有一个慷慨的永久免费层,并为每一个使用情况提供计划。现在就免费注册

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
相关文章
|
6月前
|
存储 Prometheus Kubernetes
「译文」通过 Relabel 减少 Prometheus 指标的使用量
「译文」通过 Relabel 减少 Prometheus 指标的使用量
|
6月前
|
Prometheus Cloud Native
「译文」如何使用 PromQL join 来更有效地查询大规模的 Prometheus 指标
「译文」如何使用 PromQL join 来更有效地查询大规模的 Prometheus 指标
|
6月前
|
存储 Prometheus Cloud Native
「译文」Prometheus 查询语言 PromQL 简介
「译文」Prometheus 查询语言 PromQL 简介
|
6月前
|
Prometheus Kubernetes Cloud Native
「译文」使用 Prometheus 和 Grafana 实现 SLO
「译文」使用 Prometheus 和 Grafana 实现 SLO
|
Prometheus Cloud Native
Prometheus - Relabel
通过对标签的重命名进行重整操作,便于统一化管理或者服务升级前后管理。
295 0
Prometheus - Relabel
|
Prometheus 监控 Cloud Native
Ceph 监控中应用 Prometheus relabel 功能
1. 问题描述 工作环境中有三个独立的 Ceph 集群,分别负责对象存储、块存储和文件存储。搭建这几个 Ceph 集群时,我对 Ceph 重命名 Cluster name 的难度没有足够的了解,所以使用的都是默认的 cluster name:ceph,不巧的是 Prometheus 的 ceph_exporter 就是用 cluster name 来区分不同集群,结果是 Grafana 中各个集群的数据无法区分,所有的集群数据都绘制在了一个图标中,非常乱不说,而且部分数据还无法正常显示。
1481 0
|
25天前
|
Prometheus 运维 监控
智能运维实战:Prometheus与Grafana的监控与告警体系
【10月更文挑战第26天】Prometheus与Grafana是智能运维中的强大组合,前者是开源的系统监控和警报工具,后者是数据可视化平台。Prometheus具备时间序列数据库、多维数据模型、PromQL查询语言等特性,而Grafana支持多数据源、丰富的可视化选项和告警功能。两者结合可实现实时监控、灵活告警和高度定制化的仪表板,广泛应用于服务器、应用和数据库的监控。
135 3
|
3月前
|
Prometheus 监控 Cloud Native
【监控】prometheus传统环境监控告警常用配置
【监控】prometheus传统环境监控告警常用配置
【监控】prometheus传统环境监控告警常用配置
|
15天前
|
Prometheus 监控 Cloud Native
在 HBase 集群中,Prometheus 通常监控哪些类型的性能指标?
在 HBase 集群中,Prometheus 监控关注的核心指标包括 Master 和 RegionServer 的进程存在性、RPC 请求数、JVM 内存使用率、磁盘和网络错误、延迟和吞吐量、资源利用率及 JVM 使用信息。通过 Grafana 可视化和告警规则,帮助管理员实时监控集群性能和健康状况。
|
24天前
|
Prometheus 运维 监控
智能运维实战:Prometheus与Grafana的监控与告警体系
【10月更文挑战第27天】在智能运维中,Prometheus和Grafana的组合已成为监控和告警体系的事实标准。Prometheus负责数据收集和存储,支持灵活的查询语言PromQL;Grafana提供数据的可视化展示和告警功能。本文介绍如何配置Prometheus监控目标、Grafana数据源及告警规则,帮助运维团队实时监控系统状态,确保稳定性和可靠性。
123 0