向应用插件添加后端组件
应用插件的后端组件允许您扩展应用插件以获得其他功能,例如自定义身份验证方法和与其他服务的集成。
以下是应用插件中后端组件的典型用例
- 使用 Grafana 不支持的自定义身份验证方法
- 使用 Grafana 不支持的授权检查
- 在服务器端运行工作负载
- 连接到通常无法从浏览器连接到的非 HTTP 服务
开始之前
在添加后端组件之前,请安装以下先决条件
创建新的应用插件
Grafana create-plugin 工具是一个 CLI 应用程序,它简化了 Grafana 插件的开发,使您能够专注于代码。该工具为您构建了启动插件、所有必需的配置以及使用 Docker Compose 的开发环境。
-
在新的目录中,使用 create-plugin 工具从模板创建插件。当提示您选择插件类型时,选择应用,并对“您是否希望插件具有后端部分?”回答“是”。
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>
后端插件的结构
用于构建应用的后端文件夹和文件为
文件/文件夹 | 描述 |
---|---|
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
来在开发模式下启动它。
示例
有关完整示例,请参阅我们的 带有后端的示例应用插件。