菜单
Grafana Cloud Enterprise 开源

编写表达式查询

服务端表达式使您可以使用数学和其他操作处理查询返回的数据。表达式会创建新数据,而不是直接操作数据源返回的数据。

关于表达式

服务端表达式使您可以使用数学和其他操作处理查询返回的数据。表达式会创建新数据,而不是直接操作数据源返回的数据,只会进行一些轻微的数据结构调整,使其成为表达式可接受的输入。

使用表达式

表达式最常用于 Grafana 告警。处理是在服务端完成的,因此表达式可以在没有浏览器会话的情况下运行。不过,表达式也可以用于后端数据源和可视化。

注意

表达式不适用于旧版仪表盘告警。

表达式旨在通过组合不同数据源的查询或提供数据源中不可用的操作来增强数据源。

注意

如果可能,您应该在数据源内部进行数据处理。将数据从存储复制到 Grafana 服务器进行处理效率低下,因此表达式主要针对轻量级数据处理。

表达式适用于返回时间序列或数值数据的数据源查询。它们也适用于多维数据。例如,返回多个系列(每个系列由标签标识)的查询。

单个表达式将一个或多个查询或其他表达式作为输入,并将数据添加到结果中。每个独立的表达式或查询都由一个变量表示,该变量是一个命名标识符,称为其 RefID(例如,默认字母 AB)。

要在另一个表达式中引用单个表达式或数据源查询的输出,可以使用此标识符作为变量。

表达式类型

表达式处理两种类型的数据。

  • 时间序列集合。
  • 数值集合,其中每个数值都是一个项目。

每个集合都由单个数据源查询或表达式返回,并由 RefID 表示。每个集合是一个集,其中集中的每个项目都通过其维度(存储为标签或键值对)唯一标识。

数据源查询

服务端表达式仅支持后端数据源的数据源查询。数据通常被假定为带标签的时间序列数据。将来,我们打算添加查询返回类型(数值或时间序列)数据的断言,以便表达式能够更好地处理错误。

数据源查询与表达式一起使用时,由表达式引擎执行。执行时,它会重构数据,使每个数据帧包含一个时间序列或一个数值。因此,例如,如果使用在表格视图的单个帧上返回多个系列的数据源,您可能会注意到在使用表达式执行时其外观有所不同。

目前,只有在使用数据帧且表格响应返回一个不含时间、包含字符串列和一个数值列的数据帧时,才支持非时间序列格式(数值)。

位置主机平均 CPU
MIAA1
NYCB2

上面的示例将生成一个可与表达式一起使用的数值。字符串列成为标签,数值列成为相应的值。例如 {"Loc": "MIA", "Host": "A"} 值为 1。

操作

您可以在表达式中使用以下操作:数学运算、归约和重采样。

数学运算

数学运算用于对时间序列或数值数据执行自由格式的数学公式。数学操作将数值和时间序列作为输入,并将其转换为不同的数值和时间序列。

来自其他查询或表达式的数据通过 RefID 引用,前缀为美元符号,例如 $A。如果变量名包含空格,则可以使用大括号语法,例如 ${我的变量}

数值常量可以是十进制 (2.24)、八进制(前缀为零,例如 072)或十六进制(前缀为 0x,例如 0x2A)。也支持指数和符号(例如 -0.8e-2)。

运算符

支持算术运算符 (+, 二元和一元 -, *, /, %, 幂 **)、关系运算符 (<, >, ==, !=, >=, <=) 和逻辑运算符 (&&, ||, 以及一元 !)。

操作如何处理数据取决于它是数值还是时间序列数据。

对于二元操作,例如 $A + $B$A || $B,运算符根据数据类型按以下方式应用:

  • 如果 $A$B 都是数值,则在两个数值之间执行操作。
  • 如果一个变量是数值,另一个变量是时间序列,则对时间序列中每个点的值与该数值执行操作。
  • 如果 $A$B 都是时间序列数据,则对两个系列中在 $A$B 中都存在的每个时间戳的每个值执行操作。可以使用 Resample 操作对齐时间戳。(注意:未来,我们计划为数学操作添加不同行为的选项)。

总结

  • 数值 运算符 数值 = 数值
  • 数值 运算符 系列 = 系列
  • 系列 运算符 系列 = 系列

由于表达式处理由单个变量表示的多个系列或数值,二元操作也会在两个变量之间执行联合(连接)。这是基于与每个独立系列或数值关联的标识标签完成的。

因此,如果您在 $A 中有带标签(例如 {host=web01})的数值,并在 $B 中有带相同标签的另一个数值,则将在每个变量中的这两个项目之间执行操作,结果将共享相同的标签。此联合行为的规则如下:

  • 没有标签的项目将与任何其他项目连接。
  • 如果 $A$B 各自只包含一个项目(一个系列或一个数值),它们将连接。
  • 如果标签完全匹配,它们将连接。
  • 如果标签是另一个标签的子集,例如 $A 中的一个项目标签为 {host=A,dc=MIA},而 $B 中的项目标签为 {host=A},它们将连接。
  • 目前,如果在像 $A 这样的变量中,每个项目有不同的标签 ,则连接行为未定义。

关系运算符和逻辑运算符返回 0 表示 false,返回 1 表示 true。

数学函数

虽然大多数函数存在于各自的表达式操作中,但数学操作确实有一些类似于数学运算符或符号的函数。当函数可以接受数值或系列时,将返回与参数相同类型的对象。当它是系列时,将对系列中每个点的值执行操作。

abs

abs 返回其参数的绝对值,参数可以是数值或系列。例如 abs(-1)abs($A)

is_inf

is_inf 接受一个数值或一个系列,对于 Inf 值(负或正)返回 1,对于其他值返回 0。例如 is_inf($A)

注意

如果您需要专门检查负无穷,例如,可以进行比较,如 $A == infn()

is_nan

is_nan 接受一个数值或一个系列,对于 NaN 值返回 1,对于其他值返回 0。例如 is_nan($A)。存在此函数是因为 NaN 不等于 NaN

is_null

is_null 接受一个数值或一个系列,对于 null 值返回 1,对于其他值返回 0。例如 is_null($A)

is_number

is_number 接受一个数值或一个系列,对于所有实数值返回 1,对于其他值(null, Inf+, Inf-, 和 NaN)返回 0。例如 is_number($A)

log

Log 返回其参数的自然对数,参数可以是数值或系列。如果值小于 0,返回 NaN。例如 log(-1)log($A)

inf, infn, nan, 和 null

inf, infn, nan 和 null 函数都返回同名的单个值。它们主要用于测试。示例:null()

round

Round 返回一个四舍五入的整数值。例如,round(3.123)round($A)。(此函数可能应该接受一个参数,以便可以为四舍五入的值添加精度)。

ceil

Ceil 将数值向上舍入到最接近的整数值。例如,ceil(3.123) 返回 4。

floor

Floor 将数值向下舍入到最接近的整数值。例如,floor(3.123) 返回 3。

归约

归约接受一个或多个由查询或表达式返回的时间序列,并将每个系列转换为单个数值。时间序列的标签将保留为每个输出的归约数值的标签。

字段

  • 函数 - 要使用的归约函数
  • 输入 - 要重采样的变量(RefID,例如 A
  • 模式 - 允许控制归约函数在系列包含非数值(null、NaN、+-Inf)时的行为
归约函数
计数

计数返回每个系列中的点数。

平均值

平均值返回每个系列中所有值的总和除以该系列中的点数。在 strict 模式下,如果系列中的任何值是 null 或 nan,或者如果系列为空,则返回 NaN。

最小值和最大值

最小值和最大值分别返回系列中的最小值或最大值。在 strict 模式下,如果系列中的任何值是 null 或 nan,或者如果系列为空,则返回 NaN。

总和

总和返回系列中所有值的总和。如果系列长度为零,总和将为 0。在 strict 模式下,如果系列中有任何 NaN 或 Null 值,则返回 NaN。

最后一个

最后一个返回系列中的最后一个数值。如果系列没有值,则返回 NaN。

归约模式
严格

在严格模式下,输入系列按原样处理。如果系列中的任何值是非数值(null、NaN 或 +-Inf),则返回 NaN。

丢弃非数值

在此模式下,输入系列中所有非数值(null、NaN 或 +-Inf)在执行归约函数之前被过滤掉。

替换非数值

在此模式下,所有非数值都被预定义的值替换。

重采样

重采样将每个时间序列中的时间戳更改为具有一致的时间间隔。主要用例是您可以重采样不共享相同时间戳的时间序列,以便可以在它们之间执行数学运算。这可以通过对每个系列进行重采样,然后在数学操作中引用重采样的变量来完成。

字段

  • 输入 - 要重采样的时间序列数据变量(RefID,例如 A
  • 重采样到 - 要重采样的时间间隔,例如 10s。单位可以是 s 秒,m 分钟,h 小时,d 天,w 周,y 年。
  • 降采样 - 当每个窗口样本有多个数据点时使用的归约函数。有关行为详情,请参阅归约操作。
  • 升采样 - 用于填充没有数据点的窗口样本的方法。
    • pad 使用最后一个已知值填充
    • backfill 使用下一个已知值填充
    • fillna 使用 NaN 填充空样本窗口

编写表达式

如果您的数据源支持表达式,Grafana 将显示 Expression 按钮,并在查询编辑器列表中显示任何现有表达式。

有关表达式的更多信息,请参阅关于表达式

  1. 打开面板。

  2. 在查询下方,单击 Expression

  3. Operation 字段中,选择您要编写的表达式类型。

    有关表达式操作的更多信息,请参阅关于表达式

  4. 编写表达式。

  5. 单击 Apply

特殊情况

当任何查询的数据源没有返回系列或数值时,表达式引擎返回 NoData。例如,如果一个请求包含由表达式合并的两个数据源查询,并且至少有一个数据源查询返回 NoData,则整个查询的返回结果是 NoData

有关 Grafana 告警 如何处理 NoData 结果的更多信息,请参阅无数据和错误处理

在使用表达式处理多个查询时,表达式引擎要求所有查询返回相同的时间戳。例如,如果使用数学操作合并多个 SQL 查询的结果(每个查询都使用 SELECT NOW() AS "time"),只有当所有查询将 NOW() 评估为相同的时间戳时,表达式才能工作;但这并不总是发生。要解决此问题,可以将 NOW() 替换为任意时间,例如 SELECT 1 AS "time",或任何其他有效的 UNIX 时间戳。