ZX ly模板针对ZX OLT C600的监控,除了最基础的system description和system name(前者是OLT自身的型号属性,后者是我们对OLT的命名)、operational status(端口运行状态)、speed(端口当前带宽的估计值,默认是10g)这四项,还拥有端口收发流量、光模块发光功率、下联ONU收光功率、下联ONU的Loid这四项。总共八个监控内容。
本文的一、二介绍基础的四项,剩余部分介绍光衰相关的监控功能。
一、system description和system name
以system description为例介绍SNMP代理类型监控项最基本的配置。


名称:相当于人的名称,没有实际作用。我往往写的较详细,一眼能看出监控内容。
类型:SNMP代理,利用SNMP OID获取被监控对象信息。
键值:相当于人的身份证号。我往往写的较简洁,注意身份证号是不能与别人冲突的。
SNMP OID:读取数据的命令,可在厂商给的mib文档中搜索到。在创建监控项前可以先远程登陆zabbix server,利用如下命令:snmpwalk -v 1或2c(代表SNMP版本) -c SNMP密码(默认为public) IP地址 OID(对象标识符)对被监控对象进行数据读取的测试。测试时需要关注的有三点:数据是否正确;数据的输出形式;OID的索引。
信息类型:经过snmp命令测试,可以看到system description以字符的形式输出,因此选择字符。
更新间隔:监控项多久更新一次,我理解为多久读取一次数据。
后面的几项暂不介绍,ZX ly模板制作过程中并没有用到。创建完监控项后需要做预处理(相当于zabbix server通过snmp oid读取到数据后,我们把它截下来,然后做一些运算转换,再返还给zabbix前端)。对于system description,它显然是一个不会改变的值,因此这里选择“丢弃检测周期内未变化的值”。
对于system name,操作完全相同,这里按下不表。
二、operational status和speed
一中介绍的两类监控项,是针对olt的监控,只有一个对象,因此没有索引。而对于端口运行状态和端口当前带宽的估计值,显然是针对端口而言的。OLT C600的1块板拥有18个槽位,各个槽位又拥有16个端口,每个端口都有唯一对应的一个索引,这时就要用到LLD(低级自动发现)。对于这两项,我事实上完全照搬官方模板Template Module Interfaces SNMP。我们这里就拿着它看即可。
LLD最重要的概念是:循环遍历。举个例子,我们先远程登陆zabbix server,利用snmpwalk,OID设置为ifname对应的oid(当然也可以以ifname代替又臭又长的oid,这是因为ifname命令是通用的,可以被识别,如果是一些厂商特定的命令则必须输入oid)。结果如下所示:


在自动发现规则中的SNMP OID一栏,我们模仿官方模板的格式,可以创建类似于{#IFNAME}等等循环遍历宏,它们的用处在于能够自动替换为我们读取出的数据。比如你在自动发现规则下创建监控项原型Interface {#IFNAME},它会转化为多个监控项,例如Interface epon_olt-1/1/1,Interface epon_olt-1/1/2……取决于你利用ifname读取到的数据。同理我们也可以利用其他各种命令及它们对应的oid创建循环遍历宏,对于索引的循环遍历,一种最常用的方法是{#SNMPINDEX},这是zabbix内置的循环遍历宏。当然我们也完全可以创建{#IFINDEX}得到索引的遍历循环,这是因为厂商的mib文档告诉我们C600 mib接口的一级索引是标准ifmib中定义的ifindex,因此通过ifindex我们完全可以得到接口的遍历循环输出。
其余部分与一相同,这里按下不表。需要注意的是需要把官方模板的ifspeed改为ifhighspeed,读取到的数据是M
bp
s,因此把单位bps改为Mbps。operational status的触发器先不在这边讲,可以直接照搬官方模板。
三、端口收发流量
olt需要监控流量的端口主要是上联xgei口和下联pon口,我们查看mib文档可以发现ifHcIn/OutOctets均用于监控上联xgei口。但是利用snmpwalk测试时,它却会显示对所有上下联端口的监控,并且下联pon口读取的数据显然不正确。这里需要利用过滤器和正则表达式。我们找到官方模板的宏,克隆{$NET.IF.IFNAME.NOT_MATCHES}并改名,在值的最后添加一行|^\s?xgei-[0-9/]*$。^,$表示开头和结尾,\s表示空格,?表示0个或1个,xgei-[0-9/]*匹配所有的xgei口(很多人都会忘记这个\s?,我也是经过很多次ifname的测试,才发现有些olt输出的端口名称前还有个空格)。这样就能匹配上所有的xgei,再将自动发现规则的{$NET.IF.IFNAME.NOT_MATCHES}改为我们创建的宏即可。注意这是第二个自动发现规则,我将其命名为Network interfaces discovery_epon,对于二中介绍的两个监控项我们还是需要同时上下联的。其余一样操作,值得注意的是我们采集的数据是经过端口的字节总数。既然要监控端口流量,我们肯定希望它输出为bps,因此需要利用预处理的每秒更改,才能实现ps的效果,利用自定义倍数8,把B换成b。
对于pon口流量,我则陷入了巨大的困难,这是因为ZX OLT C600对epon、10g epon两个通道的流量数据分别采集的,也就是说,一个端口,两个通道,两个索引,这两个索引都是136开头的,与ifindex不符。事实上如果我直接利用{#SNMPINDEX}读取ifindex索引,虽然是285开头的,但是却能匹配上136索引开头的10g epon,只不过对epon就无能为力了。因此我只能一条一条写,一共写了18*16*6=1728条。*6是因为单通道收发两条,两个通道就是四条,再算上收求和,发求和,就是六条。求和的方法是利用“可计算的”类型监控项,这里的公式写法与触发器表达式如出一辙。因为是一条一条写的,就没有用到LLD,直接写在监控项。这样做可以实现监控pon口流量的功能,但是劣势有三:一、耗费的时间极其巨大;二、很多根本没有流量的端口也会被不断地读取,绘图,导致zabbix前端卡顿;三、很难为它写触发器。对于SNMP代理类型的监控项,我只能想到利用{#SNMPINDEX}作端口的循环遍历,因此无可奈何。
四、光模块发光功率
与三一样,利用{#SNMPINDEX}只能读取10G epon通道的索引。但是我监控光模块出发点就是希望它报警,因此不可能像端口收发流量一样一个个写,只能说舍弃epon通道了。写监控项的过程和三一样,按下不表。注意读取的数据单位是0.001,因此需要预处理自定义倍数。这里就要用到触发器了,写的很简单,就用了last(15m)函数,表示15分钟内收到的最后一个数据。有点画蛇添足加了个恢复表达式(按zabbix官方手册的讲述,不设置恢复表达式的情况下,表达式为false,事件就会恢复)。这样就完成了对10g epon通道光模块的发光功率的监控和告警,保证它在这个波长的发光功率没有问题,至于epon就听天由命了。
五、下联ONU收光功率,下联ONU的Loid
下联ONU就不考虑双通道了,但是又出现了新的问题。第一就是一个pon口下联最多64个ONU,因此需要二级索引,{#SNMPINDEX}能完美匹配pon口的一级索引,但对于二级索引就无可奈何只能一个一个写了,写了64个。第二个问题是读取的数据是string,为了写触发器,我必须把他转换为float,才能进行数值比较,才能得到布尔值。因此利用预处理写了一个很简单的JavaScript:if(value != "N/A"){return(parseFloat(value))}if(value == "N/A"){return null}。此处的value对应的就是我读取的数据,把有数据的,string转float,没有数据的N/A,转null返回。这么做了之后又出现了新的问题,就是我在写触发器的时候,会出现拿null和数字作比较的情况,经测试,这种情况不会输出true或false。总之我的触发器勉强能用,但是在数据变换,true转false之际会出现bug。对于Loid,也是一样写了64个,但是不需要写触发器,所以没问题。还记得文章最开始的第一个预处理吗?“丢弃检测周期内未变化的值”。这里也需要用到它。
全文结束, 模板的功能在文章开篇第一段已经讲过了,这里总结下缺陷。1、为了监控端口流量,写了几千项,导致卡顿。2、对于光模块发光功率,只能监控10g epon通道。3、ONU发光功率的告警没问题,但应当恢复的时候恢复不起来。三个缺陷的原因全都是不会利用自动遍历宏读取ifindex以外的索引,希望大佬解惑。