这是原厂英文文档的翻译页面. 欢迎帮助我们 完善文档.
2022 Zabbix中国峰会
2022 Zabbix中国峰会

3 底层自动发现

概述

底层自动发现可以自动为主机上的不同实体创建监控项、触发器和图表。比如, Zabbix可以自动监控文件系统和网络接口,并且不需要为其手工创建监控项。另外,可以基于周期性自动发现的结果来删除无用的监控实体。

用户可以基于特定的JSON格式来自定义发现类型。

自动发现的大体流程如下:

首先,用户在 "配置" → "模板" → "自动发现" 一栏中创建发现规则。发现规则包含用来发现特定实体(如文件系统和网络接口)的(1)监控项以及监控项、触发器和图表的(2)原型。

用于自动发现的监控项与常规监控项没有大体区别:Zabbix server向agent(或者其它任何类型的监控代理)请求监控项的值,agent对其回复一个文本值。唯一区别是agent响应中包含所发现的一系列JSON数组。对自动发现检查规则有自定义的需求时才需要了解格式的细节方面,不过有必要知道返回值包含一系列 宏 → 值 的键值对。比如,监控项 "net.if.discovery" 会返回两组键值对:"{#IFNAME}" → "lo" 和 "{#IFNAME}" → "eth0"。

当创建实际的监控项、触发器、图表以及主机时,宏会替换成接收到的值。使用底层自动发现(LLD)的宏请参考 选项 中的全部列表。

当通过自动发现收到监控项返回值的时候,Zabbix server会查找 宏 → 值 键值对,每一对 宏 → 值 会基于原型生成监控项、触发器和图表。在上述 "net.if.discovery" 的例子中,为环回接口 "lo" 生成了一组监控项、触发器和图表,为 "eth0"接口生成了一组监控项、触发器和图表。

注意,自从Zabbix 4.2 开始,底层自动发现返回的JSON数组的格式变化了。JSON格式将不再包含 "data" 对象。现在底层自动发现接收一个普通的JSON数组,用于实现一些新特性,如监控项值的预处理和对于JSON文件中用于底层自动发现的宏的路径自定义。

内置的自动发现的键已经可以实现在JSON文件的根路径返回一个底层自动发现数组。如果数组使用{#MACRO}作为键,则宏和值会自动提取。任何新版的内置的自动发现检查会使用不含 "data"元素 的新语法格式。当处理一个底层自动发现的值时,第一个步骤就是定位根目录 (数组的根目录是 $.$.data)。

当"data"元素从所有跟自动发现有关的内置监控项中移除时,为了向后兼容,Zabbix会接受带有"data"元素的JSON格式,不过并不鼓励这么用。如果JSON数据包含一个对象,该对象只有一个"data"数组,则"data"数组的内容会通过JSONPath $.data自动提取出来。底层自动发现现在接受可选的自定义宏,可在JSONPath语法中自定义路径。

上述变更会导致新的agent不再跟旧的Zabbix server有任何关联。

参阅: 发现的实体

配置底层自动发现

下面是一个文件系统自动发现的例子。

要配置自动发现, 需完成下列操作:

  • 找到: 配置模板主机
  • 在对应模板/主机中点击 自动发现

  • 在屏幕右上角点击 创建自动发现规则
  • 在发现规则表格中填入所需信息

自动发现规则

自动发现规则表格包含五个选项卡,从左到右表示自动发现的数据流:

  • 自动发现规则 - 最重要的一项,指定了用于获取自动发现的数据的内置监控项或自定义脚本
  • 预处理 - 对发现的数据进行预处理
  • LLD 宏 - 提取已发现的监控项、触发器等监控指标上配置的宏的取值。
  • 过滤 - 过滤发现的值
  • 覆盖 - 允许修改发现对象的监控项、触发器、图表和主机的原型

自动发现规则 选项卡包含用于自动发现的监控项的键 (以及一些通用的发现规则属性):

所有强制输入区域均会标记红色星号。

参数 描述
名称 自动发现规则名称。
类型 自动发现检查的类型。
此例中使用 Zabbix agent 这个监控项的键。
自动发现规则还可以定义为 依赖型监控项, 此监控项依赖标准监控项,但不可依赖于其它自动发现规则。对于一个依赖型监控项来说, 选择对应类型 (依赖型监控项) 然后在 '主监控项' 区域指定主监控项。主监控项必须已存在。
输入监控项的键 (最大2048个字符)。
例如,可以使用内置的 "vfs.fs.discovery" 监控项的键来返回一个JSON数组列表,包含计算机文件系统和计算机类型。
注意,文件系统自动发现还可以使用"vfs.fs.get"键的发现结果,从Zabbix 4.4.5 (参照 示例)开始支持此特性。
更新间隔 此区域指定了执行自动发现的频率。刚开始执行文件系统自动发现时,可以设置很小的间隔,但当发现之前设置的已经生效,就可以改为30分钟或更长。因为文件系统通常不太会变化。
从Zabbix 3.4.0开始支持时间后缀,比如 30s, 1m, 2h, 1d。
从Zabbix 3.4.0开始支持用户宏
注意: 如果设置了取值非零的自定义间隔,则更新间隔只能设置为'0'。 如果更新间隔设置为 '0', 并且自定义间隔 (类型:灵活 或 计划) 存在非零值, 则监控项的检查频率基于自定义间隔。
注意 对于已存在的自动发现规则来说,通过点击 立刻检查 按钮可以立即执行自动发现。
自定义间隔 可创建自定义规则来检查监控项:
灵活 - 创建一个 例外的更新间隔 (不同频率的更新间隔)。
计划 - 创建一个自定义的更新时间表。
详细信息参阅 自定义间隔。从Zabbix 3.0.0开始支持该特性。
保存丢失资源倒计时 指定已发现的资源不被删除的倒计时时间间隔,当该资源的状态变成 "不再被发现"时开始倒计时(从1小时到25年;或"0")。
从Zabbix 3.4.0开始支持时间后缀,比如 2h, 1d。
从Zabbix 3.4.0开始支持用户宏
注意: 如果值设置为 "0", 资源会马上被删除。不推荐使用 "0",因为错误的设置可能导致资源连同相关历史数据均被删除。
描述 输入描述信息。
启用 如果选定,则规则生效。

自动发现规则历史记录不会保存。

预处理

预处理 选项卡定义发现结果的转换规则。可以定义一个或多个转换规则。 转换规则执行的顺序以定义的顺序为准。所有预处理均由Zabbix server来执行。 参阅:

类型 转换 描述
Text
正则表达式 将接收的值匹配正则表达式的匹配模式<pattern>,并替换为输出<output>。正则表达式可以使用 \N 转义字符提取最多10个匹配的组。
参数:
匹配模式 - 正则表达式
输出 - 输出格式化的模板。一个 \N (N=1…9) 转义字符会替换为第N个匹配的组。一个 \0 转义字符替换为匹配的文本。
如果选取了 自定义失败 检查框, 则可以自定义错误处理选项: 要么舍弃该值并设置一个特定值,要么设置一个错误信息。
替换 搜索字符串并替换为另一个字符串或空字符串。所有搜索结果均会被替换。
参数:
搜索字符串 - 需要搜索的字符串, 大小写敏感(强制要求)
替换 - 最终替换成为的字符串。替换成为的字符串可以是空值,通常用于删除搜索字符串。
可使用转义字符 "\n \r \t \s" 查找替换换行符, 回车, 制表符和空格; 反斜线可以用 "\\" 转义,转义序列可以用 "\\n"转义。底层自动发现过程中,换行符, 回车和制表符自动转义。
从5.0.0版本开始支持。
结构化数据
JSONPath 使用JSONPath功能提取数据或将JSON数据分片。
如果选取了 自定义失败 检查框, 万一预处理失败,监控项不会变为不支持。另外还可以自定义错误处理选项: 要么舍弃该值并设置一个特定值,要么设置一个错误信息。
XML XPath 使用XPath功能提取数据或将XML数据分片。
要使用此功能,Zabbix server服务器需要安装libxml库。
例子:
number(/document/item/value) 会从 <document><item><value>10</value></item></document>提取 10
number(/document/item/@attribute) 会从 <document><item attribute="10"></item></document>提取 10
/document/item 会从 <document><item><value>10</value></item></document>提取 <item><value>10</value></item>
注意,不支持命名空间。
从4.4.0版本开始支持此特性。
如果选取了 自定义失败 检查框, 则可以自定义错误处理选项: 要么舍弃该值并设置一个特定值,要么设置一个错误信息。
CSV to JSON 转换CSV数据到JSON格式。
更多信息请参考: CSV到JSON数据预处理.
从4.4.0版本开始支持此特性。
XML to JSON 转换XML数据到JSON格式。
更多信息请参阅: 序列化规则.
如果选取了 自定义失败 检查框, 则可以自定义错误处理选项: 要么舍弃该值并设置一个特定值,要么设置一个错误信息。
自定义脚本
JavaScript 点击参数区域或点击 打开 输入Javascript代码。
注意,可输入的Javascript代码长度取决于 使用的数据库.
更多信息请参考: Javascript代码预处理
验证
不匹配正则表达式 指定一个不匹配任何取值的正则表达式。
例如 Error:(.*?)\.
如果选取了 自定义失败 检查框, 则可以自定义错误处理选项: 要么舍弃该值并设置一个特定值,要么设置一个错误信息。
检查JSON数据错误 检查JSONpath路径下的应用层错误信息。如果执行成功并且信息不为空则不检查; 否则继续检查此预处理步骤之前的值。注意,这些外部服务错误原封不动报告给用户,不会添加预处理步骤信息。
例如 $.errors。如果收到一个这样的JSON数据{"errors":"e1"} ,则下个预处理步骤不会执行。
如果选取了 自定义失败 检查框, 则可以自定义错误处理选项: 要么舍弃该值并设置一个特定值,要么设置一个错误信息。
检查XML数据错误 检查xpath路径下的应用层错误信息。如果执行成功并且信息不为空则不检查; 否则继续检查此预处理步骤之前的值。注意,这些外部服务错误原封不动报告给用户,不会添加预处理步骤信息。
无效的XML分析失败不会报告给用户。
从4.4.0版本开始支持此特性。
如果选取了 自定义失败 检查框, 则可以自定义错误处理选项: 要么舍弃该值并设置一个特定值,要么设置一个错误信息。
限流
丢弃心跳时间内未改变的值 如果一个值在定义的时间周期内(秒)未改变,则丢弃该值。
秒数的范围为正整数(最小1秒)。可使用时间后缀 (如 30s, 1m, 2h, 1d)。可使用用户宏和底层自动发现宏。
一个自动发现监控项只能指定一个限流选项。
比如 1m. 如果规则在60秒内收到两次相同的值,则相同的值会被丢弃。
注意: 改变监控项原型不会重置限流。仅当预处理步骤发生变化时,限流才会重置。
Prometheus
Prometheus到JSON格式 转换Prometheus度量到JSON格式。
参阅 Prometheus检查 获取更多信息。

注意,如果自动发现规则已经通过模板应用到主机上,则此选项卡的内容是只读的。

自定义宏

LLD 宏 选项卡可以自定义底层自动发现的宏。

如果返回的JSON数据不包含所需的宏时,自定义宏就派上用场了。例如:

  • 用于文件系统自动发现的内置的 vfs.fs.discovery 键返回JSON数据,其中包含一些预定义的LLD宏,比如 {#FSNAME}, {#FSTYPE}。这些宏可直接用于监控项和触发器原型,(参考本页后续小节); 自定义宏不是强制的;
  • vfs.fs.get 键同样返回JSON数据,包含 文件系统数据, 但不包括任何预定义的LLD宏。此例中你可以自定义宏, 并把自定义的宏映射到JSONPath返回的JSON数据上:

提取的值可用于已发现的监控项、触发器等实体上。 注意,值会从自动发现的结果中提取出来,也会从任何到目前为止的预处理步骤的结果中提取出来。

参数 描述
LLD宏 底层自动发现宏的名称, 使用如下的语法格式: {#MACRO}.
JSONPath 用于提取LLD宏的取值的路径, 使用JSONPath语法格式.
比如, $.foo 会从下面的JSON数据中提取 "bar" 和 "baz": [{"foo":"bar"}, {"foo":"baz"}]
从JSON数据中提取的值用于替换监控项、触发器和其它实体的原型中配置的LLD宏。
可以使用点标记法或括号标记法来指定JSONPath。括号标记法应该用于任何使用特殊字符和编码的场景中, 像 $['unicode + special chars #1']['unicode + special chars #2']

过滤器

过滤器可用于生成只匹配过滤条件的监控项、触发器和图表。过滤器 选项卡包含自动发现规则的过滤器配置,其可以过滤自动发现的值:

参数 描述
计算类别 可用的过滤器选项如下:
- 必须满足所有过滤条件;
- 只需满足其中一条过滤条件即可;
和/或 - 不同宏的名称使用 ,相同宏的名称使用 ;
自定义表达式 - 可自定义过滤器的计算公式。公式必须包含列表中的所有过滤器。最大限制255个符号。
过滤器 可用下列过滤器条件操作符: 匹配, 不匹配, 存在, 不存在.
匹配不匹配 操作符可识别与Perl兼容的正则表达式 (PCRE). 例如, 如果你只对文件系统 C:, D: 和 E: 感兴趣, 那么可将 {#FSNAME} 放入 "宏" 然后 将正则表达式 "^C|^D|^E" 放入 "正则表达式" 文本区域. 还可通过使用{#FSTYPE} 宏 (比如. "^ext|^reiserfs") 过滤文件系统类型以及使用 {#FSDRIVETYPE} 宏 (比如, "fixed")过滤驱动类型 (只支持Windows agent)。
可以在 "正则表达式" 区域输入正则表达式或引用全局的 正则表达式
要测试正则表达式,可以使用"grep -E", 比如: for f in ext2 nfs reiserfs smbfs; do echo $f \| grep -E '^ext\|^reiserfs' \|\| echo "SKIP: $f"; done{#FSDRIVETYPE}宏可用于Windows系统上,此特性从Zabbix 3.0.0开始支持。

存在不存在 操作符可以基于响应数据中包含的特定LLD宏(存在或缺失)进行过滤(从5.4.0版本开始支持)。
从Zabbix 2.4.0 版本开始支持定义多个过滤器。

用于LLD规则中的正则表达式中的拼写错误(例如, 一个错误的 "文件系统自动发现" 的正则表达式)可能造成很多个配置项、历史数据以及主机的事件信息被删除。

如果操作系统名称只能通过区分大小写来正确识别,那么Zabbix的MYSQL数据库必须配置成大小写敏感。

覆盖

覆盖 选项卡允许设置规则来修改监控项,触发器、图形和主机原型或它们的属性以用于发现满足给定条件的对象。

覆盖(如果有)在可重新排序的拖放列表中显示,并且按照定义的顺序执行。 配置一个新的覆盖,在 覆盖选项卡单击 。要编辑现有覆盖,请单击覆盖名称。在弹出窗口中编辑覆盖规则详细信息。

所有强制参数都标有红色星号。

参数 描述
名称 唯一的(根据 LLD 规则)覆盖名称。
如果过滤器匹配 当下面条件满足时,下一个覆盖是否需要执行:
继续覆盖 - 后续覆盖会执行。
停止处理 - 前面的操作 (如果有) 和当前操作会执行, 后续覆盖会忽略。
过滤器 定义了覆盖会应用到哪些已发现实体上。覆盖过滤器在自动发现规则的过滤器 之后执行,其和自动发现规则的过滤器功能相同。
操作 覆盖操作包含下列内容:
条件 - 一个对象类型 (监控项原型/触发器原型/图表原型/主机原型) 和一个需要满足的条件(等于/不等于/包含/不包含/匹配/不匹配)
动作 - 编辑和移除操作的链接。

配置一个操作

要配置一个新操作, 点击操作面板上的 。编辑现有操作, 点击操作旁边的 。点击编辑按钮会出现弹窗。

参数
对象
条件
操作
模式
对象: 监控项原型
启用创建
发现
更新间隔
历史保存周期
趋势数据保存周期
标签
对象: 触发器原型
启用创建
发现
严重性
标签
对象: 图形原型
发现
对象: 主机原型
启用创建
发现
链接模板
标签
主机资产

表格按钮

表格底部按钮允许执行一些操作。

· ·
添加自动发现规则。此按钮只能用于新的自动发现规则。
更新自动发现规则的属性。此按钮只能用于现有的自动发现规则。
基于当前自动发现规则的属性,创建另一个自动发现规则。
立即运行自动发现规则。该自动发现规则必须已存在。 参考 更多信息.
注意 当立即执行自动发现时, 配置缓存并没有更新, 所以自动发现的结果可能不会显示最近的变更。
删除自动发现规则。
取消对自动发现规则的编辑。

发现的实体

下面的截图展示了主机配置中已发现的监控项、触发器和图表。发现的实体用橙色的链接作为前缀标记,橙色链接指向关联的自动发现规则。

注意,如果跟现有实体的设备唯一标识相同,则不会创建新发现的实体。比如,一个监控项的键的名称重复或图表的名称重复。此类错误会显示在前端页面上,表明低级别自动发现无法创建对应实体。然而自动发现规则本身无法变为不支持的(unsupported)状态,因为一些实体无法创建,且必须跳过。自动发现规则会继续创建/更新其它实体。

如果发现的实体(文件系统、接口等)不再被发现(或过滤器过滤不出来),则由低级别自动发现创建的监控项(触发器、图表也类似)会自动删除。此场景中,监控项、触发器和图表会在若干时间后被删除,数据保存的时间定义在 保存丢失资源周期 输入框中。

当发现的实体变为 '不再被发现', 监控项列表中会显示一个涵盖整个生命周期的数据。移动鼠标到该数据上面,会显示离删除还剩多少天。

如果实体标记为已删除,但过期未删除(由于禁用了发现规则或禁用了监控的主机),则会在下次运行自动发现规则时删除这些实体。

包含其它实体的实体,且标记为已删除,如果在自动发现规则层面做了变更,则不会再更新。比如, 基于低级别自动发现的触发器不会再更新,即使它们包含标记为已删除的实体。

其它类型的自动发现

如果想立刻上手熟悉其它类型的自动发现,更多信息和如何实现(how-to)方面可参阅以下章节:

更多关于JSON格式的自动发现和关于如何使用Perl脚本对文件系统做自动发现,请参阅 创建自定义LLD规则

创建自定义LLD规则

可以创建完全自定义的底层自动发现(LLD)规则,用于发现任何类型的实体 - 例如,服务器上运行的数据库。

要实现此功能,需要创建一个自定义监控项,监控项需要返回JSON数据,其中包含发现的对象以及其它可选项 - 对象的一些属性。每个实体的宏没有数量限制 - 内置的自动发现规则返回一个或两个宏(比如文件系统自动发现返回两个宏),但自定义的LLD可以返回更多个宏。

最好用一个例子来演示所需的JSON格式比较容易理解。假设一个旧版的Zabbix 1.8的agent正在运行(该agent不支持"vfs.fs.discovery"这个监控项的键),不过我们还需要对文件系统进行自动发现。下面是个简单的Perl脚本,运行在Linux上,用于发现挂载的文件系统并输出JSON数据,JSON数据中包含文件系统名称和类型。使用Perl脚本的其中一种方式是作为一个UserParameter,利用 "vfs.fs.discovery_perl" 这个键:

#!/usr/bin/perl
       
       $first = 1;
       
       print "[\n";
       
       for (`cat /proc/mounts`)
       {
           ($fsname, $fstype) = m/\S+ (\S+) (\S+)/;
       
           print "\t,\n" if not $first;
           $first = 0;
       
           print "\t{\n";
           print "\t\t\"{#FSNAME}\":\"$fsname\",\n";
           print "\t\t\"{#FSTYPE}\":\"$fstype\"\n";
           print "\t}\n";
       }
       
       print "]\n";

LLD宏的名称允许使用的符号有 0-9 ,A-Z , _ , .

名称中不支持小写字母。

下面是一个输出(为了看的更清晰,重新排版)的例子。自定义的自动发现检查的JSON格式必须遵循相同的形式。

[
           { "{#FSNAME}":"/",                           "{#FSTYPE}":"rootfs"   },
           { "{#FSNAME}":"/sys",                        "{#FSTYPE}":"sysfs"    },
           { "{#FSNAME}":"/proc",                       "{#FSTYPE}":"proc"     },
           { "{#FSNAME}":"/dev",                        "{#FSTYPE}":"devtmpfs" },
           { "{#FSNAME}":"/dev/pts",                    "{#FSTYPE}":"devpts"   },
           { "{#FSNAME}":"/lib/init/rw",                "{#FSTYPE}":"tmpfs"    },
           { "{#FSNAME}":"/dev/shm",                    "{#FSTYPE}":"tmpfs"    },
           { "{#FSNAME}":"/home",                       "{#FSTYPE}":"ext3"     },
           { "{#FSNAME}":"/tmp",                        "{#FSTYPE}":"ext3"     },
           { "{#FSNAME}":"/usr",                        "{#FSTYPE}":"ext3"     },
           { "{#FSNAME}":"/var",                        "{#FSTYPE}":"ext3"     },
           { "{#FSNAME}":"/sys/fs/fuse/connections",    "{#FSTYPE}":"fusectl"  }
       ]

上面的例子中需要让键匹配原型中使用的LLD宏的名称,另一种方式是提取LLD宏的值,提取的方式是通过JSONPath {#FSNAME}$.fsname{#FSTYPE}$.fstype, 于是可以使用下面的脚本来实现此功能:

#!/usr/bin/perl
        
       $first = 1;
        
       print "[\n";
        
       for (`cat /proc/mounts`)
       {
           ($fsname, $fstype) = m/\S+ (\S+) (\S+)/;
        
           print "\t,\n" if not $first;
           $first = 0;
        
           print "\t{\n";
           print "\t\t\"fsname\":\"$fsname\",\n";
           print "\t\t\"fstype\":\"$fstype\"\n";
           print "\t}\n";
       }
        
       print "]\n";

下面是一个输出(为了看的更清晰,重新排版)的例子。自定义的自动发现检查的JSON格式必须遵循相同的形式。

[
           { "fsname":"/",                           "fstype":"rootfs"   },
           { "fsname":"/sys",                        "fstype":"sysfs"    },
           { "fsname":"/proc",                       "fstype":"proc"     },
           { "fsname":"/dev",                        "fstype":"devtmpfs" },
           { "fsname":"/dev/pts",                    "fstype":"devpts"   },
           { "fsname":"/lib/init/rw",                "fstype":"tmpfs"    },
           { "fsname":"/dev/shm",                    "fstype":"tmpfs"    },
           { "fsname":"/home",                       "fstype":"ext3"     },
           { "fsname":"/tmp",                        "fstype":"ext3"     },
           { "fsname":"/usr",                        "fstype":"ext3"     },
           { "fsname":"/var",                        "fstype":"ext3"     },
           { "fsname":"/sys/fs/fuse/connections",    "fstype":"fusectl"  }
       ]

然后在自动发现规则的 "过滤器" 选项卡中,可以指定"{#FSTYPE}" 作为宏 和"rootfs|ext3" 作为正则表达式。

无需使用 FSNAME/FSTYPE 作为自定义LLD规则中的宏的名称,可以使用任何名称。一旦使用了JSONPath,则LLD返回的数据会是一个数组元素,该元素可以是一个对象、另一个数组或一个值。

注意,如果使用一个用户参数,返回值限制在512 KB大小。更多信息请参考 LLD返回值的数据大小限制.