NodeTextFileCollectorScrapeError 报警原因及解决方法
现象
prometheus 经常有告警 NodeTextFileCollectorScrapeError
 查看 node-exporter 日志出现如下报错
time=2025-04-01T06:43:18.266Z level=ERROR source=textfile.go:248 msg="failed to collect textfile data" collector=textfile file=ipmitool.prom err="failed to parse textfile data from \"/host/root/var/lib/node_exporter/textfile/ipmitool.prom\": text format parsing error in line 35: invalid label value \"r\\x85r??\""
 
从日志来看,ipmitool.prom 文件在第 35 行存在格式错误,具体错误是 “invalid label value”,可能的原因如下:
可能的原因
1.特殊字符或乱码
 r\x85r?? 可能是非 ASCII 字符或二进制数据,导致解析失败。
 可能是 IPMI 工具输出的数据包含不可见字符。
2.标签格式错误
 Prometheus 指标的标签必须符合:
metric_name{label="value"} number
 
例如:
ipmi_temperature{sensor="CPU Temp"} 42.0
 
label=“r\x85r??” 说明 value 部分包含了非法字符。
3.文件编码问题
 ipmitool.prom 可能是 UTF-16、UTF-8 BOM 或其他非标准编码,导致解析失败。
4.IPMI 读取错误
 ipmitool 可能返回了异常字符,导致 .prom 文件生成时包含错误数据。
解决方法
1.检查 ipmitool.prom 文件
cat -A /host/root/var/lib/node_exporter/textfile/ipmitool.prom | grep -n .
 
cat -A 显示所有特殊字符(^M、\x85 等)。
 找到第 35 行的内容,看是否有乱码或特殊字符。
2.手动清理 ipmitool.prom
 如果确认文件有乱码,可以手动编辑:
nano /host/root/var/lib/node_exporter/textfile/ipmitool.prom
 
删除第 35 行的无效字符
 确保格式正确,如:
ipmi_temperature{sensor="CPU Temp"} 42.0
 
不要使用非 ASCII 字符(如中文、特殊符号等)。
3.自动清理文件
 如果是 ipmitool 生成的问题,可用 sed 或 tr 过滤非标准字符:
sed -i 's/[^a-zA-Z0-9_{}=",.\-]//g' /host/root/var/lib/node_exporter/textfile/ipmitool.prom
 
或者:
tr -cd '\11\12\15\40-\176' < /host/root/var/lib/node_exporter/textfile/ipmitool.prom > /tmp/clean.prom && mv /tmp/clean.prom /host/root/var/lib/node_exporter/textfile/ipmitool.prom
 
这会删除所有 非 ASCII 可打印字符,避免 Prometheus 解析失败。
4.检查 ipmitool 生成的内容
 如果 ipmitool 仍然生成错误数据,建议先手动运行:
ipmitool sensor
 
然后检查输出是否包含乱码或特殊字符。如果有问题,可以尝试:
LANG=C ipmitool sensor
 
或者重定向输出后检查:
ipmitool sensor > /tmp/ipmi_output.txt
cat -A /tmp/ipmi_output.txt
 
5.重新生成 .prom 文件
 如果 ipmitool 是用脚本生成 .prom 文件的,建议在脚本里加个清理步骤:
ipmitool sensor | tr -cd '\11\12\15\40-\176' > /host/root/var/lib/node_exporter/textfile/ipmitool.prom
 
这样可以确保生成的 .prom 文件不会带有非法字符。
6.重新启动 node_exporter
 清理后,重启 node_exporter 并检查日志:
sudo systemctl restart node_exporter
journalctl -u node_exporter --no-pager | tail -n 20
 
然后再访问 Prometheus /metrics 端点:
curl -s http://localhost:9100/metrics | grep textfile
 
如果 node_textfile_scrape_error 0,说明错误已经修复。
tr -cd ‘\11\12\15\40-\176’ 命令解释
tr -cd '\11\12\15\40-\176' 这个命令的作用是 过滤掉所有非 ASCII 可打印字符,只保留特定的字符集。
解释各个部分
tr:翻译或删除字符的命令(translate)-c:取反,即匹配不在指定字符集范围内的字符-d:删除匹配到的字符'\11\12\15\40-\176':保留的字符集:\11(Tab 键HT,ASCII 9)\12(换行符LF,ASCII 10)\15(回车CR,ASCII 13)\40-\176(范围表示法,ASCII 32 到 126,即所有可见的 ASCII 字符)
字符范围
| ASCII 范围 | 说明 | 
|---|---|
\11 (9) | Tab (HT) | 
\12 (10) | 换行 (LF) | 
\15 (13) | 回车 (CR) | 
\40 (32) | 空格 (Space) | 
\176 (126) | ~(所有可打印 ASCII 字符) | 
总结
 这个命令 删除所有不可打印字符(比如 \x85、控制字符、二进制字符等)
- 只保留: 
  
- 可见的 ASCII 字符(
32-126) Tab、换行、回车(用于格式化)
 - 可见的 ASCII 字符(
 
示例
示例 1:清理包含特殊字符的文件
cat file.txt | tr -cd '\11\12\15\40-\176' > clean.txt
 
- 作用:从 
file.txt里 删除不可打印字符,输出到clean.txt - 适用于清理 
Prometheus .prom文件格式错误问题 
示例 2:处理 ipmitool.prom
tr -cd '\11\12\15\40-\176' < ipmitool.prom > clean.prom
mv clean.prom ipmitool.prom
 
- 作用:去除 
.prom文件中的乱码或非法字符,保证 Prometheus 能正确解析 
这样可以确保 ipmitool.prom 不包含非标准字符,避免 NodeTextFileCollectorScrapeError
ansible 中写法
如果使用ansible 部署,tr -cd ‘\11\12\15\40-\176’ 里的 \ 需要转义(在 YAML 里 \ 是特殊字符)
 示例如下
- name: Creates a cron file for prometheus monitor ipmi
  cron:
    name: "{{ item.name }}"
    minute: "{{ item.minute }}"
    hour: "{{ item.hour }}"
    day: "{{ item.day }}"
    month: "{{ item.month }}"
    weekday: "{{ item.weekday }}"
    user: "{{ item.user }}"
    job: "{{ item.job }}"
  with_items:
    - { name: "ipmitool", minute: "*/1", hour: "*", day: "*", month: "*", weekday: "*", user: "root", job: "sudo ipmitool sensor | sudo awk -f {{ node_exporter_root_dir }}/ipmitool | tr -cd '\\11\\12\\15\\40-\\176' > {{ node_exporter_textfile_dir }}/ipmitool.prom" }
 
tr -cd ‘\11\12\15\40-\176’ 可以使用双引号吗
在 tr -cd ‘\11\12\15\40-\176’ 中,单引号 ‘’ 是用来确保 \11\12\15\40-\176 作为转义字符被 tr 正确解析。
如果使用 双引号 “”,bash 可能会对 \11\12\15\40-\176 进行额外的 shell 解析,可能导致错误或不符合预期的行为。
是否可以使用双引号?
 单引号 ’ ’ ✅(推荐)
tr -cd '\11\12\15\40-\176'
 
✅ 正确,tr 直接解析 \11\12\15\40-\176 作为 ASCII 码范围。
双引号 " " ⚠️(可能错误)
tr -cd "\11\12\15\40-\176"
 
⚠️ 可能错误,bash 会优先解析 \,可能导致 tr 不能正确识别 ASCII 码。
