插件 〉Wild GraphQL 数据源


开发者

Lavender Shannon

注册接收不定期的产品新闻和更新



数据源
社区

Wild GraphQL 数据源

  • 概览
  • 安装
  • 更新日志
  • 相关内容

Wild GraphQL 数据源

这是一个 Grafana 数据源插件,旨在简化通过 GraphQL 端点请求时间序列数据的过程。查询编辑器使用 GraphiQL 提供带有自动补全功能的直观编辑器。请求在后端进行,支持告警。

请在我们的问题页面报告问题:wild-graphql-datasource/issues

功能

  • 复杂的 GraphQL 响应可以转换为时间序列数据或简单表格
  • 包含 GraphiQL 查询编辑器。在 Grafana 内提供 GraphQL Schema 的自动补全和文档!
    • 可以从查询编辑器打开文档浏览器
    • 点击按钮美化查询
  • fromto 变量通过原生 GraphQL 变量传递给查询
  • 查询编辑器的变量部分支持使用Grafana 变量进行字符串值插值。(*告警或其他仅后端查询不支持)
  • 支持多种解析选项,允许单个 GraphQL 查询返回多种不同格式的数据点。
    • 每个解析选项都有自己的标签,这些标签可以由响应中的字段填充。这些标签用于将响应分组到不同的数据帧中。
    • 通过在 标准选项 > 显示名称 下使用 ${__field.labels["displayName"]},标签可以用于更改显示名称。
  • 支持展开数组路径(Exploded array paths),允许嵌套数组生成多行而非多列。
  • 这是一个后端插件,因此支持告警
  • 注释支持

查询编辑器

查询

您的 GraphQL 查询位于 GraphiQL 编辑器面板的上半部分

变量

变量可以在 GraphiQL 编辑器窗口中编辑。这些变量使用 JSON 指定,其工作方式类似于任何常规 GraphQL 查询中的变量。本节是可选的,但如果您希望为查询提供常量变量或简化输入类型的指定,您可以在此处进行。

提供的变量

每个查询都会提供某些变量。这些变量包括

变量类型描述对应的 Grafana 变量执行按钮支持
from数字“起始”时间的 Epoch 毫秒数$__from
to数字“结束”时间的 Epoch 毫秒数$__to
interval_ms数字时间序列查询中时间点之间的建议时长$__interval_ms
maxDataPoints数字时间序列查询应返回的最大数据点数不适用
refId字符串查询的唯一标识符,由前端调用设置不适用

在最基本的查询中展示了一个使用示例

query ($from: Long!, $to: Long!) {
  queryStatus(from: $from, to: $to) {
    # ...
  }
}

在上面的示例中,查询请求两个 Long 类型变量,$from$to。如上表所示,值由提供的变量提供。请注意,尽管提供了 interval_ms,但我们在查询中没有使用或定义它。对于您自己的查询,需要记住的一点是 GraphQL 服务器接受给定变量的类型。对于该特定 Schema,Long 类型可以是数字或字符串。如果您的 Schema 没有 Long 类型,您可能会考虑将查询声明更改为使用 FloatString,这两种类型都内置于 GraphQL 中。

如果您在使用特定 Schema 的 fromto 变量时遇到任何问题,请提交问题。另外,如果您正在前端进行查询(除告警查询外的任何查询),您可以考虑阅读下一节来定义自己的 from 和 to 变量,并将其值分配给全局变量

Grafana 变量插值

变量部分对于变量插值最有用。字符串内的任何值,无论是嵌套在对象中还是变量对象的顶级值,都可以进行插值。请注意,插值不适用于告警查询。您可以使用任何您认为合适的变量配置。示例如下:

query ($sourceId: String!, $from: Long!, $to: Long!) {
  queryStatus(sourceId: $sourceId, from: $from, to: $to) {
    # ...
  }
}
{
  "sourceId": "$sourceId"
}

在这里,变量部分中的 $sourceId 将与 Grafana 仪表盘中定义的值进行插值。GraphQL 查询面板中的 $sourceId 是一个常规的变量,它会传递给查询。

注意:如果您需要将变量作为数字传递,则必须使用下一节所示的“高级变量插值”。

请记住:变量插值不适用于告警查询,或任何没有前端组件执行的查询。

高级变量插值

如果您需要在传递给查询的变量中包含数字变量,则无法使用默认变量编辑器,而必须改用高级变量 JSON。勾选该复选框进行定义。之后,您可以编写 JSON,它只有在插值后才有效。例如:

{
  "age": $age
}

上面的示例假设 $age 的计算结果是一个数字,使得最终的 JSON 有效。您可以同时使用高级变量 JSON 和上面描述的常规变量。只需注意,对于重复定义的变量,高级变量 JSON 会优先。

警告:仅在必要时使用高级变量 JSON。如果生成的 JSON 的任何部分无效,则高级变量插值的任何部分都不会传递给查询。

文档浏览器

GraphiQL 提供了一个文档浏览器,可以通过点击 GraphiQL 编辑器左上角的按钮在编辑器左侧打开。

GraphiQL 查询执行

GraphiQL 编辑器的右侧用于显示查询结果。这仅对调试有用,可以查看查询产生的 JSON 结果。

要运行查询并查看其原始 JSON,请按下 GraphiQL 编辑器顶部中央的“执行查询”按钮。您在此处看到的结果与允许 Grafana 查询数据源的结果是分开的。

操作名称

操作名称显示在 GraphiQL 编辑器正下方。操作名称应由 Wild GraphQL 数据源自动确定。如果在查询面板中定义了多个查询,您可能需要手动指定。在使用“执行查询”按钮运行查询后,此项也会自动更新。

解析选项

查询编辑器允许您配置一个或多个解析选项。每个额外的解析选项都会产生至少一个额外的数据帧,这可以在编辑面板页面的“表格视图”中或在查询检查器中看到。

数据路径和时间路径

数据路径是响应 JSON 中指向数据数组或数据对象的点分隔路径。

时间路径是指向时间字段的点分隔路径,如果不存在时间字段则为空。

以这个查询为例

query ($from: Long!, $to: Long!) {
  temperatures(from: $from, to: $to) {
    epochTimeMillis
    temperatureCelsius
  }
}
  • 数据路径:temperatures
  • 时间路径:epochTimeMillis

请注意,时间路径是相对于数据路径的。

展开数组路径(高级)

这是插件的一个更高级的功能。如果您有这样的响应:

{
  "myData": {
    "serverName": "Central Server 1",
    "datapoints": [
      {
        "dateMillis": 1234,
        "value": 23.2
      },
      {
        "dateMillis": 1235,
        "value": 23.3
      }
    ]
  }
}

您不会希望将 myData.datapoints 设置为数据路径,因为那样您将无法访问 serverName 字段。相反,您可以将数据路径设置为 myData,并将 datapoints 添加为展开数组路径。

此响应中显示了一个更高级的示例

{
  "myData": {
    "serverName": "Central Server 1",
    "datapoints": [
      {
        "dateMillis": 1234,
        "processorTemperatures": [
          {
            "id": "0",
            "temperatureCelsius": 44.3
          },
          {
            "id": "1",
            "temperatureCelsius": 44.0
          }
        ]
      },
      // ...
    ]
  }
}

在上述情况下,您可以配置

  • 数据路径:myData
  • 展开数组路径
    • datapoints.processorTemperatures

请注意,datapoints.processorTemperatures 展开数组路径也会展开 datapoints 数组,因此您无需同时将 datapoints 定义为展开数组路径。

标签

每个查询选项都可以指定将在结果数据帧中出现的标签。您可以在“要添加的标签”文本框中输入并按回车键来创建一个新标签。这会将具有给定名称的标签添加到每个解析选项中。

字段标签

字段标签的值是指向响应 JSON 中所需字段的点分隔路径,类似于“时间路径”的工作方式。

使用字段标签将根据该字段的值划分数据,从而产生多个数据帧,进而导致图表图例上有多个键。

常量标签

常量标签为给定的解析选项定义一个标签。常量标签可用于识别不同的解析选项,或为单个解析选项提供特定的显示名称。

使用标签作为显示名称

如果您希望根据某个字段划分数据,应使用上述的字段标签。创建该字段标签后,很有可能您希望使用同一字段作为显示名称,以便图表图例显示易读的显示名称。在面板编辑器的右侧,导航至标准选项 > 显示名称。现在,将显示名称更改为 ${__field.labels["displayName"]},其中 displayName 是您标签的名称。

或者,假设您的标签名称是有效标识符,您可以将显示名称设置为 ${__field.labels.displayName}

使用多个解析选项

多个解析选项是单个面板中多次查询的良好替代方案。由于单个 GraphQL 查询可以返回大量数据,有时您可能需要解析其中的个别部分。例如,这里有一个包含 2 个解析选项的简单示例:

query ($from: Long!, $to: Long!) {
  temperature(from: $from, to: $to) {
    epochTimeMillis
    sensorName
    temperatureCelsius
  }
  deviceCpuTemperature(from: $from, to: $to) {
    dateMillis
    temperature
  }
}
  • 解析选项 1
    • 数据路径:temperatures
    • 时间路径:epochTimeMillis
    • 标签
      • “displayName”:(字段)sensorName
  • 解析选项 2
    • 数据路径:deviceCpuTemperatures
    • 时间路径:dateMillis
    • 标签
      • “displayName”:(常量)CPU

原本需要两个查询才能完成的事情,现在通过一个查询就完成了!

使用 Grafana 转换

值得一提的是,完全有可能不使用 Wild GraphQL 数据源的标签功能,而是使用 Grafana 转换来实现部分相同的功能。

如果您有需要按值“分组”或“划分”的数据,您首先需要添加“按值划分”转换,并选择 your.field.for.displayName。完成此操作后,您可以进入“标准选项”找到“显示名称”,并将其设置为 ${__field.labels["your.field.for.displayName"]}

参考

请记住,Grafana 转换不是执行此操作的首选方法,您应该优先使用提供的标签功能。


其他信息

扁平化数据

除非配置了展开数组路径,否则数据路径中嵌套的数组会被扁平化。

以这个 GraphQL 响应为例

{
  "myData": [
    {
      "dateMillis": 1234,
      "values": [
        {
          "name": "temperature",
          "value": 23.0
        },
        {
          "name": "humidity",
          "value": 0.55
        }
      ]
    }
  ]
}

在这种情况下,我们将 myData 设置为数据路径,返回的结果将包含这些字段名称:

  • dateMillis
  • values.0.name
  • values.0.value
  • values.1.name
  • values.1.value

有了这些扁平化数据,您可以使用 values.0.value 路径引用温度。扁平化数据并不总是易于处理。根据数据代表的含义,您还可以考虑上面描述的“展开数组路径”。

您可以在数据路径和标签字段值中使用 array.<index> 语法。

数据源预置 (Provisioning)

本节介绍预置 (provisioning),这是 Grafana 的一项高级功能。

预置自定义请求头

自定义请求头必须按数据源配置,而不是按查询配置。

此配置与数据源的自定义 HTTP 请求头一致。这意味着预置请求头的方式与其他基于 HTTP 的 Grafana 数据源相同。

apiVersion: 1

datasources:

  • name: ‘My Cool GraphQL Datasource Name’ type: ‘retrodaredevil-wildgraphql-datasource’ url: ‘ https://swapi-graphql.netlify.app/graphql' access: proxy isDefault: false orgId: 1 version: 1 editable: true jsonData: httpHeaderName1: ‘HeaderName’ httpHeaderName2: ‘Authorization’ secureJsonData: httpHeaderValue1: ‘HeaderValue’ httpHeaderValue2: ‘Bearer XXXXXXXXX’

常见问题解答

  • 我可以在 GraphQL 查询本身中使用变量插值吗?
    • 不能,但您可以在传递给查询的变量的字符串值中使用变量插值
  • 这可以完全替代 fifemon-graphql-datasource 吗?
    • 不能,但这两种数据源有相似的目标,只需少量工作即可互相移植。

告警特定错误

  • 评估查询和表达式失败:输入数据必须是 Wide Series,但获取的类型是 long (输入 refid)
    • 此错误表明查询返回的字段除了时间戳和数据点之外还有更多字段。
    • 对于告警,GraphQL 查询的响应不能包含时间戳和数据点之外的字段。目前,您不能使用结果中的其他属性来过滤数据。
  • 评估查询和表达式失败:执行条件失败:输入数据必须是 Wide Series,但获取的类型是 not (输入 refid)
    • 如果您的响应中没有任何数字数据,可能会发生此错误 (https://github.com/grafana/grafana/issues/46429)
    • 当您包含标签且响应包含多个数据帧时,也会发生此错误。
      • 要解决此问题,请不要在告警查询中使用标签。告警查询支持 long 数据帧格式,因此它会自动将非数字字段视为标签。
      • 这样做的缺点是,如果您的查询返回跨越一段时间的数据,您无法轻松地按字段划分数据,并且选择只使用最新数据。

已知问题

  • 告警查询和注释查询只能使用响应数据中提供的字段。
    • 我们计划将来通过允许向响应添加自定义字段来缓解此问题

在 Grafana Cloud 上安装 Wild GraphQL 数据源

欲了解更多信息,请访问关于插件安装的文档。

更新日志

1.4.1

一些小修复。

  • 处理空查询对象。这可以防止在创建新面板时,查询有时会是空的(而不是默认查询)的 bug。
  • 正确处理 GraphQL 响应中 data 字段为 null 的情况
  • 后端更好的错误处理。

1.4.0

此版本的主要功能是展开数组路径(Exploded array paths),它允许响应中的嵌套数组“展开”成多行。

  • 功能:#6 支持展开数组路径,允许将嵌套数组转换为多行而非多列
  • 修复:#15 数据路径现在可以索引到数组中。

1.3.1

修复了 #9,这是一个 bug,该 bug 导致变量部分内部使用的数组在传递给后端之前会错误地转换为对象。此外,还进行了许多内部依赖升级,以修复阻止 1.3.0 版本正式发布的安全性漏洞。

1.3.0

合并了 #8,该 PR 将请求的 HTTP 请求头传递给 GraphQL 服务器。此更改应遵守数据源配置“身份验证”部分下的复选框,以便仅在您启用其设置时才发送 OAuth 和 Cookie 请求头。

此外,对于大多数查询,这些请求头现在总是会传递给 GraphQL 服务器:

  • X-Datasource-Uid
  • X-Grafana-Org-Id
  • X-Panel-Id
  • X-Dashboard-Uid

1.2.1

更新了 README 中的 LICENSE 链接。

1.2.0

合并了 #5,该 PR 更新了内部库以更好地支持可在数据源本身中配置的 HTTP 请求头。此外,所有 GraphQL 请求都会在每次请求中包含一个 Accept: application/json 请求头。此附加请求头符合GraphQL over HTTP 规范,以更好地与 GraphQL 服务器兼容。

1.1.1

没有新增功能或修复。

稳定性

  • 首个官方签名版本

1.1.0

新功能

  • 添加了“高级变量 JSON”,用于定义一个变量 JSON 对象,该对象对 JSON 字符串本身进行插值,而不是对 JSON 中的字符串进行插值
    • 这是新增功能,并非用于替换或改变现有功能。支持同时使用 GraphiQL 编辑器中的变量配置和高级变量 JSON。

稳定性

  • 资源正确关闭
  • 不再使用 Panics,后端日志记录得到改进
  • 不必要的 console.log() 调用已移至现有的 console.error() 调用

1.0.1

修复

  • 数值现在以 float64 值导出,这使得告警查询能够正常工作
  • 未定义的变量对象以前会导致记录错误。现在通过预置查询定义的 null/undefined variables 字段不再记录错误消息。

1.0.0

初始版本。