使用Grafana的JSON DataSource插件完成对实时监控数据的可视化展示
Grafana的JSON DataSource插件
Grafana可以制作更具科技感的dashboard,支持的数据源也越来越丰富,如Elasticsearch、MySQL、Prometheus等等。
尽管如此,在大数据时代依旧有很多的数据存储在非常见的数据源中,这些数据无法直接对接Grafana进行可视化展示,但是我们又对Grafana的性能以及制作的酷炫图表爱不释手,JSON数据源插件的出现很大程度上缓解了这个窘境。利用JSON数据源插件,无论数据存储在什么数据源中,只需要实现相应的接口,并在接口中实现将数据转换为Grafana的JSON插件所支持的数据格式,就可以实现无缝对接。
JSON DataSource插件安装
使用grafana的自带工具grafana-cli可以快速完成simple-json-datasource插件的安装,以windows系统为例:
- 打开 ./Grafana/grafana/bin 文件夹,在此处打开命令行窗口
- 输入命令:
grafana-cli plugins install simpod-json-datasource
如果有安装成功的提示,代表插件安装成功,需要重启grafana服务使新插件生效:
windows命令行中输入:
net stop grafana
net start grafana
如果没有安装成功,很可能是因为网络连接问题导致相应的插件资源下载失败,此时可以尝试为命令行工具配置上网代理:
- 右键我的电脑 → 属性 → 高级 → 环境变量 → 系统变量
- 新建参数命名为 HTTP_proxy
- 相应的路径名为 http://yourproxy.ip:yourproxy.port/
JSON DataSource接口实现
接下来需要实现实现相应的WebAPI接口,在接口中完成 源数据格式 - JSON插件所支持数据格式 的转换。
-
/
/ 是第一个需要实现的接口,该接口用于对数据源进行测试,请求方式是 GET ,无需返回有意义的实体,调用状态码为200即可,例如返回实体可以为:{"status":"success"}
实现了此接口后,即可在grafana中完成对JSON数据源的配置:
输入 / 接口的url → Save & Test,即可完成JSON数据源的配置。 -
/search
/search 接口用于在编辑图表query时选择相应的metric,即
/search 接口的请求方式是 POST ,请求体类似于{ "target": "upper_50" }
/search 接口的返回结果可以是array格式:
["upper_25","upper_50","upper_75","upper_90","upper_95"]
也可以是map格式:
[ { "text" :"upper_25", "value": 1}, { "text" :"upper_75", "value": 2} ]
/search 接口实现后,Metric的下拉框内就出现了相应的可选内容;
-
/query
/query 接口用于返回query所请求的数据。
/query 接口的请求方式是 POST ,请求体类似于:{ "panelId": 1, "range": { "from": "2016-10-31T06:33:44.866Z", "to": "2016-10-31T12:33:44.866Z", "raw": { "from": "now-6h", "to": "now" } }, "rangeRaw": { "from": "now-6h", "to": "now" }, "interval": "30s", "intervalMs": 30000, "maxDataPoints": 550, "targets": [{ "target": "upper_50", "refId": "A", "type": "timeseries", "data": { "additional": "optional json" } }, { "target": "upper_75", "refId": "B", "type": "timeseries" } ], "adhocFilters": [{ "key": "City", "operator": "=", "value": "Berlin" }] }
/query 接口的返回结果格式类似:
[{ "target": "upper_75", //The field being queried for "datapoints": [ [622, 1450754160000], //Metric value as float, timestamp in milliseconds [365, 1450754220000] ] }, { "target": "upper_90", "datapoints": [ [861, 1450754160000], [767, 1450754220000] ] } ]
/query 接口实现后,就可以对query获取的数据进行图表绘制了。
-
/annotations
/annotations 接口用于返回注释,什么是注释? grafana 的注释就是指在 panel 上打出的标记,上面填写作者自己的备注,可以是个 tip,也可以是个醒目的 tag。举个栗子,假设我对某主机的 cpu 利用率进行了监控,当利用率超过 15% 的时候,我希望在 panel 中自动给出一个醒目的提示信息,这个时候就需要用到 annotation 接口了,我们先来预览一下 annotation 的效果:
/annotations 接口须是针对时间序列数据而言的,对于非时间序列数据类型的 panel,无法添加 annotation 注解。/annotations 接口请求方式是 POST ,请求体类似于:
{ "range": { "from": "2016-04-15T13:44:39.070Z", "to": "2016-04-15T14:44:39.070Z" }, "rangeRaw": { "from": "now-1h", "to": "now" }, "annotation": { "name": "deploy", "datasource": "JSON Datasource", "iconColor": "rgba(255, 96, 96, 1)", "enable": true, "query": "#deploy", }, "variables" [] }
/annotations 接口的返回结果格式类似于:
[{ "text": "text shown in body" // text 为注解显示信息, 可有可没有. "title": "Annotation Title", // title 为注解的标题, 可有可没有. "isRegion": true, // 对一个区域范围做注解(true), 或者对一个时间点做注解(false), 必填项. "time": "timestamp", // 注解的起始时间, long 类型的时间毫秒值, 必填项. "timeEnd": "timestamp", // 注解的结束时间, long 类型的时间毫秒值, 如果 isRegion=true 那这个就是必填项了, 如果 isRegion=false 那这个可有可没有. "tags": ["tag1"], // 注解的标题按, 可有可没有. }]
/annotations 接口实现后,就可以为 panel 配置注解功能了:
Dashboard setting => Annotations => Add Annotation Query
保存之后,而且 annotation 实现没有问题,就可以看到上文那个预览图的效果了。
annotation 的相关功能实现,感谢 @满口新式 同学的留言。
Demo — 使用SNMP + Grafana对物理机的各项指标进行实时监控与可视化展示
接下来结合一个demo对Grafana的JSON数据源插件的使用以及相应接口的实现做详细介绍。源数据为通过SNMP协议采集的物理机的各项指标,包括CPU利用率、物理内存的利用率、虚拟内存的利用率、磁盘信息等。
整体架构
整体架构如下图所示:
我们的主要工作在于上图中的第二个模块和第三个模块:
- 解析JSON插件发来的http请求
- 向目标主机发送snmp请求获取目标主机的目标参数
- 获取snmp响应中目标主机的各项参数
- 将snmp响应结果封装成JSON插件支持的数据格式并作为结果返回
开启 SNMP 服务
启用或关闭 windows 功能:
计算机管理 => 服务
编码实现
监控的每个目标需要实现一个相应的 controller ,结构如下:
public interface BaseController {
@RequestMapping(value = "/", method = {RequestMethod.GET})
@ResponseBody String test();
@RequestMapping(value = "/query", method = {RequestMethod.POST})
@ResponseBody String query(@RequestBody String requestBody);
@RequestMapping(value = "/search", method = {RequestMethod.POST})
@ResponseBody String search(@RequestBody String requestBody);
@RequestMapping(value = "/annotations", method = {RequestMethod.POST})
@ResponseBody String annotations(@RequestBody String requestBody);
}
controller 通过调用相应的 service 获取目标主机的各项参数:
public abstract class BaseService {
protected String STATUS = "status";
protected String SUCCESS = "success";
protected String ANNOTATIONS = "annotations";
public String TARGET = "target";
public String DATA_POINTS = "datapoints";
public JSONObject testConnection() {
JSONObject connection = new JSONObject();
connection.put(STATUS, SUCCESS);
return connection;
}
public abstract JSONArray getQueryResult();
public abstract JSONArray getSearchResult();
public abstract JSONArray getAnnotationResult();
}
最后附上完整的 Demo 源码链接https://download.csdn.net/download/lanshanzhuyao/11350549
完善了 /annotation 接口的的 Demo 资源更新 https://download.csdn.net/download/LANSHANZHUYAO/12689819