简介

在官方文档中,关于 relabel 的介绍并不多,介绍下配置项格式就结束了。但在实际使用上,我们却离不开这个利器。

本文将结合实际使用经验,将 relabel 的使用场景做一个总结。

relabel 字面意思是指对标签进行赋值操作。采集点通过 metrics 接口将数据暴露给 Prometheus, Prometheus 将抓取的数据存储到时许数据库之前,将执行 relabel 操作。

常见用法

relabel 常见的用法有 5 种:

  • 添加新标签
  • 更新标签值
  • 正则表达式替换
  • 更新指标名
  • 删除标签名

1. 添加新标签

通过 relabel 操作,可以对所有被采集到的数据增加新标签。以标签 label_name 为例,使用以下配置:

1
2
- target_label: "label_name"
  replacement: "label_value"

采集的数据经过处理后,metrics_name{job="demo_job"} 将会变成 metrics_name{job="demo_job", label_name="label_value"}

2. 更新标签值

与上述添加新标签的方法类似,如果原指标中已经包含。如,原指标为metrics_name{job="demo_job", label_name="old_name"}, 那么在 relabel 后,指标则变为 metrics_name{job="demo_job", labe_name="label_value"}

3. 正则表达式替换

通过正则表达式,可以将原有的标签值提取进行处理,并替换新值。

1
2
3
4
- source_labels: [instance]
  regex: "([^:]+):.+"
  target_label: "instance"
  replacement: "$1"

上述规则会将 metrics_name{instance="localhost:1234"} 转换为 metrics_name{instance="localhost"}

4. 更新指标名

指标的形式除了 metrics_name{job="demo_job"}外,也可以表示为 {__name__="metrics_name", job="demo_job"}。所以,可以通过修改 __name__方式来更换指标名。

1
2
3
4
- source_labels: [__name__]
  regex: "(.+)_online"
  target_label: "__name__"
  replacement: "online_$1"

以上配置通过正则,将以 online 结尾的指标名更新为以 online 开头的指标名。因此,metrics_name_online{job="demo_job"} 将会变为 online_metrics_name{job="demo_job"}

5. 删除标签名

删除标签名有三种方式

通过 labeldrop

1
2
- action: labeldrop
  regex: "tmp.+"

通过正则表达式进行匹配,当有 label 满足该正则表达式时,则会对该标签进行移除。

通过 labelkeep

1
2
- action: labelkeep
  regex: "__name__|.*keepme"

如果源标签数据较多,只需要保留较少的标签时,则可以使用 labelkeep 完成反向标签删除。这里需要注意,指标名也是一个特殊的标签名,因此使用 labelkeep 时,要带上 __name__ 这个特殊的标签名。

标签值赋空值

1
2
3
4
- source_labels: [foo]
  regex: "bar"
  target_label: foo
  replacement: ""

在 Prometheus 中,如果一个标签的值为空,那么这个标签名就不会被采集。因此,可以通过改变标签值的方式删除标签名。

应用案例

应用:给监控增加分组

现在你负责一个监控系统,业务部门已经按照了你的要求提供了采集点。以 node_exporter 为例,你得到一批采集点或服务发现的 exporter,现在为了区分不同的业务部门,不同的环境,需要给这些指标增加业务分组、环境等 label。

如果是自己开发的 exporter,完全可以在指标暴露之前增加 label,但开源的服务怎么办?

这个时候,通过 relabel 即可。

相关配置如下:

1
2
3
4
5
6
7
- job_name: test_bdata_k8s_auto_scraped
  // ...
  relabel_configs:
  - target_label: env
    replacement: test
  - target_label: group
    replacement: xxx_bussiness_group

应用:blackbox 探针

relabel 可以实现 multi-target 模式,在一些特殊的 exporter 中非常有用。

当想监控 Kafka 9092 端口是否能连通时,由于 Kafka 本身没有提供该 exporter,所以要借助 blackbox 这个开源的 exporter。blackbox 可以检测多种协议,Kafka 用到 9092 端口是基于 TCP 协议。普通的 exporter,需要在哪里用到时,就去对应的服务器上进行安装。但是 TCP 连通性需求是通用的,如果每次都去对应的机器安装,就会比较麻烦。

blackbox 实现了一种被称作 multi-target 的模式,这种模式的好处是:

  • 通过网络协议获取指标数据
  • 不需要去指标所在机器部署 exporter
  • exporter 把 target 和 query 配置作为 Prometheus GET 请求的参数
  • exporter 在收到 Prometheus 的 GET 请求并完成抓取后才开始抓取
  • exporter 可以查询多个 target

其实原理也很简单,

blackbox 本身是可以发起类似 telnet 请求到对应的服务的,这完全可以在一个中心服务器上进行部署,并通过配置告诉 blackbox,我现在要探测 kafka01 kafka03 的 9092 端口情况。请分别探测这两台机器,并把结果通过指标的形式告诉我。

现在的问题是,blackbox 如何知道你要探测的地址呢?答案是,Get 请求。

现在最后的难点就是,如何让 Prometheus 访问 blackbox 时带上参数呢?

完整配置如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
- job_name: blackbox_probe
  honor_timestamps: true
  track_timestamps_staleness: false
  params:
    module:
      - tcp_connect_kafka
  scrape_interval: 15s
  scrape_timeout: 3s
  metrics_path: /probe
  scheme: http
  basic_auth:
    username: node_exporter
    password: <secret>
  follow_redirects: true
  enable_http2: true
  relabel_configs:
    - source_labels: [__address__]
      separator: ;
      regex: (.*)
      target_label: __param_target
      replacement: $1
      action: replace
    - source_labels: [__param_target]
      separator: ;
      regex: (.*)
      target_label: instance
      replacement: $1
      action: replace
    - separator: ;
      regex: (.*)
      target_label: __address__
      replacement: 39.105.157.26:9115
      action: replace