指标 relabel 是一个在 Prometheus 里十分重要、高频使用的配置。本文介绍指标 relabel 的基本使用方法和常见示例,帮助您快速入门和上手实操。
在 Prometheus 服务中,从目标 Target 中采集到的标准指标格式,如下所示:
http_requests_total{method="POST", handler="/api/v1/vmp", status="200"} 1024
通过指标 relabel,您可以实现以下操作:
通常,在 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 配置时,格式上略有区别:
上述区别仅涉及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。包括:
__name__
:被抓取指标的名称。__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>
Prometheus 支持使用多个配置实现 relabel 配置,最常用的是relabel_configs
和metric_relabel_configs
,其配置结构字段均相同,区别在于生效的时机不同。
scrape_configs: - job_name: "test" ... relabel_configs: [ - <relabel_config> ... ] metric_relabel_configs: [ - <relabel_config> ... ] remote_write: write_relabel_configs: [ - <relabel_config> ... ]
两者的区别如下:
relabel_configs
在抓取目标 target 的时候生效,也是唯一可以拿到服务发现内置 labels 的配置。在该阶段,除了可以对 labels 进行处理,还可以根据内置的 labels 进行过滤,从而实现服务发现的资源筛选。metric_relabel_configs
则在抓取到 target 指标之后,存储指标之前生效。如果您使用 Prometheus-agent 组件采集 VKE 集群中的指标,则是指发送指标到 VMP 工作区的 remote-write 阶段之前。说明
带有双下滑线__
前缀的系统 label,会在relabel_configs
之后被丢弃。
relabel_config
里的配置字段,如下表所示。
字段 | 说明 |
---|---|
source_labels | 配置源 label 的 key,数组形式,支持填写多个 label。 |
separator | 指定源 label 的 value 使用的分隔符,需要配合source_labels 里多个 label 使用。 |
target_label | 配置目标 label 的 key。 |
regex | 正则表达式,可用于 label 匹配或者修改,默认为(.*) ,即匹配所有。 |
replacement | 用于 label 的替换,默认为$1 。 |
| 在 label 上执行的操作,支持操作 label 的 key 或 value,包括:
|
注意
请特别关注字段中的默认值,一些 relabel 配置中可能由于默认值符合要求,就不会填写该字段,例如action
的默认值为replace
。如果不清楚这点,往往会看不懂某些配置。
说明
假设原始指标为 http_requests_total{method="POST", handler="/api/v1/vmp", status="200"} 1024
,以下的示例均基于该原始指标。
使用如下配置,在原始指标中创建或覆盖 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
在本例中,使用了replacement
,表示新增一个固定的 label,value 为replacement
里的固定值(如果不配置replacement
,则会使用source_labels
指定 label 的 value)。
- action: replace replacement: "success" 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,并获取source_labels
列表里对应的 value,然后按照separator
定义的分割符拼接起来,作为新 label 的 value。
- action: replace source_labels: [method, handler] separator: "#" target_label: url
预期得到的指标如下,可以看到新标签url
的值为POST#/api/v1/vmp
,即将method
和handler
的值,使用#
符号拼接后的结果。
http_requests_total{method="POST", handler="/api/v1/vmp", status="200", url="POST#/api/v1/vmp"} 1024
replacement
除了填写固定值外,还可以通过结合regex
来实现较为复杂的转换。配置示例如下:
- action: replace source_labels: [method, handler] separator: "#" regex: "(.*)#(.*)" replacement: "$2 $1" target_label: url
在本例中,执行逻辑如下:
method
和handler
获取 value。separator
定义的分割符,将获取的 value 进行拼接,得到POST#/api/v1/vmp
。$1
为POST
,$2
为/api/v1/vmp
。replacement
进行重新格式化,预期得到的指标如下所示。
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
,则会:
keep
:保留这类指标,丢弃其他指标。drop
:丢弃这类指标,保留其他指标。例如:在 Kubernetes 集群里,可以使用如下配置,丢弃服务发现阶段内置的__meta_kubernetes_namespace
系统 label 中,值为 test 和 stage 的指标。
- source_labels: [__meta_kubernetes_namespace] regex: “test|stage” action: drop
labelkeep
和labeldrop
和上文中描述的keep/drop
字段不一样,其包含label
前缀,表示允许基于指标的 label key 过滤指标。例如:
- action: labeldrop regex: status
预期得到的指标如下,直接丢弃了原指标中的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 系统内置标签保留到指标里。
- action: labelmap regex: "__meta_kubernetes_(.*)" replacement: "k8s_${1}"
另外,假设 Pod label 的系统内置标签如下,表示 Kubernetes 服务发现的 Target Pod 里有app=foo
的 label:
__meta_kubernetes_pod_label_app: foo ...
使用如下 relabel 配置,可将 Pod label 的系统内置标签自动添加到指标上。
- action: labelmap regex: __meta_kubernetes_pod_label_(.+)
说明
由于replacement
默认值为$1
,所以这里拿到的是第一个正则捕获组里,即(.+)
表示的值。
预期得到的指标为:
http_requests_total{method="POST", handler="/api/v1/vmp", status="200", app="foo"} 1024