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

導(dǎo)語(yǔ)

在時(shí)序分析及監(jiān)控展示領(lǐng)域清寇,Grafana無(wú)疑是開(kāi)源解決方案中的翹楚浩村,其靈活的插件機(jī)制做葵,支持各種漂亮的面板、豐富的數(shù)據(jù)源以及強(qiáng)大的應(yīng)用心墅。典型的面板有Graph酿矢、Text、Singlestat怎燥、PieChart瘫筐、Table、Histogram等铐姚,支持的數(shù)據(jù)源有ES策肝、Graphite、InfluxDB隐绵、OpenTSDB之众、MySQL、Druid 依许、Prometheus棺禾、SimpleJson等,提供的應(yīng)用有Zabbix峭跳、K8s等膘婶。但是某公司在分布式集群中物理機(jī)監(jiān)控的數(shù)據(jù)源為gRPC方式,即連接gRPC即可獲取實(shí)時(shí)物理機(jī)監(jiān)控信息坦康,如CPU竣付,內(nèi)存,磁盤(pán)滞欠,負(fù)載等信息古胆,這樣就能使用后臺(tái)轉(zhuǎn)發(fā)gRPC的消息,這里使用SSM框架的java后臺(tái)為grafana提供的SimpleJson數(shù)據(jù)源筛璧。

作者撰文時(shí)逸绎,網(wǎng)上幾乎沒(méi)有分享SimpleJson數(shù)據(jù)源的java后臺(tái)API,為此分享給大家夭谤,初次分享棺牧,不便之處請(qǐng)見(jiàn)諒。

整體架構(gòu)如下所示:

一朗儒、WebAPI

如果要支持SimpleJson颊乘,后端WebAPI需要實(shí)現(xiàn)4個(gè)URL:

/:返回200参淹,用于SimpleJson數(shù)據(jù)源測(cè)試連通性;
/search:返回所有可選的指標(biāo)乏悄;
/query:返回對(duì)應(yīng)指標(biāo)的時(shí)間序列點(diǎn)浙值;
/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)规求,有詳細(xì)說(shuō)明筐付。
啟動(dòng)訪問(wèn),使用admin賬戶(hù)登錄阻肿,

1瓦戚、創(chuàng)建數(shù)據(jù)源:DataSources

type選擇SimpleJson類(lèi)型,URL填入后臺(tái)服務(wù)的API地址冕茅,

2伤极、創(chuàng)建面板dashboard

這個(gè)面板我已經(jīng)分享到grafana網(wǎng)站了,可以前去下載:https://grafana.com/dashboards/5075

綜上所述姨伤,基于SimpleJson數(shù)據(jù)源哨坪,只要配置數(shù)據(jù)源之后,按正確的方式添加API即可將數(shù)據(jù)靈活展現(xiàn)在Grafana中乍楚,當(dāng)然SimpleJson只是一個(gè)數(shù)據(jù)源協(xié)議載體当编,理論上可以對(duì)接任何類(lèi)型的后臺(tái)數(shù)據(jù),只要組裝成它支持的格式即可徒溪。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末忿偷,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子臊泌,更是在濱河造成了極大的恐慌鲤桥,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件渠概,死亡現(xiàn)場(chǎng)離奇詭異茶凳,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)播揪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)贮喧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人猪狈,你說(shuō)我怎么就攤上這事箱沦。” “怎么了雇庙?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵谓形,是天一觀的道長(zhǎng)灶伊。 經(jīng)常有香客問(wèn)我,道長(zhǎng)套耕,這世上最難降的妖魔是什么谁帕? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任峡继,我火速辦了婚禮冯袍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘碾牌。我一直安慰自己康愤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布舶吗。 她就那樣靜靜地躺著征冷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪誓琼。 梳的紋絲不亂的頭發(fā)上检激,一...
    開(kāi)封第一講書(shū)人閱讀 51,488評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音腹侣,去河邊找鬼叔收。 笑死,一個(gè)胖子當(dāng)著我的面吹牛傲隶,可吹牛的內(nèi)容都是我干的饺律。 我是一名探鬼主播,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼跺株,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼复濒!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起乒省,我...
    開(kāi)封第一講書(shū)人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤巧颈,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后袖扛,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體砸泛,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年攻锰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了晾嘶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡娶吞,死狀恐怖垒迂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情妒蛇,我是刑警寧澤机断,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布楷拳,位于F島的核電站,受9級(jí)特大地震影響吏奸,放射性物質(zhì)發(fā)生泄漏欢揖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一奋蔚、第九天 我趴在偏房一處隱蔽的房頂上張望她混。 院中可真熱鬧,春花似錦泊碑、人聲如沸坤按。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)臭脓。三九已至,卻和暖如春腹忽,著一層夾襖步出監(jiān)牢的瞬間来累,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工窘奏, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嘹锁,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓蔼夜,卻偏偏與公主長(zhǎng)得像兼耀,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子求冷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 一瘤运、準(zhǔn)備搭建環(huán)境 1.系統(tǒng):CentOS 7.3 2.軟件:Zabbix 3.2 二、安裝前的準(zhǔn)備 最小化安裝Ce...
    塵世不擾閱讀 4,144評(píng)論 8 31
  • 1. 準(zhǔn)備搭建環(huán)境 1.1 系統(tǒng):CentOS 7.3 1.2 軟件:Zabbix 3.2 主機(jī)IP地址系統(tǒng)Zab...
    若有所思11閱讀 729評(píng)論 0 0
  • 【《熒惑VS該婭》目錄】戳進(jìn)來(lái)吧匠题,親拯坟! 【上一章】第九章:我最親愛(ài)的 【下一章】第十一章:陰謀 前景再現(xiàn):楊寶...
    藍(lán)眼鏡閱讀 340評(píng)論 0 1
  • 午后郁季,陽(yáng)光明媚。決定出門(mén)尋找一下春天钱磅。隨手拍下了我看到的春天梦裂。
    那些花兒Flowers閱讀 500評(píng)論 0 0
  • 多么感謝年柠,你能回來(lái),我們能回去褪迟! 在雯子兄的推薦下冗恨,周末在家里宅著追完了《致我們單純的小美好》答憔,似乎是把青春...
    雜草虹閱讀 487評(píng)論 0 2