實踐:物理機實時監(jiān)控UI之grafana(SimpleJson)+gRPC

導語

在時序分析及監(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ù),只要組裝成它支持的格式即可。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容