您的位置:首页 > Web前端 > JavaScript

Grafana SimpleJson插件实现自定义数据源

2020-02-01 06:42 525 查看

SimpleJson数据源简介

Grafana作为最火热的开源数据可视化工具,最大的特点就是支持多种数据源以及丰富的插件库了。官方提供了Elasictsearch、Prometheus、Mysql等常见数据库的数据源,社区也提供了支持Zabbix监控数据展示的数据源,但是实际应用中仍会遇到现有数据源无法满足需求的情况。比如Grafana没有现成插件支持从MongoDB等其他数据库中读取数据。

SimpleJson是Grafana开源社区提供的数据源,它本身并不依赖某种特定的后端存储,只需要后端能实现Grafana报表的几个查询接口就行,可以说给开发者提供了很大的想象空间了。

SimpleJson 基本原理

SimpleJson是Grafana众多数据源插件中的一种,但它又不像其他插件配置好数据库信息就能用,开发者需要自己实现一部分数据源插件的功能来使SimpleJson插件能够使用。

Grafana官方的数据源插件开发指南中写到:

Data source plugins enables people to develop plugins for any database that communicates over http. Its up to the plugin to transform the data into time series data so that any grafana panel can then show it.

也就是说一个 DataSource 插件主要是实现了一个 HTTP 服务,把后端数据源中的数据提取成HTTP协议中的数据体并返回给Grafana。
对照一下 DataSource 插件开发和 SimpleJson 的实现要求:

DataSource SimpleJson
可用性测试接口
指标展示接口
数据查询接口
注释展示接口
配置文件
配置控制器
数据查询控制器
注释查询控制器

可以看到SimpleJson其实是对数据源插件的进一步简化,只要求开发者处理跟数据处理相关的接口即可。在开发指南中,数据源插件的上述功能都要通过JavaScript对象来实现的,而SimpleJson只需要开发者实现满足上面那些接口的HTTP服务,也就是说你可以用自己熟悉的语言来实现。

SimpleJson后端需要实现的四个接口:

  • /
    用于数据源配置界面的"Test connection"调用,若后端服务器正常应返回 200 状态码
  • /search
    用于 panel 面板中查询有哪些可用的指标
  • /query
    基于用户的查询语句,返回相应的数据
  • /annotations
    返回注释内容

后端实现

SimpleJson的Github仓库中推荐了4个后端实现用于参考:

  • https://github.com/bergquist/fake-simple-json-datasource
  • https://github.com/smcquay/jsonds
  • https://github.com/ContextLogic/eventmaster
  • https://gist.github.com/linar-jether/95ff412f9d19fdf5e51293eb0c09b850 (Python/pandas backend)
    分别是用 JavaScript,Go,Python等语言实现的,在下面的实践案例中我用的是基于Python pandas库的后端实现

实践案例

场景:工作中需要对eureka服务列表完整性进行监控,不仅要能在服务下线时告警还需要能够通过报表展示过去一段时间的情况,毕竟有时候告警响应不及时或者被其他告警信息淹没时,还是需要监控图表来展示往期状态的。

Grafana本身没有存储功能,数据都是存储在数据源插件中配置的后端数据库中,得益于SimpleJson的开放性,我们可以选择Sqlite甚至CSV文件这些轻量的东西来保存数据。

SimpleJson的 Python实现中,主要是通过这段代码来处理核心逻辑:

这段是实例代码,效果是展示一个正弦函数的曲线图

def get_sine(freq, ts_range):
freq = int(freq)
ts = pd.date_range(ts_range['$gt'], ts_range['$lte'], freq='H')
return pd.Series(np.sin(np.arange(len(ts)) * np.pi * freq * 2 / float(len(ts))), index=ts).to_frame('value')

add_reader('sine_wave', get_sine)

add_reader函数是增加一个指标并将指标与一个函数绑定,也就是这里的get_sine函数,用于从后端读取数据并处理成特定的数据结构(不过这个例子中没有后端数据)。

get_sine函数接受两个参数,freq和ts_range,ts_range就是Grafana右上角的时间范围,freq属于指标的额外参数,当你在查询面板输入查询语句 sine_wave:24,就会调用 get_sine(24, ts_range)。

然后get_sine函数利用Pandas的series和data_frame 两种数据结构,最后返回一个类似这样的数据:

sine_wave
2019-11-30 1
2019-12-01 0

每行数据都是一个 datapoint,根据时间戳和值在图表上打数据点,而sine_wave就是这些数据点从属的指标名称。

如果你要加个自己的指标和处理函数,大概就是写这些代码:

def <处理函数>(<额外参数,可选>, ts_range):
data_point = <根据时间范围,从后端数据中读取符合条件的时间戳和对应的值,
每个时间戳需要是Pandas的datetime类型>
return <将data_point处理成Pandas的data frame数据结构并返回>

add_reader('<指标名称>', <处理函数>)

思考与总结

  1. 依赖倒置原则: Grafana支持多种数据源,并不为每种数据源都去适配一个专门的解决方案,而是通过声明接口,让各种数据源去实现,这就是软件设计模式中著名的依赖倒置原则的体现了,在生产活动中的说法就是标准化是规模化的前提了。
  2. 通过不断简化降低上手门槛:SimpleJson使用户自定义数据源更加方便,就是因为它屏蔽了查询界面UI设计这些用户不太关心的高级设置,只把最重要的数据处理接口交给用户,又有许多开发者提供后端实现模板进一步简化了工作量,让我这样只有一些Python编程基础的人也能自定义数据源。说明软件中的插件设计要尽量灵活可配置,让高手玩家能够深度定制;但是在推广过程中也需要不断简单化,让更多小白都能有上手机会。
  • 点赞
  • 收藏
  • 分享
  • 文章举报
wonain 发布了3 篇原创文章 · 获赞 0 · 访问量 126 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: