使用Python脚本导出Prometheus数据到CSV时遇JSON解析错误
问题描述
我有一个名为yprom_csv.py的Python脚本,用来将Prometheus数据导出为CSV格式,但运行时出现JSON解析错误。
脚本代码
import csv import requests import sys def GetMetrixNames(url): response = requests.get('{0}/api/v1/label/__name__/values'.format(url)) names = response.json()['data'] #Return metrix names return names """ Prometheus hourly data as csv. """ writer = csv.writer(sys.stdout) if len(sys.argv) != 2: print('Usage: {0} http://localhost:9090'.format(sys.argv[0])) sys.exit(1) metrixNames=GetMetrixNames(sys.argv[1]) writeHeader=True for metrixName in metrixNames: #now its hardcoded for hourly response = requests.get('{0}/api/v1/query'.format(sys.argv[1]), params={'query': metrixName+'[1h]'}) results = response.json()['data']['result'] # Build a list of all labelnames used. #gets all keys and discard __name__ labelnames = set() for result in results: labelnames.update(result['metric'].keys()) # Canonicalize labelnames.discard('__name__') labelnames = sorted(labelnames) # Write the samples. if writeHeader: writer.writerow(['name', 'timestamp', 'value'] + labelnames) writeHeader=False for result in results: l = [result['metric'].get('__name__', '')] + result['values'] for label in labelnames: l.append(result['metric'].get(label, '')) writer.writerow(l)
运行命令
python3 yprom_csv.py https://prometheus-k8s-openshift-monitoring.apps.XXXX-XXXXXXX.Xx8X.p1.openshiftapps.com
错误信息
Traceback (most recent call last): File "/root/yprom_csv.py", line 16, in <module> metrixNames=GetMetrixNames(sys.argv[1]) File "/root/yprom_csv.py", line 6, in GetMetrixNames names = response.json()['data'] File "/usr/lib/python3.9/site-packages/requests/models.py", line 900, in json return complexjson.loads(self.text,** kwargs) File "/usr/lib64/python3.9/json/__init__.py", line 346, in loads return _default_decoder.decode(s) File "/usr/lib64/python3.9/json/decoder.py", line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "/usr/lib64/python3.9/json/decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 2 column 1 (char 1)
解决方案
这个错误的核心是requests.get返回的响应不是有效的JSON格式,以下是针对性的解决步骤:
1. 先验证Prometheus API的可访问性
用浏览器或curl直接访问目标API地址:
curl https://prometheus-k8s-openshift-monitoring.apps.XXXX-XXXXXXX.Xx8X.p1.openshiftapps.com/api/v1/label/__name__/values
如果返回HTML页面(比如登录页、权限错误页),说明需要身份验证或URL存在问题。
2. 添加OpenShift身份验证
OpenShift上的Prometheus通常需要Bearer Token认证:
- 先获取当前用户的Bearer Token:
oc whoami -t - 修改脚本,添加认证头并更新参数逻辑:
def GetMetrixNames(url, token): headers = {'Authorization': f'Bearer {token}'} response = requests.get(f"{url}/api/v1/label/__name__/values", headers=headers) # 先检查响应状态 if response.status_code != 200: print(f"请求失败:状态码 {response.status_code},响应内容:{response.text}") sys.exit(1) try: data = response.json() except json.decoder.JSONDecodeError as e: print(f"JSON解析失败:{e}") sys.exit(1) return data['data'] # 修改参数检查逻辑 if len(sys.argv) != 3: print('Usage: {0} <prometheus-url> <bearer-token>'.format(sys.argv[0])) sys.exit(1) metrixNames=GetMetrixNames(sys.argv[1], sys.argv[2]) # 后续查询请求也要添加认证头 response = requests.get(f"{sys.argv[1]}/api/v1/query", params={'query': f"{metrixName}[1h]"}, headers={'Authorization': f'Bearer {sys.argv[2]}'})
3. 排查响应内容(临时调试用)
在调用response.json()前,先打印响应的状态码和文本,确认返回内容:
def GetMetrixNames(url): response = requests.get('{0}/api/v1/label/__name__/values'.format(url)) print(f"状态码:{response.status_code}") print(f"响应内容:{response.text[:500]}") # 打印前500字符 try: data = response.json() except json.decoder.JSONDecodeError as e: print(f"解析失败:{e}") sys.exit(1) return data['data']
4. 处理SSL证书问题(可选)
如果是自签名SSL证书导致请求失败,可临时关闭证书验证(生产环境建议导入信任证书):
response = requests.get('{0}/api/v1/label/__name__/values'.format(url), verify=False)
5. 修复脚本缩进错误
原脚本中for result in results:一行缩进错误,会导致语法问题,修正为:
labelnames = set() for result in results: labelnames.update(result['metric'].keys())
内容的提问来源于stack exchange,提问作者Navaratnam
相关产品推荐
相关产品推荐

