跳到主要内容

为应用插件添加后端组件

应用插件的后端组件允许您扩展应用插件以实现附加功能,例如自定义认证方法和与其他服务的集成。

以下是应用插件中后端组件的典型用例

  • 使用 Grafana 不支持的自定义认证方法
  • 使用 Grafana 不支持的授权检查
  • 在服务器端运行工作负载
  • 连接到通常无法从浏览器连接的非 HTTP 服务

开始之前

在添加后端组件之前安装以下先决条件

创建一个新的应用插件

Grafana create-plugin 工具是一个 CLI 应用程序,它简化了 Grafana 插件开发,让您可以专注于代码。该工具会为您搭建一个入门插件、所有必需的配置以及一个使用 Docker Compose 的开发环境。

  1. 在一个新目录中,使用 create-plugin 工具从模板创建一个插件。当提示您选择插件类型时,请选择app并回答 yes(是)以确认“Do you want a backend part of your plugin?”(您想要为您的插件添加后端部分吗?)

    npx @grafana/create-plugin@latest
  2. 进入您新创建的插件目录

    cd <your-plugin>
  3. 安装依赖项

    npm install
  4. 构建插件前端

    npm run dev
  5. 在一个新的终端窗口中,构建插件后端

    mage -v build:linux
  6. 启动 Grafana

    docker compose up
  7. 打开 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.modGo 模块依赖项
/src/plugin.json一个描述插件的 JSON 文件。
/pkg/main.go插件二进制文件的起点。

plugin.json 文件

所有插件都需要 plugin.json 文件。构建后端插件时,尤其要注意以下属性

属性描述
backend对于后端插件,设置为 true。这告诉 Grafana 在加载插件时应启动一个二进制文件。
executable这是 Grafana 期望启动的可执行文件的名称。有关详细信息,请参阅 plugin.json 参考
alerting如果您的后端数据源支持告警,请设置为 true。需要将 backend 设置为 true

为您的应用插件添加认证

要详细了解如何为您的应用插件添加认证(例如,调用自定义后端或第三方 API)以及如何处理密钥,请参阅为应用插件添加认证

访问应用设置

设置是 AppInstanceSettings 结构体的一部分。它们作为第二个参数传递给应用插件构造函数。例如

src/app.go
func NewApp(ctx context.Context, settings backend.AppInstanceSettings) (instancemgmt.Instance, error) {
jsonData := settings.JSONData // json.RawMessage
secureJsonData := settings.DecryptedSecureJSONData // map[string]string
}

您还可以从请求 Context 中获取设置

src/resources.go
func (a *App) handleMyRequest(w http.ResponseWriter, req *http.Request) {
pluginConfig := backend.PluginConfigFromContext(req.Context())
jsonData := pluginConfig.AppInstanceSettings.JSONData // json.RawMessage
}

为您的应用插件添加自定义端点

以下是如何为您的应用插件添加 ServeMuxCallResource 端点。

您搭建的应用插件已经有一个使用 ServeMux 的默认 CallResource。它看起来像这样

app.go
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 文件。

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 处理器添加到您的后端组件中来为您的应用插件添加自定义端点。您必须实现处理多个请求的逻辑。

app.go
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 来以开发模式启动它。

注意

默认情况下,Grafana 要求后端插件经过签名。要加载未签名的后端插件,您需要将 Grafana 配置为允许未签名插件。有关详细信息,请参阅插件签名验证

示例

有关完整的示例,请参阅我们的带后端的应用插件示例