普罗米修斯自定义label作为变量的显示值和实际值

现象

当使用普罗米修斯监控mysql的时候,我们使用的是docker来部署prometheus,使用docker版的mysqld-exporter来实现对mysql指标的监控。

然后,问题来了, 在普罗米修斯的架构体系中,普罗米修斯负责从mysqld-exporter来拉取数据,然后在grafana看板里展示监控的指标,而我们为了节省机器(当然第一次部署也不熟),将prometheus和mysqld-exporter部署在了一台机器上,然后利用mysqld-exporter远程抓取的功能从mysql服务器里抓取数据。

理论上,这么跑也没有问题,我们也成功的将数据抓取到了。

但是在显示的时候,在host主机筛选框里,显示的是mysqld-exporter所在的主机的ip地址,而我们实际想要的是mysql服务器的ip地址。

以下是我们当时的验证阶段的prometheus架构:

普罗米修斯远程采集mysql架构

host筛选的效果:

显示exporter所在的host

解决

中间的试错过程就不说了,直接进入主题。

核心思路:

  1. Prometheus支持自定义label功能,我们可以在配置mysql采集器的时候,把mysql的实际ip当做一个label配置进去
  2. grafana在配置变量的时候,可以通过正则的方式,实现下拉列表中显示值-实际值这种键值对的功能

增加mysql_server_ip 自定义label

修改普罗米修斯配置文件prometheus.yml

1
2
3
4
5
6
7
8
9
10
11
12
scrape_configs: 
- job_name: 'mysql'
scrape_interval: 10s
static_configs:
- targets:
- '192.168.202.172:9104'
labels:
mysql_server_ip: 192.168.202.48
- targets:
- '192.168.202.172:9105'
labels:
mysql_server_ip: 192.168.202.248

重启生效。

然后登录prometheus后端: http://ip:9090/targets, 查看我们新增的mysql_server_ip label是否生效,此时在我们的mysql一栏中,应该已经有了mysql_server_ip这个label,且值就是对应mysql的实际ip。

配置grafana变量

接下来,我们登录grafana,进入变量配置页面,添加变量,选择Query result 类型。

在query 一栏 输入 mysql_up, 这会查出所有mysql生效的结果集。 可以执行页面尾部的run query预览结果。

然后在正则表达式一栏输入 /mysql_server_ip="(?<text>[^"]+)|instance="(?<value>[^"]+)/g 即可。

这段正则的含义是:从query的结果中,提取出mysql_server_ip这个label的值,作为显示值,instance这个label的值作为实际值。

保存生效

至此,我们的自定义下拉选择框就完成了,如下图:

显示实际的mysql地址

当我们选择显示值192.168.202.48时,host获得的是其对应的实际值192.168.202.172:9104

这样,我们就可以在整个mysql模板不用大改的情况下,实现了显示mysql实际ip地址的功能了。

总结

当然,在上述的实践中,我们的架构是有点问题的,mysqld-exporter不应该和prometheus部署在一起的,而是应该部署到mysql的服务器上,这样,上面的问题也就不存在了。

我们只是利用这个契机,调研学习了一下prometheus的自定义label功能,以及自定义配置grafana的下拉选择框的配置方法。

以下是Prometheus的推荐架构:

prometheus架构

mysqld-exporter的推荐使用:

mysqld-exporter推荐使用

高级玩法

其实,Prometheus在配置文件中,还提供了一套再配置label的语法,可以实现对一些原生label的二次修改。

大致配置和效果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
scrape_configs:
- job_name: 'mysql_job'
static_configs:
- targets: ['localhost:9090']

metric_relabel_configs:
# 删除掉所有以"temp_"开头的标签
- source_labels: [__name__]
action: drop
regex: 'temp_.*'

# 将`instance`标签值改为`host`
- source_labels: [instance]
target_label: host
action: replace
regex: '(.*)'
replacement: '$1'

# 删除掉所有没有"job"标签的时间序列
- source_labels: [job]
action: drop
regex: ''

完整的relabel_config配置如下所示:

字段 含义 默认值
source_labels 用于拼接并匹配的原始标签列表,内容按 separator 连接后与 regex 对比 []
separator 多个 source_labels 拼接时的分隔符 ";"
regex 用于匹配拼接后字符串的正则表达式,支持捕获组,常用来提取子串 "(.*)"
target_label 匹配成功后新标签的名称;在某些 action 下表示目标标签
replacement 用于替换的新值,支持 $1$2 等捕获组引用 "$1"
modulus 仅对 hashmod 有效,指定哈希取模的除数
action 执行的操作类型,包括 replacekeepdrophashmodlabelmaplabeldroplabelkeepkeepequaldropequallowercaseuppercase "replace"

其中action的枚举:

  1. replace:使用 regexreplacement 修改或新增标签值(默认)
  2. keep / drop:根据 regex 保留或丢弃整个目标(当匹配失败时,会跳过该目标)
  3. hashmod:对拼接后内容做哈希并取模,通常用于均匀分流或分区
  4. labelmap:对标签名称做正则替换,例如将所有 __meta_kubernetes_* 标签统一前缀
  5. labeldrop / labelkeep:批量删除或保留与 regex 匹配的标签名称
  6. keepequal / dropequal:仅当某两个标签值相等或不等时才保留或丢弃目标
  7. lowercase / uppercase:将指定标签值转换为小写或大写

参考

grafana的正则表达式功能

relabel 配置文档


普罗米修斯自定义label作为变量的显示值和实际值
https://www.hancher.top/2025/05/27/frame-prometheus-select-label-var/
作者
寒澈
发布于
2025年5月27日
许可协议