使用Grafana的JSON DataSource插件完成对实时监控数据的可视化展示

Grafana的JSON DataSource插件

Grafana可以制作更具科技感的dashboard,支持的数据源也越来越丰富,如Elasticsearch、MySQL、Prometheus等等。

grafana jsonapi集合获取 grafana导入json_grafana


尽管如此,在大数据时代依旧有很多的数据存储在非常见的数据源中,这些数据无法直接对接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数据源的配置:

grafana jsonapi集合获取 grafana导入json_json数据源插件_02


输入 /

  • /search
    /search 接口用于在编辑图表query时选择相应的metric,即
    /search 接口的请求方式是 POST ,请求体类似于
{ "target": "upper_50" }

/search

["upper_25","upper_50","upper_75","upper_90","upper_95"]

也可以是map格式:

[ { "text" :"upper_25", "value": 1}, { "text" :"upper_75", "value": 2} ]

/search

  • /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

grafana jsonapi集合获取 grafana导入json_JSON_03

保存之后,而且 annotation 实现没有问题,就可以看到上文那个预览图的效果了。

annotation 的相关功能实现,感谢 @满口新式

Demo — 使用SNMP + Grafana对物理机的各项指标进行实时监控与可视化展示

接下来结合一个demo对Grafana的JSON数据源插件的使用以及相应接口的实现做详细介绍。源数据为通过SNMP协议采集的物理机的各项指标,包括CPU利用率、物理内存的利用率、虚拟内存的利用率、磁盘信息等。

整体架构

整体架构如下图所示:

grafana jsonapi集合获取 grafana导入json_json数据源插件_04

我们的主要工作在于上图中的第二个模块和第三个模块:

  • 解析JSON插件发来的http请求
  • 向目标主机发送snmp请求获取目标主机的目标参数
  • 获取snmp响应中目标主机的各项参数
  • 将snmp响应结果封装成JSON插件支持的数据格式并作为结果返回

开启 SNMP 服务

启用或关闭 windows 功能:

grafana jsonapi集合获取 grafana导入json_grafana jsonapi集合获取_05


计算机管理 => 服务

grafana jsonapi集合获取 grafana导入json_JSON_06

编码实现

监控的每个目标需要实现一个相应的 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 源码链接

完善了 /annotation 接口的的 Demo 资源更新

效果演示

grafana jsonapi集合获取 grafana导入json_json数据源插件_07