【弄nèng - Grafana】入门篇(九)—— 配置使用JSON_DataSource数据源

JSON数据源针对任意后端执行JSON请求。Grafana虽然支持很多数据源,但是有一些特殊的数据处理没办法实现,JSON数据源使得我们更加灵活的组装我们想要的数据。使Grafana不在有数据源的限制。更加灵活。
地址传送门,本文参考官网和https://blog.csdn.net/lanshanzhuyao/article/details/95888257#JSON_DataSource_27

1. 安装

要使用该grafana-cli工具安装此插件,请执行以下操作:

 grafana-cli plugins install simpod-json-datasource

安装完成后重启Grafana服务。

2. 使用API

要使用此数据源,后端需要实现4个URL:

  • /应该返回200 ok。用于数据源配置页面上的“测试连接”。
  • /search 当由面板中“查询”选项卡上的“查找指标”选项调用时,应返回可用指标。
  • /query 应该根据输入返回指标。
  • /annotations 应该返回注释。

这两个网址是可选的:

  • /tag-keys 应该返回临时过滤器的标记键。
  • /tag-values 应该返回临时过滤器的标记值。

2.1 /

/ 该接口用于对数据源进行测试,请求方式是 GET ,调用状态码为200即可,返回实体为:

{"status":"success"}

2.2 /search

/search 该接口用于在编辑图表Query时选择相应的Metric
在这里插入图片描述
返回实体为:

[
    "cpuInfo",
    "netInfo"
]

也可以设定为Map形式

[ { "text": "cpuInfo", "value": 1}, { "text": "netInfo", "value": 2} ]

2.3 /query

/query 接口用于返回query所请求的数据,请求方式是 POST 。分为timeseries和table

2.3.1 timeseries

timeseries请求体类似于:

{
  "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": "Packets", "refId": "A", "type": "timeseries", "data": { "additional": "optional json" } },
     { "target": "Errors", "refId": "B", "type": "timeseries" }
  ],
  "adhocFilters": [{
    "key": "City",
    "operator": "=",
    "value": "Berlin"
  }]
}

targets中的data可以存储自定义参数,例如Metrics设置如下:
在这里插入图片描述
则target中就会附加data:

{
    "target":"upper_50",
    "refId":"A",
    "type":"timeseries",
    "data":{
        "additional":"optional json"
    }
}

timeseries响应体类似于:

[
  {
    "target":"pps in",
    "datapoints":[
      [622,1450754160000],  // Metric value as a float , unixtimestamp in milliseconds
      [365,1450754220000]
    ]
  },
  {
    "target":"pps out",
    "datapoints":[
      [861,1450754160000],
      [767,1450754220000]
    ]
  }
  {
    "target":"errors out",
    "datapoints":[
      [861,1450754160000],
      [767,1450754220000]
    ]
  }
  {
    "target":"errors in",
    "datapoints":[
      [861,1450754160000],
      [767,1450754220000]
    ]
  }
]

datapoints 中数组,第一个是值,第二个是时间戳。

2.3.2 table

table请求体同timeseries

table响应体类似于:

{
  "columns":[
    {"text":"Time","type":"time"},
    {"text":"Country","type":"string"},
    {"text":"Number","type":"number"}
  ],
  "rows":[
    [1234567,"SE",123],
    [1234567,"DE",231],
    [1234567,"US",321]
  ],
  "type":"table"
}

2.4 /annotations

/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": []
}

响应体类似于:

[
  {
    "text": "text shown in body" // Text for the annotation. (required)
    "title": "Annotation Title", // The title for the annotation tooltip. (optional)
    "isRegion": true, // Whether is region. (optional) (http://docs.grafana.org/reference/annotations/#adding-regions-events)
    "time": "timestamp", // Time since UNIX Epoch in milliseconds. (required)
    "timeEnd": "timestamp", // Time since UNIX Epoch in milliseconds (required if `isRegion` is true )
    "tags": ["tag1"], // Tags for the annotation. (optional)
  }
]

2.5 /tag-keys

/tag-keys 返回临时过滤器的标记键
请求体类似于:

{}

响应体类似于:

[
    {"type":"string","text":"City"},
    {"type":"string","text":"Country"}
]

2.6 /tag-values

/tag-values 返回临时过滤器的标记值
请求体类似于:

{"key": "City"}

响应体类似于:

[
    {"text": "Eins!"},
    {"text": "Zwei"},
    {"text": "Drei!"}
]

3. JAVA实现API

3.1 Controller

基础类

package com.it.cloud.modules.grafana.controller.base;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

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();
	
	@RequestMapping(value = "/annotations", method = {RequestMethod.POST})
	@ResponseBody String annotations(@RequestBody String requestBody);
	
}

实现类

package com.it.cloud.modules.grafana.controller;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.it.cloud.common.annotation.SysLog;
import com.it.cloud.common.base.Result;
import com.it.cloud.common.constants.SysConstants;
import com.it.cloud.common.utils.PageUtils;
import com.it.cloud.common.validator.ValidatorUtils;
import com.it.cloud.common.validator.group.AddGroup;
import com.it.cloud.modules.auth.entity.UserEntity;
import com.it.cloud.modules.auth.service.IUserService;
import com.it.cloud.modules.grafana.controller.base.BaseController;
import com.it.cloud.modules.grafana.service.CpuService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 司马缸砸缸了
 * @since 2019-07-15
 */
@Api(value = "JSON控制器", tags = "用户")
@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/grafana/json")
public class JsonController implements BaseController {
    @Autowired
    private CpuService cpuService;


    @Override
    public String test() {
        log.trace("trace 成功了");
        log.debug("debug 成功了");
        log.info("info 成功了");
        log.warn("warn 成功了");
        log.error("error 成功了");
        JSONObject connection = cpuService.testConnection();
        return connection.toString();
    }

    @Override
    public String query(String requestBody) {
        log.info(requestBody);
        JSONArray cpuInfo = cpuService.getQueryResult();
        return cpuInfo.toString();
    }

    @Override
    public String search() {
        JSONArray metrics = cpuService.getSearchResult();
        return metrics.toString();
    }

    @Override
    public String annotations(String requestBody) {
        JSONObject annotations = cpuService.getAnnotationResult();
        return annotations.toString();
    }

    @RequestMapping(value = "/tag-keys", method = {RequestMethod.POST})
    @ResponseBody String tagKeys(@RequestBody String requestBody){

        String keys = "[\n" +
                "    {\"type\":\"string\",\"text\":\"City\"},\n" +
                "    {\"type\":\"string\",\"text\":\"Country\"}\n" +
                "]";
        return keys;
    }
}

3.2 Service

基础类

package com.it.cloud.modules.grafana.service.base;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

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 JSONObject getAnnotationResult() {
		JSONObject annotationResult = new JSONObject();
		annotationResult.put(ANNOTATIONS, "result");
		return annotationResult;
	}
	
}

实现类

package com.it.cloud.modules.grafana.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.it.cloud.modules.grafana.service.base.BaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.*;

@Service
@Slf4j
public class CpuService extends BaseService {

    public static final String CPU_INFO = "cpuInfo";
    private static int MAX_SIZE = 1000;
    private List<Map<Long, Double>> cpuUtilInfo = new LinkedList<Map<Long, Double>>();

    @Override
    public JSONArray getSearchResult() {
        JSONArray searchResult = new JSONArray();
        searchResult.add(CPU_INFO);
        return searchResult;
    }

    @Override
    public JSONArray getQueryResult() {
        collectCPUInfo();
        JSONArray cpuInfo = timeSeriesFormat();
        return cpuInfo;
    }

    private void collectCPUInfo() {
        if (cpuUtilInfo.size() > 1000) {
            cpuUtilInfo.remove(0);
        }

        Map<Long, Double> map = Maps.newHashMap();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        map.put(calendar.getTimeInMillis(), Double.valueOf(10 + Math.random()));
        cpuUtilInfo.add(map);
    }

    private JSONArray timeSeriesFormat() {
        JSONArray timeSeriesResult = new JSONArray();
        JSONObject cpuInfo = new JSONObject();
        cpuInfo.put(TARGET, CPU_INFO);
        JSONArray datapoints = new JSONArray();

        for (Map<Long, Double> tempInfo : cpuUtilInfo) {
            for (Map.Entry<Long, Double> entry : tempInfo.entrySet()) {
                JSONArray tempArray = new JSONArray();
                tempArray.add(entry.getValue());
                tempArray.add(entry.getKey());
                datapoints.add(tempArray);
            }
        }
        cpuInfo.put(DATA_POINTS, datapoints);
        timeSeriesResult.add(cpuInfo);
        return timeSeriesResult;
    }

}

4. Grafana添加JSON 数据源

左侧菜单配置–Data Sources – Add data source-- Json

在这里插入图片描述
Save & Test

5. 使用JSON 数据源

在这里插入图片描述


项目推荐

IT-CLOUD :IT服务管理平台,集成基础服务,中间件服务,监控告警服务等。
IT-CLOUD-ACTIVITI6 :Activiti教程源码。博文在本CSDN Activiti系列中。
IT-CLOUD-ELASTICSEARCH :elasticsearch教程源码。博文在本CSDN elasticsearch系列中。

开源项目,持续更新中,喜欢请 Star~

发布了160 篇原创文章 · 获赞 46 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/yy756127197/article/details/103475529