🌅

json转换为Prometheus

Tags
运维
监控
Date
Dec 3, 2022
2024.1.22更新:不需要看下文了,直接使用Grafana 的 Infinity 插件即可,可以可视化来自 JSON、CSV、XML、GraphQL 和 HTML 端点的数据。

json_exporter

yadcc导出的指标是json格式的,而Prometheus不能直接接收json格式,所以需要转换一下,Prometheus社区有个json_exporter,可以帮助我们完成这件事情。
比如xxx_exporter输出的json格式如下:
{ "task_dispatcher": { "capacity": 150, "running_tasks": 0, "servants": [ { "capacity_available": 15, "location": "192.168.33.7:3335", "max_tasks": 15, "version": 7 }, { "capacity_available": 15, "location": "192.168.33.8:3335", "max_tasks": 15, "version": 7 } ] } }

学习JsonPath

然后我们来学习下JsonPath,正如XPath之于XML文档一样,JsonPath为Json文档提供了解析能力,通过使用JsonPath,你可以方便的查找节点、获取想要的数据,JsonPath是Json版的XPath。
  1. JsonPath基本用法
  1. Jsonpath语法
  1. JSONPath Support | Kubernetes
看了上面两个教程学会JsonPath之后,我们就能参考官方readme中的demo,给我们的json格式转成yaml,下面介绍一下demo中的yaml:
--- modules: default: metrics: - name: example_global_value # 使用path定位到json某个位置,以此为父节点(如果最终结果以{}包裹的话) path: "{ .counter }" # 在json_exporter中,可以省略根节点符号$,等价于{ $.counter } help: Example of a top-level global value scrape in the json # help是注释 labels: # label用来区分不同节点,给节点打标签 environment: beta # static label,静态标签 location: "planet-{.location}" # dynamic label - name: example_value type: object # json中有数组和对象,但是此处经过实验,json_exporter只支持object,不过数组也兼容了 help: Example of sub-level value scrapes from a json path: '{.values[?(@.state == "ACTIVE")]}' # JsonPath语法,筛选出state为ACTIVE的value元素 labels: environment: beta # static label id: '{.id}' # dynamic label # 注意,此处values是json_exporter yaml文件中的固定属性(列举对象中的属性,都是values然后下面映射), # 不是demo中json里面的values对象,刚开始我把两者混为一谈,导致踩坑 values: active: 1 # static value count: '{.count}' # dynamic value boolean: '{.some_boolean}' headers: X-Dummy: my-test-header
同理可得我们的yaml文件,如果在编写yaml文件过程中path老是写不对,可以用JsonPath验证器:JSONPath Online Evaluator
notion image
--- modules: default: metrics: - name: running_tasks valuetype: gauge # 如果不指定会报这个信息:TYPE xxx untyped,至于具体类型,可以参考Prometheus文档或node_exporter指标 path: '{.task_dispatcher.running_tasks}' help: Example of a top-level global value scrape in the json - name: servants type: object help: Example of sub-level value scrapes from a json path: '{.task_dispatcher.servants[*]}' # 通过[*]获取servants对象,并以此为父节点,这样下面values中才可以直接使用.x labels: ip: '{.location}' priority: '{.priority}' values: capacity_available: '{.capacity_available}' max_tasks: '{.max_tasks}' running_tasks: '{.running_tasks}' # dynamic value headers: X-Dummy: my-test-header

运行json_exporter

curl "http://localhost:7979/probe?module=default&target=http://root:[email protected]:3336/inspect/vars/yadcc",json_exporter的默认端口为7979,我们可以通过-web.listen-address=":3331"修改。
示意图,仅供参考
示意图,仅供参考
报错:Failed to convert extracted value to float64
原因就是没有加values映射,json_exporter会默认把整个path获取到的内容转成float64,所以报错。
 

接入Prometheus

之前想把metrics_path直接设置为"/probe?module=default&target=http://root:[email protected]:3336/inspect/vars/yadcc",结果Prometheus报错,说不支持问号?,stackoverflow上有老哥解答:Question mark in Prometheus metrics_path gets encoded - Stack Overflow,使用params参数即可,个人感觉比官方的要更顺手一点。
- job_name: "yadcc" # metrics_path defaults to '/metrics' # scheme defaults to 'http'. static_configs: - targets: ["host2:7979"] metrics_path: "/probe" params: module: ['default'] target: ['http://root:[email protected]:3336/inspect/vars/yadcc'] # basic_auth: # username: "root" # password: "abc"
- job_name: json metrics_path: /probe params: module: [default] static_configs: - targets: - http://host-1.foobar.com/dummy/data.json - http://host-2:8000/other-examples/data.json - http://localhost:8000/examples/data.json ## Used from the example steps in Readme relabel_configs: - source_labels: [__address__] target_label: __param_target - source_labels: [__param_target] target_label: instance - target_label: __address__ ## Location of the json exporter's real <hostname>:<port> replacement: host.docker.internal:7979 # equivalent to "localhost:7979"
参考2中还列出对labels利用正则进行处理的方法:
- source_labels: [__address__] regex: ^http.+currency=([A-Z]{3}) action: replace target_label: currency replacement: ${1}

参考

  1. Prometheus Exporter (三十四)JSON Exporter_json
  1. Transforming remote JSON into Prometheus metrics
  1. How to Convert Simple JSON to Prometheus Format · Issue #186 · prometheus-community/json_exporter
  1. Question: nested json structure · Issue #85 · prometheus-community/json_exporter