构建数据源后端插件
简介
Grafana 支持广泛的 数据源,包括 Prometheus、MySQL 和 Datadog。但在某些情况下,您可能已经有了希望添加到 Grafana 仪表板的自定义指标解决方案。本教程将指导您构建新的数据源插件以查询数据。
后端组件为您的插件提供了一些额外的功能,例如自定义身份验证方法。要了解更多信息,请参阅有关 后端插件 的文档。
在本教程中,您将
- 为您的数据源构建 后端
- 实现数据源的健康检查
- 为您的数据源启用 Grafana 警报
先决条件
创建一个新插件
Grafana create-plugin 工具 是一个 CLI 应用程序,可简化 Grafana 插件开发,让您专注于代码。该工具使用 Docker Compose 为您搭建了起始插件、所有必需的配置和开发环境。
-
在新的目录中,使用创建插件工具从模板创建一个插件。当提示插件类型时,选择 并回答“是否要插件的后端部分?”的问题时选择“是”
npx @grafana/create-plugin@latest
-
进入新创建的插件的目录
cd <your-plugin>
-
安装依赖
npm install
-
构建插件前端
npm run dev
-
在新的终端窗口中,构建插件后端
mage -v build:linux
-
启动Grafana
docker compose up
- 打开Grafana,默认情况下https://127.0.0.1:3000/,然后转到 管理 > 插件。确保您的插件已在那里。插件已在那里。
您也可以通过检查日志来验证Grafana是否已发现该插件。
INFO[01-01|12:00:00] Plugin registered logger=plugin.loader pluginID=<your-plugin>
现在,让我们验证您迄今为止构建的插件是否可以在创建新的数据源时在Grafana中使用。
- 在侧边菜单中,转到 连接 > 数据源。
- 点击 添加数据源。
- 搜索您新创建的插件名称并选择它。
- 输入一个名称,然后点击 保存 & 测试。如果发生“随机错误”,您可以忽略它 - 这是在下面进一步解释的健康检查的结果。
您现在有一个插件的新数据源实例,它已准备好在仪表板中使用。
要将数据源添加到仪表板
- 创建一个新的仪表板并添加一个新的面板。
- 在查询选项卡上,选择您刚刚创建的数据源。一个包含两个数据点的系列的单线图被渲染。
- 保存仪表板。
故障排除
Grafana无法加载我的插件
确保Grafana已以开发模式启动。如果您是从源运行Grafana,请在您的 conf/custom.ini
文件中添加以下行
app_mode = development
如果您还没有 conf/custom.ini
文件,请在继续之前创建它。
然后您可以通过在Grafana存储库根目录中运行 make run & make run-frontend
来以开发模式启动Grafana。
如果您从二进制文件或Docker容器中运行Grafana,您可以通过设置环境变量 GF_DEFAULT_APP_MODE
为 development
来以开发模式启动它。
后端插件的结构
用于构建数据源后端的文件夹和文件如下所示文件/文件夹
描述 | 文件/文件夹 |
---|---|
Magefile.go | 使用mage构建文件不是必需的,但我们强烈建议使用它们,这样您就可以使用插件SDK提供的构建目标。 |
/go.mod | Go 模块依赖项。 |
/src/plugin.json | 描述插件的JSON文件。 |
/pkg/main.go | 插件二进制的起始点。 |
插件.json文件
所有插件都需要plugin.json
文件。当构建后端插件时,特别关注以下属性
属性 | 文件/文件夹 |
---|---|
后端 | 对于后端插件,设置为true 。这告诉Grafana在加载插件时应该启动一个二进制文件。 |
可执行文件 | 这是Grafana期望启动的可执行文件名称。有关详细信息,请参阅plugin.json参考。 |
警报 | 如果您的后端数据源支持警报,设置为true 。需要将后端 设置为true 。 |
在下一步中,我们将查看查询端点!
实现数据查询
我们首先打开文件/pkg/plugin/datasource.go
。在这个文件中,您将看到实现backend.QueryDataHandler接口的Datasource
结构体。这个结构体上的QueryData
方法是在数据源插件中进行数据获取的地方。
每个请求包含多个查询,以减少Grafana和插件之间的流量。因此,您需要遍历查询切片,处理每个查询,然后返回所有查询的结果。
在教程中,我们提取了一个名为query
的方法来处理每个查询模型。由于每个插件都有自己的独特查询模型,Grafana将其作为JSON发送到后端插件。因此,插件需要将查询模型Unmarshal
为更容易处理的东西。
如您所见,示例仅返回静态数字。尝试扩展插件以返回其他类型的数据。
例如,为了生成时间上等距的三浮点数,您可以替换生成的两个静态数字,使用以下代码
duration := query.TimeRange.To.Sub(query.TimeRange.From)
mid := query.TimeRange.From.Add(duration / 2)
s := rand.NewSource(time.Now().UnixNano())
r := rand.New(s)
lowVal := 10.0
highVal := 20.0
midVal := lowVal + (r.Float64() * (highVal - lowVal))
// add fields.
frame.Fields = append(frame.Fields,
data.NewField("time", nil, []time.Time{query.TimeRange.From, mid, query.TimeRange.To}),
data.NewField("values", nil, []float64{lowVal, midVal, highVal}),
)
您可以在我们的文档中了解更多关于如何在构建数据帧的信息。
添加对健康检查的支持
实现健康检查处理程序允许Grafana验证数据源是否已正确配置。
在Grafana UI中编辑数据源时,您可以保存并测试以验证它是否按预期工作。
在这个示例数据源中,有50%的可能性健康检查将成功。确保返回适当的错误消息给用户,通知他们数据源中配置了什么问题。
打开/pkg/plugin/datasource.go
。在这个文件中,您会看到Datasource
结构体还实现了backend.CheckHealthHandler接口。转到CheckHealth
方法以查看此示例插件的健康检查是如何实现的。
要了解更多信息,请参阅我们示例存储库中的其他健康检查实现。
添加身份验证
实现身份验证可以让您的插件访问受保护的资源,如数据库或API。有关如何使用后端插件进行身份验证的更多信息,请参阅我们的文档。
启用Grafana警报
-
将顶级
alerting
属性设置为true
,以指定您的插件支持Grafana警报,例如:src/plugin.json{
...
"backend": true,
"executable": "gpx_simple_datasource_backend",
"alerting": true,
"info": {
...
} -
重新启动您的Grafana实例。
-
在您的网络浏览器中打开Grafana。
-
通过转到您创建的数据源来验证警报是否受支持。您应该在设置视图中看到“警报受支持”消息。
创建警报
以下说明基于Grafana v10.1.1,有关适用于相应版本的指南,请参阅文档。
- 打开您在“创建新插件”步骤中创建的仪表板。
- 编辑现有面板。
- 点击面板下方的“警报”标签。
- 点击“从该面板创建警报规则”按钮。
- 在“表达式”部分,在“阈值”表达式
C
中,将“IS ABOVE”设置为15
。 - 点击“将阈值表达式
C
设置为警报条件”上的按钮。您的警报现在应该如下所示。 - 在“设置警报评估行为”部分,点击“新建文件夹”按钮并创建一个新的文件夹以存储评估规则。
- 然后,点击“新建评估组”按钮并创建一个新的评估组;选择一个名称并将“评估间隔”设置为
10s
。 - 点击“保存规则并退出”按钮。
- 保存仪表板。经过一段时间后,警报规则评估并过渡到“警报”状态。
并发运行多个查询
此功能仅适用于Grafana后端插件SDK版本0.232.0及更高版本。
默认情况下,单个请求(即在单个面板中)内的多个查询是顺序执行的。要并发运行多个查询,您可以使用SDK公开的concurrent.QueryData
函数。
要使用concurrent.QueryData
,指定如何执行单个查询以及要运行的并发查询数量限制。请注意,最大为10个并发查询。
import (
...
"github.com/grafana/grafana-plugin-sdk-go/experimental/concurrent"
...
)
func (d *Datasource) handleSingleQueryData(ctx context.Context, q concurrent.Query) (res backend.DataResponse) {
// Implement the query logic here
}
func (d *Datasource) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
return concurrent.QueryData(ctx, req, d.handleSingleQueryData, 10)
}
摘要
在本教程中,您为数据源插件创建了后端。