跳至主要内容

将插件从 Grafana 9.3.x 迁移到 9.4.x

请按照以下说明将插件从 Grafana 9.3.x 迁移到 9.4.x。

支持新的导航布局

首先,在 custom.ini 中启用 topnav 功能标志,以检查您的插件在新导航布局中的渲染方式

[feature_toggles]
enable = topnav

onNavChanged 迁移

如果您的插件使用 onNavChanged 回调来通知 Grafana 其导航模型和子页面,您应该会看到这会导致重复的导航元素。如果您禁用 topnav,那么它应该看起来与以前一样。

如果启用了 topnav,那么我们需要更新插件以利用新的 PluginPage 组件。在这种情况下,我们不会调用 onNavChanged,它现在已弃用。

切换到 PluginPage 组件

Grafana 现在从 @grafana/runtime 公开了一个新的 PluginPage 组件,该组件连接到新的导航和页面布局。这个新组件在禁用 topnav 功能时也支持旧的页面布局。

新的 PluginPage 组件还将处理渲染部分导航。部分导航可以包含其他核心部分和其他插件。为了控制在特定插件的部分导航中显示哪些页面,Grafana 使用在 plugin.json 中添加的页面,其中 addToNav 设置为 true

要使用此组件,只需将其包装在您的页面内容周围即可

import { PluginPage } from '@grafana/runtime';

...

return (
<PluginPage>
{your page content here}
</PluginPage>
);

Grafana 查看 URL 以了解在部分导航中应激活哪些插件和页面。因此,此组件仅适用于您在 plugin.json 中指定的页面。PluginPage 然后将根据在 plugin.json 中指定的页面名称渲染页面标题。

plugin.json 中未定义的页面使用 PluginPage

PluginPage 组件还公开了一个 pageNav 属性,它是一个 NavModelItem。这个 pageNav 属性对 plugin.json 中未定义的页面(例如单个项目页面)很有用。您在 pageNav 模型中指定的 textdescription 用于填充面包屑和页面标题。

示例

const pageNav = {
text: 'Write errors cortex-prod-04',
description: 'Incident timeline and details'
};

return (
<PluginPage pageNav={pageNav}>
{your page content here}
</PluginPage>
);

面包屑和部分导航中匹配活动页面的方式依赖于页面路由是分层的。如果您有一个列表页面和一个项目页面,那么您需要将项目页面设为列表页面的子路由。此外,您还需要在 plugin.json 中指定列表页面的 URL。

例如,您可能在 /users 处有一个用户列表。这意味着特定用户的项目页面需要位于 /users/:id。这可能需要对您的路由进行一些重构。

PluginPage 与选项卡一起使用

您还可以通过在 pageNav 模型中指定 children 来创建更深一层的层次结构,从而创建一个带有选项卡导航的页面。

示例

const pageNav = {
text: 'My page',
description: 'Incident timeline and details',
url: '/a/myorgid-pluginname-app',
children: [
{
url: '/a/myorgid-pluginname-app/tab1',
text: 'Tab1',
active: true,
},
{
url: '/a/myorgid-pluginname-app/tab2',
text: 'Tab1',
},
],
};

return (
<PluginPage pageNav={pageNav}>
{your page content here}
</PluginPage>
);

以向后兼容的方式使用 PluginPage

如果您想与旧版 Grafana 保持向后兼容性,一种方法是实现 PluginPage 包装器。如果 PluginPage 可用并且启用了 topnav 功能,则使用真正的 PluginPage。在其他情况下,回退到每个插件今天正在执行的操作(例如,调用 onNavChanged)。

示例

import { PluginPageProps, PluginPage as RealPluginPage, config } from '@grafana/runtime';

export const PluginPage = RealPluginPage && config.featureToggles.topnav ? RealPluginPage : PluginPageFallback;

function PluginPageFallback(props: PluginPageProps) {
return props.children;
}

还需要一个额外的步骤(和 if 块)来根据 config.features.topnav 是否为 true 来隐藏或显示选项卡。您的插件需要在 useNavModel.ts 文件中包含这些更改

// useNavModel.ts

import { config } from '@grafana/runtime';

...

export function useNavModel({ meta, rootPath, onNavChanged }: Args) {
const { pathname, search } = useLocation();
useEffect(() => {
if (config.featureToggles.topnav) {
return;
}
}, [config]);

...

Go 插件 SDK 中转发的 HTTP 标头

我们建议使用 <request>.GetHTTPHeader<request>.GetHTTPHeaders 方法检索转发的 HTTP 标头。请参阅 转发已登录用户的 OAuth 身份转发已登录用户的 Cookie转发已登录用户的用户标头,以了解示例用法。

技术细节

Go 的 Grafana SDK v0.147.0 引入了一个新的接口 ForwardHTTPHeadersQueryDataRequestCheckHealthRequestCallResourceRequest 实现该接口。

在 Grafana v9.4.0 中新引入的转发的 HTTP 标头是 X-Grafana-UserX-Panel-IdX-Dashboard-UidX-Datasource-UidX-Grafana-Org-Id。在内部,我们为它们添加前缀 http_,并在 CheckHealthRequest.HeadersQueryDataRequest.Headers 中以 http_<HTTP header name> 的形式发送。

我们建议使用 ForwardHTTPHeaders 方法,这样您就能保证能够在不使用前缀的情况下对 HTTP 标头进行操作。也就是说,您可以对 X-Grafana-UserX-Panel-IdX-Dashboard-UidX-Datasource-UidX-Grafana-Org-Id 进行操作。