【弄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~
更多推荐
所有评论(0)