指标 relabel 是一个在 Prometheus 里十分重要、高频使用的配置。本文介绍指标 relabel 的基本使用方法和常见示例,帮助您快速入门和上手实操。
背景信息
在 Prometheus 服务中,从目标 Target 中采集到的标准指标格式,如下所示:
http_requests_total{method="POST", handler="/api/v1/vmp", status="200"} 1024
通过指标 relabel,您可以实现以下操作:
- 在原始指标中,新增、修改或删除 label 的 key 或 value。
基础知识
raw job 和 ServiceMonitor/PodMonitor
通常,在 Prometheus 中使用 scrape config 配置需要采集指标的对象。其中,除了 relabel 配置外,还包括服务发现配置。例如在 Kubernetes 环境中,如果需要采集 Node 或 Pod 的指标,则使用kubernetes_sd_config配置服务发现。 由于直接配置 raw job 较为麻烦和不便,在 Kubernetes 中常使用 Prometheus Operator 进行配置管理和下发。Prometheus Operator 实现了几种 CRD,包括 ServiceMonitor 和 PodMonitor,用于进行 Kubernetes 资源的指标采集配置。实际上,ServiceMonitor/PodMonitor 的技术原理也是由 Prometheus Operator 转换成 Prometheus 的 raw job 配置,其本质上依然还是配置kubernetes_sd_config。
说明
使用 raw job 或 ServiceMonitor/PodMonitor 中的 relabelConfig 进行 relabel 配置时,格式上略有区别: - raw job 中的字段为 snake_case,即小写字母下划线连接的方式。
- ServiceMonitor/PodMonitor 中的字段为 驼峰式。
上述区别仅涉及sourceLabels、source_labels和targetLabel、target_label两个字段。
在 Prometheus 指标中,指标名称其实是名为__metric_name__的 label。因此,指标也可以看作一组key: value形式的集合。如下所示:
{__metric_name__="http_requests_total", method="POST", handler="/api/v1/vmp", status="200"} 1024
除此之外,还有一些使用双下划线__开头的 label key,表示系统内置的 label。包括:
- __address__:抓取目标的主机和端口,格式为host:port。
- __scheme__:抓取目标的 URI 方案,如 http 或 https。
- __metrics_path__:抓取目标的指标端点路径。
- __param_<name>:传递给目标的第一个 URL 参数的值,其中<name>是参数名。
- __scrape_interval__:目标的抓取间隔。
- __scrape_timeout__:目标的超时时间。
- __meta_:由服务发现机制设置的特殊标签集。
- __tmp:用于在丢弃前临时存储标签值的特殊前缀。
其中,__meta__表示服务发现配置的内置 label。当您使用kubernetes_sd_config或 ServiceMonitor/PodMonitor 时,内置 label 详情请参见 官方文档。 __meta_kubernetes_node_name
__meta_kubernetes_node_provider_id
__meta_kubernetes_node_label_<labelname>
__meta_kubernetes_node_labelpresent_<labelname>
__meta_kubernetes_node_annotation_<annotationname>
__meta_kubernetes_node_annotationpresent_<annotationname>
__meta_kubernetes_node_address_<address_type>
多个 relabel 阶段
Prometheus 支持使用多个配置实现 relabel 配置,最常用的是relabel_configs和metric_relabel_configs,其配置结构字段均相同,区别在于生效的时机不同。
[ - <relabel_config> ... ]
[ - <relabel_config> ... ]
[ - <relabel_config> ... ]
两者的区别如下:
- relabel_configs在抓取目标 target 的时候生效,也是唯一可以拿到服务发现内置 labels 的配置。在该阶段,除了可以对 labels 进行处理,还可以根据内置的 labels 进行过滤,从而实现服务发现的资源筛选。
- metric_relabel_configs则在抓取到 target 指标之后,存储指标之前生效。如果您使用 Prometheus-agent 组件采集 VKE 集群中的指标,则是指发送指标到 VMP 工作区的 remote-write 阶段之前。
说明
带有双下滑线__前缀的系统 label,会在relabel_configs之后被丢弃。
配置字段
relabel_config里的配置字段,如下表所示。
注意
请特别关注字段中的默认值,一些 relabel 配置中可能由于默认值符合要求,就不会填写该字段,例如action的默认值为replace。如果不清楚这点,往往会看不懂某些配置。
配置示例
说明
假设原始指标为http_requests_total{method="POST", handler="/api/v1/vmp", status="200"} 1024,以下的示例均基于该原始指标。
创建/覆盖 label
使用如下配置,在原始指标中创建或覆盖 label。首先从source_labels指定的源 label(即status)中获取对应的 value,然后将 value 写入到target_label指定的目标 label 中(即status_code)。
- source_labels: [status]
target_label: status_code
说明
- action的默认值为replace,因此该配置中未填写action: replace字段。
- replace字面含义为 替换,实际生效逻辑如下:
- 如果target_label和source_labels的值一致,则表示覆盖source_label。
- 如果target_label定义的 key 不存在,则会默认创建新的 label。
预期得到的指标如下,可以看到在原始指标中,创建了新的标签status_code,其值200为源标签status的值。
http_requests_total{method="POST", handler="/api/v1/vmp", status="200", status_code="200"} 1024
指定 label 的值
在本例中,使用了replacement,表示新增一个固定的 label,value 为replacement里的固定值(如果不配置replacement,则会使用source_labels指定 label 的 value)。
target_label: status_code
预期得到的指标如下,可以看到在原始指标中,创建了新的标签status_code,其值为replacement配置的固定值success。
http_requests_total{method="POST", handler="/api/v1/vmp", status="200", status_code="success"} 1024
说明
由于replacement的默认值为$1,因此replacement可以结合正则表达式实现更灵活的 label 转换,具体可参考下文。
label 值的拼接
使用如下配置,在原始指标中创建新的 label,并获取source_labels列表里对应的 value,然后按照separator定义的分割符拼接起来,作为新 label 的 value。
source_labels: [method, handler]
预期得到的指标如下,可以看到新标签url的值为POST#/api/v1/vmp,即将method和handler的值,使用#符号拼接后的结果。
http_requests_total{method="POST", handler="/api/v1/vmp", status="200", url="POST#/api/v1/vmp"} 1024
使用正则表达式修改 label
replacement除了填写固定值外,还可以通过结合regex来实现较为复杂的转换。配置示例如下:
source_labels: [method, handler]
在本例中,执行逻辑如下:
- 从指标的method和handler获取 value。
- 通过separator定义的分割符,将获取的 value 进行拼接,得到POST#/api/v1/vmp。
- 根据 regex 正则捕获组,得到$1为POST,$2为/api/v1/vmp。
预期得到的指标如下所示。
http_requests_total{method="POST", handler="/api/v1/vmp", status="200", url="/api/v1/vmp POST"} 1024
keep和drop允许基于指标的 label value 过滤指标,支持使用regex。即如果该指标有source_labels对应 label 的 value 值符合regex,则会:
例如:在 Kubernetes 集群里,可以使用如下配置,丢弃服务发现阶段内置的__meta_kubernetes_namespace系统 label 中,值为 test 和 stage 的指标。
- source_labels: [__meta_kubernetes_namespace]
labelkeep和labeldrop和上文中描述的keep/drop字段不一样,其包含label前缀,表示允许基于指标的 label key 过滤指标。例如:
预期得到的指标如下,直接丢弃了原指标中的status标签。
http_requests_total{method="POST", handler="/api/v1/vmp"} 1024
当使用replace对指标的 label 进行转换时,一般需要使用source_labels指定具体的 label。而labelmap提供了一种更加泛用的处理方式,即结合regex和replacement进行批量的格式转换。
例如,在 Kubernetes 服务发现配置中,系统内置标签可能有很多,包括:
__meta_kubernetes_node_name
__meta_kubernetes_node_provider_id
__meta_kubernetes_pod_name
__meta_kubernetes_pod_ip
此时,可以用如下 relabel 配置,批量将这些 Kubernetes 系统内置标签保留到指标里。
regex: "__meta_kubernetes_(.*)"
另外,假设 Pod label 的系统内置标签如下,表示 Kubernetes 服务发现的 Target Pod 里有app=foo的 label:
__meta_kubernetes_pod_label_app: foo
使用如下 relabel 配置,可将 Pod label 的系统内置标签自动添加到指标上。
regex: __meta_kubernetes_pod_label_(.+)
说明
由于replacement默认值为$1,所以这里拿到的是第一个正则捕获组里,即(.+)表示的值。
预期得到的指标为:
http_requests_total{method="POST", handler="/api/v1/vmp", status="200", app="foo"} 1024