作为当前最流行的图形化运维监控解决方案之一,Grafana 提供了一个灵活易用的界面,可以连接多种不同的数据源,包括时序数据库(Time Series Database)、云服务、监控系统等,然后从这些数据源中提取数据并实时地将其可视化。为了给用户打造更丰富的可视化方案,TDengine 在开源不久就提供了对 Grafana 的支持,此后也在不断升级改造 TDengine Grafana 插件,还推出了基于 Grafana 的零依赖监控解决方案 TDinsight。本篇文章将以 tdengine-datasource 为例介绍 Grafana 插件开发。
实际上,tdengine-datasource 是 TDengine 为 Grafana 打造的 datasource 插件,它能够从 TDengine 读取数据,并展示到 Grafana。
开发环境准备
Grafana
go
Mage:https://github.com/magefile/mage
nodejs
-
yarn
Grafana 配置
-
修改插件加载路径。Grafana 插件会默认加载在 plugins = data/plugins,这里需要修改为自己插件的地址。这里通常改为插件项目下的 dist 目录。
[paths]
plugins = /path/to/Grafana-plugins
-
修改 allow_loading_unsigned_plugins 配置,配置项的值为插件的名字,允许 Grafana 加载 unsigned 的插件。
allow_loading_unsigned_plugins = my_plugin_name
新建插件
$ npx @Grafana/create-plugin
? What is going to be the name of your plugin? my-plugin # 输入插件名字
? What is the organization name of your plugin? taosdata # 输入公司名字
? How would you describe your plugin? my testing plugin # 输入插件描述
? What type of plugin would you like? datasource # 选择插件类型 app or panel or datasource
? Do you want a backend part of your plugin? Yes # datasource 类型插件是否包含后端
? Do you want to add Github CI and Release workflows? Yes # 是否添加 github ci 和 release 工作流
? Do you want to add a Github workflow for automatically checking "Grafana API compatibility" on PRs? Yes # 是否添加 pr 工作流
后端代码
后端代码需要实现 QueryDataHandler 接口和 CheckHealthHandler 接口,分别用于查询数据和 checkHealth。
type QueryDataHandler interface {
QueryData(ctx context.Context, req *QueryDataRequest) (*QueryDataResponse, error)
}
Grafana 会定时调用 CheckHealth 方法,以检测插件的健康状态。数据源配置页面的 Save & Test 按钮也会调用 CheckHealth 方法来检测配置是否正确。
type CheckHealthHandler interface {
CheckHealth(ctx context.Context, req *CheckHealthRequest) (*CheckHealthResult, error)
}
前端代码
datasource-with-backend 插件,datasource 的前端代码需要实现(extends)DataSourceWithBackend 接口。由于通过后端接口进行数据查询,所以前端页面代码比较简单。
datasource-backend 插件,datasource 的前端代码需要实现(extends)DataSourceApi 接口,并至少实现 query、testDatasource 等方法。其中 query 方法用于数据查询,testDatasource 方法用于测试数据源配置。
async query(options: DataQueryRequest<MyQuery>): Promise<DataQueryResponse>
async testDatasource()
plugin.json 和 module.ts
如果是通过 grafna-create-plugin 创建的插件项目,grafna-create-plugin 会在 src 目录下生成 plugin.json 和 module.ts 文件。其中 plugin.json 包含了插件的信息,包括插件类型、插件名字、ID 等。而 module.ts 是 grafana 插件的入口。
Grafana 和 backend plugin 通讯协议
Grafana 和 backend-plugin 是两个进程,plugin 是 Grafana 的子进程,二者通过 gRpc 通信,plugin 作为 server 端,Grafana 作为 client 端。
其 gRpc 通信协议可参考 https://github.com/Grafana/Grafana-plugin-sdk-go/blob/master/proto/backend.proto,从协议上看,backend-plugin 提供了如下 service:
//---------------------------------------------------------
// Resource service enables HTTP-style requests over gRPC.
//---------------------------------------------------------
service Resource {
rpc CallResource(CallResourceRequest) returns (stream CallResourceResponse);
}
//-----------------------------------------------
// Data
//-----------------------------------------------
service Data {
rpc QueryData(QueryDataRequest) returns (QueryDataResponse);
}
//-----------------------------------------------
// Diagnostics
//-----------------------------------------------
service Diagnostics {
rpc CheckHealth(CheckHealthRequest) returns (CheckHealthResponse);
rpc CollectMetrics(CollectMetricsRequest) returns (CollectMetricsResponse);
}
//-----------------------------------------------------------------
// Stream -- EXPERIMENTAL and is subject to change until 8.0
//-----------------------------------------------------------------
service Stream {
// SubscribeStream called when a user tries to subscribe to a plugin/datasource
// managed channel path – thus plugin can check subscribe permissions and communicate
// options with Grafana Core. When the first subscriber joins a channel, RunStream
// will be called.
rpc SubscribeStream(SubscribeStreamRequest) returns (SubscribeStreamResponse);
// RunStream will be initiated by Grafana to consume a stream. RunStream will be
// called once for the first client successfully subscribed to a channel path.
// When Grafana detects that there are no longer any subscribers inside a channel,
// the call will be terminated until next active subscriber appears. Call termination
// can happen with a delay.
rpc RunStream(RunStreamRequest) returns (stream StreamPacket);
// PublishStream called when a user tries to publish to a plugin/datasource
// managed channel path. Here plugin can check publish permissions and
// modify publication data if required.
rpc PublishStream(PublishStreamRequest) returns (PublishStreamResponse);
}
tdengine-datasource
ConfigEditor
在数据源配置页面可以配置数据源的信息。添加数据源时,需要配置数据源的名字(默认为 TDengine Datasource)、TDengine 的地址、认证信息,通过 Save&test 按钮,可以校验 TDengine 的认证信息。
QueryEditor
结语
tdengine-datasource 代码:
https://github.com/taosdata/Grafanaplugin/
更多 Grafana-plugin 示例:
https://github.com/Grafana/Grafana-plugin-examples
如果在使用 TDengine Grafana 插件的过程中遇到任何问题,或者有新的功能建议,也欢迎在 GitHub(https://github.com/taosdata/grafanaplugin) 上和我们交流。或者添加小T vx:tdengine,和 TDengine 的技术研发人员进行直接沟通。
往
期
推
荐
本文分享自微信公众号 - TDengine(taosdata_news)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。