如何在Prometheus中按位置合并不同指标的标签到自定义指标
问题需求
现有多个独立的Prometheus Gauge指标,所有指标共享pd_location标签,需要将同一pd_location对应的所有标签整合到一个自定义命名的指标中(例如将位置1的所有相关标签合并为pd_info_loc_1指标)。
原始指标示例
# HELP pd_RG RG name - 1.3.6.1.4.1.22274.1.2.1.1.3 # TYPE pd_RG gauge pd_RG{pd_RG="Pool_01_SSD",pd_location="1"} 1 pd_RG{pd_RG="Pool_01_SSD",pd_location="2"} 1 pd_RG{pd_RG="Pool_01_SSD",pd_location="3"} 1 # HELP pd_command_queuing command queuing - 1.3.6.1.4.1.22274.1.2.1.1.13 # TYPE pd_command_queuing gauge pd_command_queuing{pd_command_queuing="Enabled",pd_location="1"} 1 pd_command_queuing{pd_command_queuing="Enabled",pd_location="10"} 1 pd_command_queuing{pd_command_queuing="Enabled",pd_location="11"} 1 # 其余指标省略...
期望输出示例
pd_info_loc_1{pd_RG="Pool_01_SSD",pd_location="1",pd_command_queuing="Enabled",pd_performance="2496",pd_readahead="Enabled",pd_serial="843IPLHT", pd_size="3575",pd_status_health="Good"} 1 pd_info_loc_10{pd_RG="Pool_01_SSD",pd_location="10",pd_command_queuing="Enabled",pd_performance="8148",pd_readahead="Enabled",pd_serial="5KKLY7KGT", pd_size="16762",pd_status_health="Good"} 1 pd_info_loc_11{pd_RG="Pool_01_SSD",pd_location="11",pd_command_queuing="Enabled",pd_performance="12748",pd_readahead="Enabled",pd_serial="6UHYGKGT", pd_size="16762",pd_status_health="Good"} 1
解决方案
方案1:Python脚本预处理Metrics数据
编写脚本读取原始metrics文本,按pd_location聚合所有标签,直接生成目标格式的指标,实现简单且灵活。
示例脚本:
import re from collections import defaultdict # 读取原始metrics文件 with open('original_metrics.txt', 'r') as f: lines = f.readlines() # 按location存储所有标签 location_tags = defaultdict(dict) # 匹配指标行的正则表达式 metric_pattern = re.compile(r'(\w+)\{(.+)\} (\d+)') for line in lines: line = line.strip() # 跳过注释和空行 if line.startswith('#') or not line: continue match = metric_pattern.match(line) if not match: continue metric_name, tags_str, _ = match.groups() # 解析标签键值对 tags = {} for tag in tags_str.split(','): if '=' not in tag: continue key, val = tag.split('=', 1) tags[key.strip()] = val.strip('"') # 获取当前指标的location loc = tags.get('pd_location') if not loc: continue # 将指标对应的标签存入location字典 if metric_name in tags: location_tags[loc][metric_name] = tags[metric_name] # 保留pd_location标签 location_tags[loc]['pd_location'] = loc # 生成合并后的指标 for loc, tags in location_tags.items(): metric_name = f'pd_info_loc_{loc}' tag_pairs = [f'{k}="{v}"' for k, v in tags.items()] print(f'{metric_name}{{{",".join(tag_pairs)}}} 1')
使用说明:
- 将原始metrics内容保存为
original_metrics.txt - 运行脚本即可输出合并后的指标
- 可自行修改指标命名规则或调整需要保留的标签
方案2:Prometheus生态工具(局限性说明)
Prometheus原生relabel机制无法直接跨指标合并标签,若要通过Prometheus配置实现,需借助prometheus-adapter或自定义exporter:
- 核心思路是通过PromQL关联多个指标的标签,生成自定义指标
- 但要求每个
pd_location在所有目标指标中都存在,否则会丢失数据,实现复杂度高于脚本预处理
内容的提问来源于stack exchange,提问作者Philip Scot
相关产品推荐
相关产品推荐

