Zabbix演示版本:2.4.4
涉及到的脚本语言:PHP
low-level discovery的意思是“低层次的自动发现”,检查lld。 lld并不似因为功能简单或者不重要而被称为“低层次的”,而是因为相对于服务器的自动发现,low-level discovery是针对服务器上设备的自动发现。
Zabbix 原生支持针对三种(文件系统、网卡、SNMP OIDs)自动发现来配套自动添加Items、Triggers 和 Graphs等。在lld中它们被称为Item原型、Trigger原型 和 Graph原型。
因为low-level discovery是基于Template或者Host的。一个low-level discovery由以下两部分组成。
- 探测部件(文件系统或者网卡)的Item,比如 net.if.discovery。
- 基于Item创建的Triggers 和 Graphs。
low-level discovery 的 Item比较特殊,普通的Item返回的可能是数字、字符串等的监控数据,lld的Item返回的是一个JSON对象,其中包含了探测到的部件列表。以net.if.discovery为例,它会返回一些键值对,比如"{#IFNAME}" - "lo",和 "{#IFNAME}" - "eth0"。
lld会发现很多不同的部件,比如多块网卡,这些变量(网卡名称,eth0,eth1等)会绑定在宏上。定义Triggers或者Items的时候使用这些宏来代替变量名就行了。针对侦测到的网卡的监控就可以是 net.if.out[{#IFNAME}]。
单击模板后面的“Discovery”链接进入Template OS Linux 的 lld界面,接下来可以看到我们想看到的lld。
在显示的界面中个,每一行里除了lld的名字外,显示了Item原型、Trigger原型、Graph原型 和 Host原型,因为作为例子的lld没有Host原型,所以笔者会在例子后面单独介绍它。“Key”就是执行lld的Item key(也就是那个需要返回JSON数据的key)。
其中
- Type:和配置Item时的Type的含义一致。
- Key:和配置Item时的key含义一致。
- Update interval (in sec):表示更新该lld发现规则的间隔时间。
- Flexible intervals:弹性的间隔时间。
- Keep lost resources period (in days):lld侦测到的新部件在各种原型保留多少天。 比如设置为10,那么在侦测到一块磁盘后的原型会连续监控10天,如果在10天内这块硬盘还被侦测到了,那么这个时间会顺延。设置这个参数的目的是当服务器上的部件发生变化时,能够将不用的部件禁用。注意,这里设置为0,并不是永远不停止,而是立刻删除。
- Filter选项卡:lld的Item会返回JSON对象,其中通常只有一部分是我们需要的。比如,vfs.fs.discovery返回的JSON是这样的:
{"data":[{"{#FSNAME}":"/","{#FSTYPE}":"rootfs"},{"{#FSNAME}":"/proc","{#FSTYPE}":"proc"},{"{#FSNAME}":"/boot","{#FSTYPE}":"ext4"},{"{#FSNAME}":"/data","{#FSTYPE}":"xfs"},{"{#FSNAME}":"/proc/sys/fs/binfmt_misc","{#FSTYPE}":"binfmt_misc"},{"{#FSNAME}":"/nfs","{#FSTYPE}":"nfs"}]}
而你只想要监控nfs的,那么就需要对{#FSTYPE}进行过滤,简单来说,需要{#FSTYPE}符合一些条件。这里所说的条件是在“Administration → General”的Regular Expressions中配置的,它对{#FSTYPE}进行了过滤。
1 ^(btrfs|ext2|ext3|ext4|jfs|reiser|xfs|ffs|ufs|jfs|jfs2|vxfs|hfs|ntfs|fat32|zfs)$[Result is TRUE]
下面来创建 Item原型:
Item原型的配置和普通的Item是差不多的,唯一不同的就是key中使用了特殊的宏来替代lld发现的部件的变量。 比如图中的{#FSNAME}就是磁盘路径。 Trigger原型 和 Graph原型都是类似的情况。
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
实际操作:结合Nginx的两个第三方模块实现Nginx单独虚拟主机的并发监控
第三方模块1:ngx_req_status GitHub
第三方模块2:ngx_realtime_request_module GitHub
这两个模块功能差不多,但还是有那一点小区别。
大致上分为以下几个步骤:
- 编译Nginx 添加支持查询虚拟主机状态数据的第三方模块。
- zabbix agent端添加自定义key
- 编写自定义key的数据采集脚本
- 并且该脚本支持单独主机的数据抽样采集
- zabbix 编写lld模板配置
- 关联实体监控主机并测试
首先需要在编译Nginx的时候添加第三方模块。(省略)
web访问测试。
realtime_request
req_status
我这里使用的php写的两个简单的脚本。源码如下(这里只讲req_status模块)
// ngx_req_status 模块 <?php /** * Created by PhpStorm. * User: Eric * Date: 2016/09/20 * Time: 21:20 */ /** 此模块适用于 ngx_req_status 统计模块 */ // bugfix $URL = ‘http://localhost/req_status?l‘; $CONTENT = explode("\n", file_get_contents($URL)); function handle_req_status_to_hostArray($subject, $argv) { function sub_explode($value) { return explode("\t", $value); } function sub_filter($value) { if (is_array($value) && count($value) > 1) { return $value; } } function sub_combine($value) { $item_name = array(‘zone‘, ‘{#KEY}‘, ‘max_active‘, ‘max_bandwidth‘, ‘traffic‘, ‘request‘, ‘current_active‘, ‘current_bandwidth‘); return array_combine($item_name, $value); } if (count($argv) == 2) { $split = explode(" ", $argv[2]); $argv[1] = $split[0]; $argv[2] = $split[1]; } if (is_array($subject)) { $result = array_map(‘sub_explode‘, $subject); $result = array_filter($result, ‘sub_filter‘); $result = array_map(‘sub_combine‘, $result); array_shift($result); if (count($argv) > 1) { while ($item = each($result)) { if ($item[‘value‘][‘{#KEY}‘] == $argv[1]) { return $item[‘value‘][$argv[2]]; } } } //return $result; return array(‘data‘ => $result); } else { return $subject; } } if (!isset($argv)) { $argv = false; } // web浏览不报错 $test = handle_req_status_to_hostArray($CONTENT, $argv); if (count($argv) > 1) { echo $test; } else { echo json_encode($test); } ?>
req_status模块的nginx配置如下
http { req_status_zone server_name "$server_name:$server_port" 256k; // key值是基于server_name和server_port的组合值 req_status server_name; ..... server { ..... location = /req_status { req_status_show on; } } }
这个就是ngx_req_status返回的数据格式,然后利用php处理该数据返回位JSON对象。
而且该脚本也能根据提供两个参数取出特定的值。如图
最后做好测试工作(通过zabbix_get方式获取例如该key的值)。
回到正题,配置 Zabbix 模板
根据如图配置新生成一个新的空模板。
点击模板的 Discovery rules → Create discovery rules 创建一个新的 lld 发现规则。
如图,配置好lld发现规则。
这里的 key 就是需要在zabbix_agentd中配置的自定义key,对应的是那个php脚本。
由于我没有需要过滤的数据,所以Filter页面就留空。
点击上面的 Item prototypes 进入到Item原配置界面。
按照如图,配置好6个根据{#KEY}迭代的key值。(注意区分大小写,特殊的{#KEY}宏是需要特定的格式,而且全大写字母)
比如 req_status current Request 这个监控项
然后创建图形源模板
比如 Nginx_req_status - {#KEY} - Current Data 这个图形源的配置
这些都配置好过后,那么接下来就可以关联那台nginx主机了。
关联该模板过后,大约在lld发现规则周期之内就会根据定义查询指定主机的 ngx_req_status key值返回的JSON数据了。
如果配置都正常,那么就会陆续自动添加很多监控项,然后生成图形。
注意事项:
- lld discovery自动发现的key的返回值必须是指定格式的JSON对象数据。 比如格式为
{"data":[{"{#HOST}":" "request":"1024", "active":"512"}, {"{#HOST}":"static.bdimg.com", "request":"4051", "active":"2415"}]}
其中还有一点是需要注意的,稍不注意就容易掉坑里。作为lld发现key的特殊宏的格式是特定的,上例中的格式中只有{#HOST}这个特殊宏才能作为lld发现key,而且key的字母必须为全大写。
B. lld的发现key的间隔时间与该发现规则的 Item原型的间隔时间是不相干的,前者可以设置的间隔时间稍大,后者就相当于一个普通的Item项,根据你业务的需求设置监控粒度。
C. UserParameter=ngx_req_status[*],php /tmp/req_status.php $1 $2 这样可以让php脚本接收两个命令行参数,但是在zabbix web端配置的时候,有个坑,, 如图
模板Item原型中的key参数之间不能有空格。(我当时在逗号后面接了个空格,导致zabbix_get始终无法测试出带两个参数的key值获取,捣鼓了好久,才看到这个坑)