如何通过Prometheus与SNMP Exporter正确解析MIB表负载指标?
你遇到的这个情况其实是SNMP Exporter处理表格型OID的默认行为导致的——UCD-SNMP-MIB的laLoad是一个表格结构,SNMP Exporter默认会把表格里的列值(也就是你的负载数值)当成标签存储,同时把样本值固定为1,用来标记这一行数据存在。要让负载数值成为真正的指标值,我们可以从两个层面来调整:
方法一:修改SNMP Exporter的配置文件(snmp.yml)
直接在SNMP Exporter的配置里定义如何提取laLoad的数值,而不是依赖默认的表格处理逻辑。
假设你之前用NetSNMP生成的配置里有类似这样的walk项:
walk: - laLoad
你可以把它替换成专门的metrics配置,指定提取数值:
metrics: - name: node_load oid: 1.3.6.1.4.1.2021.10.1.3 # 这是laLoad对应的OID type: gauge labels: - name: laIndex value: "{{.laIndex}}" # 保留laIndex标签区分1/5/15分钟负载
这样配置后,SNMP Exporter会直接把laLoad对应的数值作为node_load指标的样本值,同时用laIndex标签来标记是1分钟(laIndex=1)、5分钟(laIndex=2)还是15分钟(laIndex=3)的负载,最终得到符合预期的时间序列。
方法二:在Prometheus中添加metric_relabel_configs
如果不想修改SNMP Exporter的配置,也可以在Prometheus的采集配置里通过重标记规则来转换现有数据:
scrape_configs: - job_name: 'poc' static_configs: - targets: ['boston01:9116'] metric_relabel_configs: # 先把laLoad标签里的数值临时存到__tmp_load - source_labels: [laLoad] regex: "(.*)" target_label: "__tmp_load" # 把原指标名laLoad改成更直观的node_load - source_labels: [__name__] regex: "laLoad" target_label: "__name__" replacement: "node_load" # 丢弃原来的laLoad标签 - action: labeldrop regex: "laLoad" # 把临时存储的负载数值替换成样本值 - action: replace source_labels: [__tmp_load] regex: "(.*)" target_label: "__value__"
这个规则的作用是把原本存在laLoad标签里的数值提取出来,替换成指标的实际值,同时清理掉多余的标签,最终得到node_load{instance="boston01",job="poc",laIndex="1"} 1.43这样的结果。
补充说明
你说得没错,Linux的UCD-SNMP-MIB里确实没有标量形式的负载指标,所有负载数据都封装在laLoad表中,所以必须通过处理表格型OID的方式来获取正确的数值。上面两种方法都能解决问题,推荐第一种,因为在SNMP Exporter层面处理会更高效,减少Prometheus的重标记开销。
内容的提问来源于stack exchange,提问作者Ken - Enough about Monica

