7 可计算监控项

概述

此监控项类型允许对已存在的指标进行计算。计算型监控项本身不会采集任何数据。

例如,您可能希望:

  • 对两个值进行计数。
  • 计算多个监控项值的平均值。
  • 计算一组监控项的总值。

结果值会像其他任何监控项一样存储在 Zabbix 数据库中;历史值和趋势值都会被存储,并且可以生成图形。

计算基于公式进行。公式的语法与触发器表达式共用。

实际上,可以通过将复杂的数据处理逻辑放在计算型监控项中来保持触发器的简洁——然后在触发器中使用监控项键来引用该计算型监控项。

指定计算数据源有两种方式:

  1. 在公式中指定监控项。
  2. 基于选择监控项的过滤器执行数据聚合

第二种方式允许计算组平均值、总值等。

所有计算都由 Zabbix 服务器完成;proxy 或 agent 完全不参与。请注意,大量使用具有较长时间周期的计算型监控项可能会影响服务器性能。

可配置字段

要使用计算型监控项,请选择监控项类型 Calculated

key 是唯一的监控项标识符(每个主机内唯一)。您可以使用受支持的符号创建任意 key 名称。key 允许在触发器中引用该计算型监控项。

必须在 Formula 字段中输入计算定义。

公式与 key 之间没有任何关联。key 参数 不会以任何方式在公式中使用。

与触发器表达式不同,Zabbix 处理计算型监控项时是根据 监控项更新间隔进行的,而不是在接收到新值时进行。

请注意,如果您选择 Numeric (unsigned) 作为信息类型,而计算结果是浮点值,则会将其截断为整数。

简单计算公式

简单公式的语法为:

function(/host/key,<parameter1>,<parameter2>,...)

其中:

Element Description
function 支持的函数之一:last、min、max、avg、count 等
host 用于计算的监控项所属的主机。
当前主机可省略(即如 function(//key,parameter,...) 所示)。
key 用于计算的监控项的键。
不支持返回二进制或 JSON 数据类型值的监控项。
如果更改了被引用监控项的键,则必须在公式中手动更新该键。
所有被历史函数引用的监控项都必须存在并且正在采集数据。
parameter(s) 函数的参数(如需要)。
支持时间后缀内存大小后缀

更复杂的公式可以使用函数、运算符和括号的组合。

请参见计算型监控项公式示例:

某些变量可以通过用户宏传递给公式。
请注意,仅当用户宏用于引用函数参数、监控项过滤参数或常量时,才会被解析。
如果用户宏引用的是函数、主机名、监控项键、监控项键参数或运算符,则不会被解析。

允许与字符串进行比较。

如果缓存中没有最近的数据,并且函数中未定义查询周期,Zabbix 默认会向过去回溯最多一周,以从数据库中查询历史值。

计算型监控项在以下几种情况下可能变为不支持:

  • 被引用的监控项
    • 未找到
    • 已禁用,或属于已禁用的主机
    • 不受支持(nodata() 函数以及带有未知值的运算符除外)
  • 没有可用于计算函数的数据
  • 除以零
  • 使用了错误的语法

数据聚合

数据聚合基于一个用于选择多个监控项的过滤器。数据聚合也是一种计算型监控项,不过在公式中使用的语法略有不同。

要获取聚合值,请使用支持的聚合函数之一:avgmaxminsum 等。 然后添加 foreach 函数作为唯一参数,以及其监控项过滤器来选择所需的监控项:

aggregate_function(function_foreach(/host/key?[group="host group"],timeperiod))

foreach 函数(例如 avg_foreachcount_foreach 等)会为每个选定的监控项返回一个聚合值。 监控项通过监控项过滤器(/host/key?[group="host group"])从监控项历史数据中选出。 更多详细信息,请参见 foreach 函数

如果某些监控项在请求的时间段内没有数据,则在计算时会忽略它们。 如果没有任何监控项有数据,则该函数将返回错误。

或者,您也可以将多个监控项列为聚合的参数:

aggregate_function(function(/host/key,parameter),function(/host2/key2,parameter),...)

请注意,这里的 function 必须是历史/趋势函数。

请参见聚合计算示例:

以下位置支持用户宏和低级发现宏:

  • 监控项键参数
  • 函数参数
  • 过滤条件(主机组名称和标签名称)
  • 表达式常量

在以下情况下,聚合计算可能变为不受支持:

  • 找不到任何被引用的监控项(这可能发生在监控项键不正确、监控项均不存在,或所有包含的组都不正确时)
  • 没有可用于计算函数的数据

计算监控项示例

(1) 接口上的总流量
last(//net.if.in[eth0,bytes])+last(//net.if.out[eth0,bytes])

计算 eth0 上的总带宽。

(2) 可用磁盘空间百分比
100*last(//vfs.fs.size[/,free])/last(//vfs.fs.size[/,total])

Zabbix 将获取 / 上可用磁盘空间和总磁盘空间的最新值,并根据给定公式计算百分比。

(3) 入站流量百分比
100*last(//net.if.in[eth0,bytes])/(last(//net.if.in[eth0,bytes])+last(//net.if.out[eth0,bytes]))

计算总流量中入站流量所占的百分比。

(4) 已处理值的平均数量
avg(/Zabbix server/zabbix[wcache,values],10m)

计算 Zabbix 在 10 分钟内处理的值数量的平均值。

(5) 主机的总入站流量
sum(last_foreach(/host/net.if.in[*]))

计算主机上所有匹配 net.if.in[*] 的监控项总和。

(6)组的总磁盘空间
sum(last_foreach(/*/vfs.fs.size[/,total]?[group="MySQL Servers"]))

计算所有 MySQL Servers 的总磁盘空间。

(7)组的平均处理器负载
avg(last_foreach(/*/system.cpu.load[,avg1]?[group="MySQL Servers"]))

计算所有 MySQL Servers 的平均处理器负载。

(8)组和标签的平均处理器负载
avg(last_foreach(/*/system.cpu.load?[(group="Servers A" or group="Servers B" or group="Servers C") and (tag="Service:" or tag="Importance:High")]))

计算多个主机组中具有特定标签的所有主机上的平均 CPU 负载。

(9) Average number of queries for group
avg(avg_foreach(/*/mysql.qps?[group="MySQL Servers"],5m))

Calculate the 5-minute average of the number of queries per second for MySQL Servers.

(10) 成功 DNS 检查总数
sum(last_foreach(/*/net.dns[*,*,*]))

计算所有主机上成功 DNS 检查的总数。
显示的监控项形式 net.dns[192.0.2.0,example.com,A] 只是一个可能键值的示例。

请注意,通配符必须与键中的参数数量匹配(这里 net.dns 有三个参数:ip、name、type)。

(11)组中不受支持监控项的总数
sum(last_foreach(/*/zabbix[host,,items_unsupported]?[group="Zabbix servers"]))

计算 Zabbix servers 的不受支持监控项总数。

(12)组的接口统计信息
sum(last_foreach(/*/net.if.out[eth0,bytes]?[group="video"])) / sum(last_foreach(/*/nginx_stat.sh[active]?[group="video"])) 

计算 video 组的接口统计信息。

Examples of correct/incorrect syntax

Expressions (including function calls) cannot be used as history, trend, or foreach function parameters. However, those functions themselves can be used in other (non-historical) function parameters.

Expression Example
Valid avg(last(/host/key1),last(/host/key2)*10,last(/host/key1)*100)

max(avg(avg_foreach(/*/system.cpu.load?[group="Servers A"],5m)),avg(avg_foreach(/*/system.cpu.load?[group="Servers B"],5m)),avg(avg_foreach(/*/system.cpu.load?[group="Servers C"],5m)))
Invalid sum(/host/key,10+2)

sum(/host/key, avg(10,2))

sum(/host/key,last(/host/key2))

Note that in an expression like:

sum(sum_foreach(//resptime[*],5m))/sum(count_foreach(//resptime[*],5m))

it cannot be guaranteed that both parts of the equation will always have the same set of values. While one part of the expression is evaluated, a new value for the requested period may arrive and then the other part of the expression will have a different set of values.