首页 > 其他分享 >Grafana 自定义数据源支持 RESTful API 查询

Grafana 自定义数据源支持 RESTful API 查询

时间:2023-12-20 21:47:11浏览次数:52  
标签:插件 自定义 展示 数据源 Grafana query 数据

背景

数据爆炸的时代,信息化步伐越来越快,接入互联网的服务越来越多。随着业务迭代变更越来越复杂化,需求/产品者对系统的要求越来越高,对业务走势及健康状态需要更直观的感知。这意味着我们需要随时能够“看见”系统的状态,对系统/业务的实时监控以及可视化是技术演进的必然。

Grafana 是什么?

Grafana 是一个可视化面板(Dashboard),有着非常漂亮的图表和布局展示,功能齐全的度量仪表盘和图形编辑器。支持 Graphite、zabbix、InfluxDB、Prometheus 和 OpenTSDB 作为数据源。

Grafana 特点:

  • 丰富的仪表盘插件:折线图、饼图、地图等,官方提供丰富的图表可供选择
  • 支持多种后端库:官方支持的时序数据库非常丰富,基本常用 API 皆可满足
  • 注释:支持直接在看板上标注注释,记录现场发生的问题待复盘使用
  • 过滤器:使用 Ad-hoc 过滤器允许动态创建新的键/值过滤器

合理利用 Grafana 图表和功能,能创造出非常 Amazing 的图表,可以参考下图一官网的模板示例:

图一 Grafana 示例模板

挑战

虽然 Grafana 的图表和插件很丰富,但是在实际的生产使用中,我们发现 Grafana 还是不能满足业务需求,官方和社区提供的数据源插件,大多是“运维型”的,即数据源本身实现的功能是监测数据源本身的性能状态,而不是数据源内存储的业务数据。

如官方提供的 Redis 数据源 Redis Data Source for Grafana ,该插件提供很多当前 Redis 数据源的包括但不限于:QPS、连接数、key 数量、网络、内存使用等等,如图二是官方提供的示例图:

图二 Redis 数据源看板示例

那如何查询 Redis 内存储的业务数据?如何监控业务数据是否波动?如果数据存在 Hbase、MySQL/PG、或者一些小众的数据源中,那又如何展示呢?本文就自定义数据源支持 RESTful API 方式做详细介绍。

熟悉 Grafana

我将基于一个 Grafana + ES 的 demo 向你展示如何使用,还是那句话,先会用,再去学。直观的使用并感受它,为更好的深入理解做准备。

 

环境搭建

我假设你熟悉 docker 使用方式,我将基于 docker 搭建 Grafana 环境及配置

1
2
3
4
5
6
7
8
9
10
docker pull grafana/grafana -- 拉取最新的grafana镜像
docker images -- 查看是否存在镜像

-- 运行 grafana 镜像
-- 其中 -e 是指定需要安装的插件
docker run -d \
-p 3000:3000 \
--name=grafana \
-e "GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource" \
grafana/grafana

如果一切顺利,此时访问 http://localhost:3000 可以看到图三界面(默认密码登录即可),则搭建完毕。

图三 Grafana 登录界面

集成 Elasticsearch

同上安装 docker 一直,Elasticsearch 也是基于 docker 安装

1
2
3
4
5
6
docker pull elasticsearch
docker run -d \
--name elasticsearch \
--net somenetwork \
-p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" elasticsearch:tag

配置数据源
如图四,添加 Elasticsearch 数据源

图四 添加数据源

如图五,搜索框输入关键字,匹配到 Elasticsearch 数据源后,点击 Select 开始配置

图五 选择 Elasticsearch 数据源

如图六,配置数据源信息,假设你或者公司的 ES 集群需要权限认证,则需要配置 Auth 相关信息

图六 配置 ES 数据源地址 & 授权信息

如图七,配置 ES Index 相关信息,然后保存,如果测试联通则保存成功,此时 Grafana 已经有访问 ES 的权限了。

图七 配置 ES 索引信息

下面我们就可以搭建看板并访问 ES 内的数据了,如图八,首先创建一个 Dashboard 默认初始化一个 Panel ,也可以点击右上角的 “图表+” 创建新的 Panel 看板。

图八 创建 Dashbard & Panel

Query 处填写 ES 查询语句(完全兼容 Lucene query syntax),添加分组信息,即可查看数据(此处省略 ES 写入数据逻辑),如图九所示

图九 ES Panel 配置 ES 查询语句及分组

Grafana 自定义数据源

如何通过 Grafana 去查询业务数据并展示呢?假设业务数据是存储在 Redis 中,首先得去官网的 Data Sources 资源库中检索是否存在插件,其次再去社区或者 Github 上搜寻是否有开源的适配插件。假设存在,那就开心了,拿来主义;如果不存在,要么将数据同步到能找到插件的库中存储,要么就得自己实现一个插件,两个方案怎么看都是不可控的。

那有没有能直接适配所有库的插件呢?很明显是不存在的。那如何能满足一个插件对应所有的数据库?想想后端-前端开发交互,前端在获取数据时是通过 API,而不会去关心后端的数据是从 Hbase 来的还是从 Redis 来的。中间的桥接层正是 Controller,即 RESTful API 协议接口。如图十所示:


图十 数据源插件实现对比

此时已经相当明显了,只需要找到支持 RESTful API 的数据源插件即可“一劳永逸”!幸运的是社区真的有志同道合的开发者,提供了开源的插件 JSON API Grafana Datasource.

RESTful API 数据源插件

JSON API Grafana Datasource 支持任意后端请求,并返回 JSON 数据给到 Grafana 作数据渲染。此处不在演示如何安装此款数据源插件,可以看下该数据源插件特点如下(具体的数据接口可查看官网地址):

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

  • GET /带有 200 状态代码响应。属于数据源测试的心跳接口。
  • POST /search 很重要,假设你需要自定义变量,需要用到该接口。
  • POST /query 很重要,自定义实现图表数据的展示接口。

这两个网址是可选的(基本不用):

  • POST /tag-keys 为临时过滤器返回标签键。
  • POST /tag-values 为临时过滤器返回标签值。

该数据源最大特点是支持传递自定义参数 JSON 到后端,这为我们设计统一的接口协议是利好的。经过梳理分析,我们设计如下架构,如图十一所示:


图十一 数据查询接口设计

四个接口实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@Slf4j
@RestController
@RequestMapping("/grafana")
public class GrafanaController {

@Autowired
private GrafanaJsonDataSourceGenerator grafanaJsonDataSourceGenerator;

/**
* 该接口用于对数据源进行测试,请求方式是 GET ,无需返回有意义的实体,调用状态码为200即可
*
* @return
*/
@GetMapping
public String status() {
return "success";
}

/**
* 接口用于在编辑图表query时选择相应的metric
*
* @param search
* @return
*/
@PostMapping("/search")
public String[] search(@RequestBody GrafanaSearch search) {
return grafanaJsonDataSourceGenerator.search(search);
}

/**
* 接口用于返回query所请求的数据
*
* @param dto
* @return
*/
@PostMapping("/query")
public Object query(@RequestBody GrafanaQuery dto) {
return grafanaJsonDataSourceGenerator.generate(dto);
}

/**
* returning annotations.
* 暂时用不到
*
* @param req
* @return
*/
@PostMapping("/annotations")
public List<AnnotationData> annotations(@RequestBody GrafanaAnnotations req) {
return grafanaJsonDataSourceGenerator.annotations(req);
}
}

DataHandle 路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Override
public List<SimpleBaseData> generate(GrafanaQuery query) {
if (CollectionUtils.isEmpty(query.getTargets())) {
return Collections.emptyList();
}

return query.getTargets().stream()
.filter(t -> StringUtils.isNotEmpty(t.getTarget()))
// 解析自定义指标
.map(this::analyzeCustomerConfig)
.filter(ct -> StringUtils.isNotEmpty(ct.getHandle()))
// 定位解析器
.map(ct -> execHandle(ct, query))
.flatMap(Collection::stream)
.collect(Collectors.toList());
}

private List<SimpleBaseData> execHandle(CustomerTargetInfo ct, GrafanaQuery query) {
TimeRange timeRange = analyzeCustomerTimeRange(ct, query.getRange());
List<SimpleBaseData> list = applicationContext.getBean(TARGET_HANDLE_PREFIX + ct.getHandle(), IDataHandle.class)
.exec(ct, timeRange.getFrom().toDate(), timeRange.getTo().toDate());

// 包装名字&时间轴,否则无法展示
wrapRangeRawTimeData(ct, list);

// 聚合函数
aggFunHandle(ct, list);

return list;
}

此时,前端在配置查询条件时,只需要配置一段 JSON Config 即可

1
2
3
4
5
6
{
"handle": "appServerLog",
"config": {
"appNames": $appServer
}
}

Grafana 图表数据美化

Grafana 的可玩性绝对超乎你的想象,如果你是一个心灵手巧且富有美感的人,一定创造美观

标签:插件,自定义,展示,数据源,Grafana,query,数据
From: https://www.cnblogs.com/ExMan/p/17917639.html

相关文章

  • c# - 如何在自定义 System.Text.Json JsonConverter 中使用默认序列化?
    我正在写一个 custom System.Text.Json.JsonConverter 将旧数据模型升级到新版本。我已覆盖 Read()并实现了必要的后处理。但是,我根本不需要在 Write() 中做任何自定义操作。方法。如果我根本没有转换器,如何自动生成默认序列化?显然我可以使用不同的 JsonSerializerOption......
  • 关于Chart控件 C# 自定义
    usingSystem;usingSystem.Collections.Generic;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows.Forms.DataVisualization.Charting;namespacePieChartLibrary{publicclassViewProp{publ......
  • Flutter 使用PageView 自定义无限轮播
    import'package:flutter/material.dart';int_getRealIndex(intindex,intlength){returnindex>=length?index%length:index;}classInfinitySliderextendsStatefulWidget{finalintinitialPage;finalList<Widget>items;......
  • 秦疆的Java课程笔记:79 异常 自定义异常及经验小结
    使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。(秦疆老师:用的不多,但开源框架或者大型系统会用到。)用户自定义异常类,只需要继承Exception类即可。自定义异常类的步骤:创建自定义异常类在方法中通过throw关键字抛出异常对象......
  • Postgresql中PL/pgSQL的游标、自定义函数、存储过程的使用
    场景Postgresql中PL/pgSQL代码块的语法与使用-声明与赋值、IF语句、CASE语句、循环语句:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/135090263上面讲了基本语法,下面记录游标、自定义函数、存储过程的使用。注:博客:https://blog.csdn.net/badao_liumang_qizhi......
  • SpringBoot入门三十四,自定义Springboot Starter
    1.前言SpringBootStarter是一种用于简化SpringBoot应用程序配置的机制。通过自定义Starter,我们可以将一组相关的配置、依赖和自动配置打包成一个可重用的模块,使得其他开发者可以轻松地集成和使用。本篇文章将引导你创建一个简单的自定义SpringBootStarter,并演示如何在应用程序......
  • Qt自定义GridView从显示单个到九宫格
    一、概述由于测试OpenCV的需要自定义一个可变的用于显示图片的GridView,从显示单张图片到9张图片。效果图如下:这个GridView目前只是自己使用,还有瑕疵,这里仅提供一个可行性的思路,有需要可以自行扩展。二、代码示例1.自定义GridView--->VariableGridView.h/Vari......
  • 如何使用 Helm 在 K8s 上集成 Prometheus 和 Grafana|Part 1
    本系列将分成三个部分,您将学习如何使用Helm在Kubernetes上集成Prometheus和Grafana,以及如何在Grafana上创建一个简单的控制面板。Prometheus和Grafana是Kubernetes最受欢迎的两种开源监控工具。学习如何使用Helm集成这两个工具,使您能够轻松监控Kubernetes集群并......
  • C++ Qt开发:QItemDelegate 自定义代理组件
    Qt是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍QStyledItemDelegate自定义代理组件的常用方法及灵活运用。在Qt中,QStyledItemDelegate类是用于......
  • 在Mapbox-gl-js中添加自定义图层
    在Mapbox-gl-js中添加自定义图层前言一、制作geojson地图二、使用Tippecanoe将geojson转换成vectortile(.pbf)文件三、使用mapbox-gl-js显示三、Mapbox-gl-js中根据矢量数据的属性过滤显示前言本文说明如何制作自定义的地图数据,并使用mapbox-gl-js进行显示一、制作geoj......