導語
在時序分析及監(jiān)控展示領域,Grafana無疑是開源解決方案中的翹楚,其靈活的插件機制,支持各種漂亮的面板、豐富的數(shù)據(jù)源以及強大的應用。典型的面板有Graph、Text、Singlestat、PieChart、Table、Histogram等,支持的數(shù)據(jù)源有ES、Graphite、InfluxDB、OpenTSDB、MySQL、Druid 、Prometheus、SimpleJson等,提供的應用有Zabbix、K8s等。但是某公司在分布式集群中物理機監(jiān)控的數(shù)據(jù)源為gRPC方式,即連接gRPC即可獲取實時物理機監(jiān)控信息,如CPU,內存,磁盤,負載等信息,這樣就能使用后臺轉發(fā)gRPC的消息,這里使用SSM框架的java后臺為grafana提供的SimpleJson數(shù)據(jù)源。
作者撰文時,網(wǎng)上幾乎沒有分享SimpleJson數(shù)據(jù)源的java后臺API,為此分享給大家,初次分享,不便之處請見諒。
整體架構如下所示:

一、WebAPI
如果要支持SimpleJson,后端WebAPI需要實現(xiàn)4個URL:
/:返回200,用于SimpleJson數(shù)據(jù)源測試連通性;
/search:返回所有可選的指標;
/query:返回對應指標的時間序列點;
/annotations:返回注解。
@RequestMapping(value = "/", method = RequestMethod.GET)
@ResponseBody
public Map ReturnTest(HttpServletResponse response){
response.setHeader("Access-Control-Allow-Headers", "accept, content-type");
response.setHeader("Access-Control-Allow-Methods", "POST");
response.setHeader("Access-Control-Allow-Origin", "*");
Map<String, Object> map = new HashMap<String, Object>();
map.put("result", "200 ok");
return map;
}
@RequestMapping(value = "/search", method = RequestMethod.POST)
@ResponseBody
public List Search(HttpServletResponse response) {
response.setHeader("Access-Control-Allow-Headers", "accept, content-type");
response.setHeader("Access-Control-Allow-Methods", "POST");
response.setHeader("Access-Control-Allow-Origin", "*");
List<String> result = new ArrayList<String>();
result.add("CPU");
result.add("RAM");
result.add("LOAD");
result.add("SWAP");
result.add("DISK");
result.add("NET");
return result;
}
``
```java
@RequestMapping(value = "/query", method = RequestMethod.POST)
@ResponseBody
public List Query(@RequestBody Map<String,Object> params, HttpServletResponse response) {
List<Map> targetList = (List) params.get("targets");
List<Map<String, Object>> result = new ArrayList<Map<String, Object>>() ;
for (Map targetMap : targetList){
String target = (String)targetMap.get("target");
Map scopedVars = (Map) params.get("scopedVars");
Map IP = (Map) scopedVars.get("IP");
String nodeIP = (String) IP.get("text");
if (target.equals("CPU")){
result.add(nodeMonitorService.getCpuMap(nodeIP));
}else if (target.equals("RAM")){
result.add(nodeMonitorService.getRamMap(nodeIP));
}else if (target.equals("LOAD")) {
result.add(nodeMonitorService.getLoadMap(nodeIP));
}else if (target.equals("SWAP")){
result.add(nodeMonitorService.getSwapMap(nodeIP));
}else if(target.equals("DISK")){
result = nodeMonitorService.getDiskList(nodeIP);
}else if (target.equals("NET")){
result = nodeMonitorService.getNetList(nodeIP);
}
}
response.setHeader("Access-Control-Allow-Headers", "accept, content-type");
response.setHeader("Access-Control-Allow-Methods", "POST");
response.setHeader("Access-Control-Allow-Origin", "*");
Collections.sort(result, new Comparator<Map<String, Object>>() {
public int compare(Map<String, Object> o1, Map<String, Object> o2) {
String name1 = String.valueOf(o1.get("target").toString()) ;
String name2 = String.valueOf(o2.get("target").toString()) ;
return name1.compareTo(name2);
}
});
return result;
}
@RequestMapping(value = "/annotations", method = RequestMethod.POST)
@ResponseBody
public Map Annotations() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("result", "200 ok");
return map;
}
注意header里面加上這3條:
response.setHeader("Access-Control-Allow-Headers", "accept, content-type");
response.setHeader("Access-Control-Allow-Methods", "POST");
response.setHeader("Access-Control-Allow-Origin", "*");
二、grafana配置
安裝grafana,安裝SimpleJson插件,在grafana官網(wǎng),有詳細說明。
啟動訪問,使用admin賬戶登錄,
1、創(chuàng)建數(shù)據(jù)源:DataSources
type選擇SimpleJson類型,URL填入后臺服務的API地址,

2、創(chuàng)建面板dashboard
這個面板我已經(jīng)分享到grafana網(wǎng)站了,可以前去下載:https://grafana.com/dashboards/5075

綜上所述,基于SimpleJson數(shù)據(jù)源,只要配置數(shù)據(jù)源之后,按正確的方式添加API即可將數(shù)據(jù)靈活展現(xiàn)在Grafana中,當然SimpleJson只是一個數(shù)據(jù)源協(xié)議載體,理論上可以對接任何類型的后臺數(shù)據(jù),只要組裝成它支持的格式即可。