为应用插件添加后端组件
应用插件的后端组件允许您扩展应用插件以实现附加功能,例如自定义认证方法和与其他服务的集成。
以下是应用插件中后端组件的典型用例
- 使用 Grafana 不支持的自定义认证方法
- 使用 Grafana 不支持的授权检查
- 在服务器端运行工作负载
- 连接到通常无法从浏览器连接的非 HTTP 服务
开始之前
在添加后端组件之前安装以下先决条件
创建一个新的应用插件
Grafana create-plugin 工具是一个 CLI 应用程序,它简化了 Grafana 插件开发,让您可以专注于代码。该工具会为您搭建一个入门插件、所有必需的配置以及一个使用 Docker Compose 的开发环境。
-
在一个新目录中,使用 create-plugin 工具从模板创建一个插件。当提示您选择插件类型时,请选择app并回答 yes(是)以确认“Do you want a backend part of your plugin?”(您想要为您的插件添加后端部分吗?)
npx @grafana/create-plugin@latest
-
进入您新创建的插件目录
cd <your-plugin>
-
安装依赖项
npm install
-
构建插件前端
npm run dev
-
在一个新的终端窗口中,构建插件后端
mage -v build:linux
-
启动 Grafana
docker compose up
-
打开 Grafana,默认地址为 https://:3000,然后前往 Administration(管理) > Plugins(插件)。确保您的app插件已显示在那里。
您还可以通过检查日志来验证 Grafana 是否已发现该插件
INFO[01-01|12:00:00] Plugin registered logger=plugin.loader pluginID=<your-plugin>
后端插件的剖析
用于构建后端的文件夹和文件app是
文件/文件夹 | 描述 |
---|---|
Magefile.go | 使用 mage 构建文件并非必需,但我们强烈建议您使用它们,以便能够使用插件 SDK 提供的构建目标。 |
/go.mod | Go 模块依赖项。 |
/src/plugin.json | 一个描述插件的 JSON 文件。 |
/pkg/main.go | 插件二进制文件的起点。 |
plugin.json 文件
所有插件都需要 plugin.json
文件。构建后端插件时,尤其要注意以下属性
属性 | 描述 |
---|---|
backend | 对于后端插件,设置为 true 。这告诉 Grafana 在加载插件时应启动一个二进制文件。 |
executable | 这是 Grafana 期望启动的可执行文件的名称。有关详细信息,请参阅 plugin.json 参考。 |
alerting | 如果您的后端数据源支持告警,请设置为 true 。需要将 backend 设置为 true 。 |
为您的应用插件添加认证
要详细了解如何为您的应用插件添加认证(例如,调用自定义后端或第三方 API)以及如何处理密钥,请参阅为应用插件添加认证。
访问应用设置
设置是 AppInstanceSettings
结构体的一部分。它们作为第二个参数传递给应用插件构造函数。例如
func NewApp(ctx context.Context, settings backend.AppInstanceSettings) (instancemgmt.Instance, error) {
jsonData := settings.JSONData // json.RawMessage
secureJsonData := settings.DecryptedSecureJSONData // map[string]string
}
您还可以从请求 Context
中获取设置
func (a *App) handleMyRequest(w http.ResponseWriter, req *http.Request) {
pluginConfig := backend.PluginConfigFromContext(req.Context())
jsonData := pluginConfig.AppInstanceSettings.JSONData // json.RawMessage
}
为您的应用插件添加自定义端点
以下是如何为您的应用插件添加 ServeMux
或 CallResource
端点。
ServeMux(推荐)
您搭建的应用插件已经有一个使用 ServeMux
的默认 CallResource
。它看起来像这样
type App struct {
backend.CallResourceHandler
}
// NewApp creates a new example *App instance.
func NewApp(_ context.Context, _ backend.AppInstanceSettings) (instancemgmt.Instance, error) {
var app App
// Use an httpadapter (provided by the SDK) for resource calls. This allows us
// to use a *http.ServeMux for resource calls, so we can map multiple routes
// to CallResource without having to implement extra logic.
mux := http.NewServeMux()
app.registerRoutes(mux)
// implement the CallResourceHandler interface
app.CallResourceHandler = httpadapter.New(mux)
return &app, nil
}
现在您可以为您的应用插件添加自定义端点。
搭建的代码已经包含一个带有 registerRoutes
函数的 resources.go
文件。
// this function already exists in the scaffolded app plugin
func (a *App) registerRoutes(mux *http.ServeMux) {
mux.HandleFunc("/myCustomEndpoint", a.handleMyCustomEndpoint)
}
func (a *App) handleMyCustomEndpoint(w http.ResponseWriter, r *http.Request) {
// handle the request
// e.g. call a third-party API
w.Write([]byte("my custom response"))
w.WriteHeader(http.StatusOK)
}
CallResource
您还可以通过直接将 CallResource
处理器添加到您的后端组件中来为您的应用插件添加自定义端点。您必须实现处理多个请求的逻辑。
func (a *App) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
switch req.Path {
case "myCustomEndpoint":
sender.Send(&backend.CallResourceResponse{
Status: http.StatusOK,
Body: []byte("my custom response"),
})
default:
return sender.Send(&backend.CallResourceResponse{
Status: http.StatusNotFound,
})
}
return nil
}
您还可以查看数据源的资源处理器文档,这些文档也可以应用于您的应用插件。
从前端代码调用您的自定义端点
要从前端代码调用您的自定义端点,您可以使用 getBackendSrv
中的 fetch
函数。例如
import { getBackendSrv } from '@grafana/runtime';
import { lastValueFrom } from 'rxjs';
function getMyCustomEndpoint() {
const response = await getBackendSrv().fetch({
// replace ${PLUGIN_ID} with your plugin id
url: '/api/plugins/${PLUGIN_ID}/myCustomEndpoint',
});
return await lastValueFrom(response);
}
故障排除
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
来以开发模式启动它。
示例
有关完整的示例,请参阅我们的带后端的应用插件示例。