谢海鹏
浪潮软件集团,运营商事业本部湖南中心运维工程师
于2019年8月接触Zabbix,已为湖南移动项目搭建一个400台主机的Zabbix环境,利用Zabbix的Web场景监控、自定义脚本+自动发现功能等实现了若干业务上的自动监控与自动处理,给运维工作带来了极大的效率提升与便捷。
背景
联机指令平台网元自动登录,通过telnet或ssh协议连接网元,按特定方式输入用户或密码或登录指令登录网元,登录后可发送相关指令获取如CPU使用率等报文或通过ADD,MOD等指令对配置数据进行修改更新,从而实现对设备配置的批量化、自动化。
由于网元自动登录因网络、用户名密码不正确、密码过期、超过最大连接数等原因会有登录不上的情况,为了保障网元登录的连通性,需要对网元自动登录进行常规检查,发现登录异常需要通知相关人员进行处理,以恢复连通性。
以下是本文的思维导图,供大家参考。
01 - 需求分析
常规的检查方法是手工登录测试检查,当前核心网接入设备数量为700+,每天人工检查每一个网元需要耗费大量时间,并且很难做到一天多次检查。所以急需实现网元自动登录检查连通性的自动化。
失败原因分析
1、网元IP ping不通;或IP能ping通,但是ssh或telnet端口不通(网络连接超时)。
2、网络通畅时的登录问题:密码错误,帐号锁定,密码过期,用户被用户admin禁用,超出网元最大连接数等。
02 - 人工检查
为什么要人工登录检查?当自动登录有问题时,需要了解问题出在哪里,找到失败原因通知相关人员进行处理。
或新网元入网时配置规则时,需要先人工登录之了解整个登录过程,再给此类新入网的网元配置登录规则,方可实现网元的自动登录。
一、查询网元信息
--查询网元信息
SELECT
a.ch_name,d.en_name as netype,f.en_name as en_city,e.en_name as nevendor,b.equipe_ip,b.port,c.user_name,c.password
,case g.role_id when 3 then 'root' else 'tszc' end as role,CASE b.description WHEN 'SSH2' THEN 'ssh' ELSE 'telnet' END AS dlxy
,case b.description WHEN 'SSH2' THEN 'ssh -p '||b.port||' '||c.user_name||'@'||b.equipe_ip else 'telnet '||b.equipe_ip||' '||b.port end as cmd,
f.ch_name as ch_city,b.max_connection as rversion
FROM
tbl_xxxx_bisic a,tbl_xxxx_address b,tbl_xxxx_user c,tbl_xxxx_dictionary d,tbl_xxxx_dictionary e,tbl_xxxx_dictionary f,tbl_xxxx_user g
WHERE
a.entity_id = b.equipe_id
and a.entity_id = b.equipe_id
AND b.entity_id = c.equipe_address_id
AND g.equipe_id = b.equipe_id
AND c.entity_id = g.port_user_id
AND d.entity_id = a.equipe_type_id AND e.entity_id = a.supplier_id AND f.entity_id = a.city_id
--按网元类型
AND d.en_name in('DNS') AND e.en_name in ('HW')
二、对密码进行解密
因为数据库中存放的密码为DES加密的密文,实际登录时程序会将密文解密,然后再用解密的明文进行登录,手工登录测试自然也要先解密密码才能正常登录
1、 连接服务器1x.xxx.xxx.134,以tmn用户登录
2、cd /xx/xxx/xxxhp/ddes
3、执行解密小程序对密文进行解密,获取到对应明文
[tmn@necpproxy1 ddes]$ ./ddes 5F3D63C8A82FEDDF
xxxxxxxx
三、登录测试
1、同样连接服务器1x.xxx.xxx.134,以tmn用户登录
2、此类华为DNS网元连通协议为ssh,使用查询出来的cmd指令连接网元
[tmn@necpproxy1 ~]$ ssh -p 22 xxxj@10.xxx.xxx.74
Password:
Last login: Wed Jul 1 16:36:00 2020 from 1x.xxx.xxx.134
Authorized users only. All activity may be monitored and reported
xxxj@CXXXX09BXX:~>
3、以上如返回期待的xxxj@CXXXX09BXX:~>字符,表示登录成功,这些登录规则被配置到了联机指令的登录规则文件中,自动登录时读取这些规则实现不同网元厂商、类型、版本的自动登录。
4、退出登录,每次成功登录网元后需要输入退出指令将连接断开,否则会造成连接数浪费。
登录规则配置文件
FTP::1x.xxx.xxx.134-tmn\//xx/xxx/XXD/bin|nelogin_rule.cfg
如上图配置的退出指令为exit回车换行,执行exit退出网元登录
xxxj@CXXXX09BXX:~> exit
logout
Connection to 10.xxx.xxx.74 closed.
如上是ssh协议手工登录的一个示例,基本上是纯手工进行测试
1、连接指令cmd需要从查询的数据中进行复制,然后粘贴到CRT中
2、数据库中存放的密文需要使用解密小程序进行解密,然后才能正常登录
3、登录规则及退出指令需要从登录规则配置文件中找到并复制使用
以上操作过程即便是熟练也要用约30秒到一分钟完成
假如700个网元全部需要检查一次,则需要花费至少350分钟,也就是近6个小时。并且这个ssh登录是相对来说最简单的登录规则,telnet还有较为复杂的登录规则,那样需要花费的时间就更多。
03 - 半自动检查?
1、给出网元名称,能查询到网元的信息,自动执行连接指令
2、自动打印规则,将规则呈现在同一屏幕,避免多窗口切换的麻烦
实现:
从联机指令代理程序nxxx_xxxxx_ssh程序中将获取登录规则的代码片断编写成小程序,可以在服务器上运行获取登录规则,并打印到屏幕上,测试时只需要复制粘贴执行即可。
小程序名称为neloginrule
使用方法:neloginrule CXXXX09BXX root
CXXXX09BXX为网元名称,root为联机指令平台的用户名,当前root用于普通登录,tszc用户用于投诉用户的登录。
示例:
[tmn@necpproxy1 bin]$ neloginrule CXXXX09BXX root
SELECT entity_id,version,equipe_type_id,supplier_id FROM tbl_xxxx_bisic where en_name='CXXXX09BXX';
SELECT en_name from tbl_xxxxnary where entity_id=26;
SELECT en_name from tbl_xxxxnary where entity_id=66;
select b.equipe_ip,b.port,c.user_name,c.password from tbl_role_xxxxuser a,tbl_xxxxress b,tbl_xxxx_user c where a.role_id=3 and a.equipe_id=72984 and a.equipe_address_id=b.entity_id and a.port_user_id=c.entity_id;
========= ne information ==========
name = CXXXX09BXX
type = DNS
vendor = HW
version = 3
username = xxxj
password = Xxxxxxxx
ip = 10.xxx.xxx.74
port = 22
========= auto login rules information ==========
index = 0 status = 1 nextstep = 0 recvmsg = ~>
exitcmd =
exit
ne information部分为网元信息,包含网元名称、网元类型、厂商、规则版本、用户名、密码(已用ddes解密)、IP地址、端口号
auto login rules information部分为登录规则,此华为DNS网元登录规则特别简单,只有一步,输入用户名密码后recevmsg返回~>即代表登录成功。
3、半自动测试脚本
#!/usr/bin/sh
#set +x
if [ $# -lt 1 ]
then
echo "cp: Insufficient arguments ($#)"
echo "Usage: $0 nename or $0 nename username"
exit 1
fi
if [ $# -eq 1 ]
then
neloginrule $1 root
else
neloginrule $1 $2
fi
nename=`cat ./telnet/nename.tel`
chmod +x $nename
cat $nename
echo ''
$nename
4、测试实例
[tmn@necpproxy1 bin]$ telnet.sh XXL3
SELECT entity_id,version,equipe_type_id,supplier_id FROM tbl_xxxx_bisic where en_name='XXL3';
SELECT en_name from tbl_xxxxnary where entity_id=43;
SELECT en_name from tbl_xxxxnary where entity_id=44;
select b.equipe_ip,b.port,c.user_name,c.password from tbl_xxxx_port_user a,tbl_xxxx_address b,tbl_xxxx_user c where a.role_id=3 and a.equipe_id=332291 and a.equipe_address_id=b.entity_id and a.port_user_id=c.entity_id;
========= ne information ==========
name = XXL3
type = LSTP
vendor = ALCATEL
version = 23
username = xxxxj
password = Xxxxxxxx
ip = 10.xxx.xxx.70
port = 23
========= auto login rules information ==========
index = 0 status = 0 nextstep = 1 recvmsg = ogin:
sendmsg =
xxxxj
index = 1 status = 0 nextstep = 2 recvmsg = assword:
sendmsg =
Xxxxxxxx
index = 2 status = 0 nextstep = 3 recvmsg =
sendmsg =
smv
index = 3 status = 0 nextstep = 4 recvmsg = >
sendmsg =
sgcmd
index = 4 status = 0 nextstep = 5 recvmsg = Userid:
sendmsg =
xxxxjzz
index = 5 status = 0 nextstep = 6 recvmsg = Password:
sendmsg =
Xxxxxxxx
index = 6 status = 0 nextstep = 7 recvmsg = >
sendmsg =
MM
index = 7 status = 0 nextstep = 8 recvmsg = >MM
sendmsg =
index = 8 status = 1 nextstep = 0 recvmsg = <
exitcmd =
exit
exit
exit
telnet 10.xxx.xxx.70 23
Trying 10.xxx.xxx.70...
Connected to 10.xxx.xxx.70.
Escape character is '^]'.
Linux 2.6.32-504.12.2.el6.x86_64 (oamce-2a) (09:14 on Thursday, 02 July 2020)
login: xxxxj
Password:
Last login: Thu Jul 2 08:31:27 from 1x.xxx.xxx.134
***************************************
OAM XXL3 105_0872D01.3.8 oamce-2
***************************************
***This session is being logged***
xxxxj@oamce-2:~$smv
**************************************************
Welcome to the A1000 S12 System Management View!
**************************************************
XXL3:XXXXXXGR-1-B:/home/xxxxj>sgcmd
Registering to GUIServer ......
Userid: xxxxjzz
Password:
Done!
>MM
XXL3 2020-07-02 09:14:32 Thu
<exit
Terminated
XXL3:XXXXXXGR-1-B:/home/xxxxj>exit
exit
xxxxj@oamce-2:~$exit
logout
Connection closed by foreign host.
[tmn@necpproxy1 bin]$
此测试实例已实现半自动化,
1、自动生成连接指令,自动执行连接指令
2、打印网元信息,自动登录规则以及解密的密码明文
3、操作时,只需要按打印的登录规则一步一步执行
节省了查询设备信息、解密密文密码、查找登录规则等耗时而繁琐的操作。
但仍然不够智能,仍需要大量工人介入。
04 - 全自动化
需要解决的问题:
1、查询所有需要检查的网元名称等信息,用以触发每个网元的检查
2、定时执行所有网元的检查
3、改造联机指令平台代理程序nxxx_xxxxx_ssh使自动登录失败时能返回具体失败原因码
4、遇到问题时及时通过短信等方式通知到相关人员
实现步骤
改造联机指令平台,使用开源监控方案zabbix系统+自定义脚本进行自动监控
一、改造联机指令平台
改造联机指令平台,使得网元登录失败时能返回失败码,从而得知失败的具体原因
-1 ? 连接被拒绝
-10 ? 其他&用户锁定The user is locked.
-30 ? 网络连接超时
-40 ? 超出网元最大连接数
-50 ? 帐号或密码错误
-60 ? 此用户被用户admin禁用
-70 ? 密码已过期
1 ? 登录成功
代码片段
执行示例:
[tmn@necpproxy1 ~]$ /xx/xxx/xxxhp/necp_login_test/getfile_proxy -nename APP-HXXXXX-XXXXX012 -username root
会话号:
输出信息:TimePoint:2020-07-02 10:21:05 PID 90643 APP-HXXXXX-XXXXX012 登录网元失败!失败码:-30
二、获取网元信息
使用Zabbix系统的自动发现功能,编写自定义脚本查询需要检查的网元信息,生成json格式报文,Zabbix配置自动发现规则,实现退网入网时删除和新增的网元自动添加网元的监控项。
自定义脚本:check_nename.sh
#!/bin/bash
tstr=`date '+%y%m%d%H%M'`
. /u1/tmn/nechk/nechk.env
if [ $# -lt 2 ]
then
echo "cp: Insufficient arguments ($#)"
echo "Usage: sh $0 object_type vendor_type"
exit 1
fi
BIN_DIR=/xx/xxx/xxxhp/necp_login_test
DOC_DIR=${BIN_DIR}/doc
CFG_FILE=${DOC_DIR}/$1_$2_${tstr}.unl
if [ $2 = "ALL" ];
then
if [ $1 = "ALL" ];
then
#wherec="AND d.en_name in('MSC','MME','PGW','FW','GMSC','TMSC','HSS_BE','HSS_UMM','HSS_FE')"
wherec="AND d.en_name in('AGCF','CG','CL','CSCF','DNS','DRA','EDS','EMSC','FW','GMGW','GMSC','GWU','HSS_BE','HSS_FE','HSS_UMM','HSTP','IBCF','IMSCG','LSTP','MGCF','MGW','MME','MSC','NPHSS','NPMSC','PCRF','PGW','SBC','SPR','SW','TAS','TMSC','VC','vCG','vGWC','vMME','vPCRF')"
else
wherec="AND d.en_name in('$1')"
fi
else
wherec="AND d.en_name in('$1') AND e.en_name in ('$2');"
fi
#导出网元需要测试登录的网元信息,按网元厂商及设备类型
dbaccess >/dev/null 1>/dev/null 2>&1 << !
database $DB_UNI;
unload to ${CFG_FILE}
SELECT
a.ch_name,case g.role_id when 3 then 'root' else 'tszc' end as role,e.en_name,c.user_name,d.en_name,b.equipe_ip
FROM
tbl_xxxx_bisic a,tbl_xxxx_address b,tbl_xxxx_user c,tbl_xxxxnary d,tbl_xxxxnary e,tbl_data_dictionary f,tbl_xxxx_user g
WHERE
a.entity_id = b.equipe_id
and a.entity_id = b.equipe_id
AND b.entity_id = c.equipe_address_id
AND g.equipe_id = b.equipe_id
AND c.entity_id = g.port_user_id
AND d.entity_id = a.equipe_type_id AND e.entity_id = a.supplier_id AND f.entity_id = a.city_id
AND not(d.en_name = 'FW' and e.en_name = 'ERICSSON')
AND not(d.en_name = 'MME' and e.en_name = 'HW' and g.role_id = 2)
AND a.version <> '退网'
$wherec;
!
COUNT=`cat ${CFG_FILE} | wc -l`
INDEX=0
echo '{"data":['
cat ${CFG_FILE} | while read LINE; do
nename=`echo ${LINE} | awk -F\| '{print $1}'`
rolename=`echo ${LINE} | awk -F\| '{print $2}'`
supplier=`echo ${LINE} | awk -F\| '{print $3}'`
username=`echo ${LINE} | awk -F\| '{print $4}'`
netype=`echo ${LINE} | awk -F\| '{print $5}'`
ipaddress=`echo ${LINE} | awk -F\| '{print $6}'`
echo -n '{"{#NENAME}":"'${nename}'","{#ROLENAME}":"'${rolename}'","{#USERNAME}":"'${username}'","{#SUPPLIER}":"'${supplier}'","{#NETYPE}":"'${netype}'","{#IPADDR}":"'${ipaddress}'"}'
INDEX=`expr $INDEX + 1`
if [ $INDEX -lt $COUNT ]; then
echo ','
fi
done
echo ']}'
find /xx/xxx/xxxhp/necp_login_test/doc -type f -mtime +7 -exec rm -f {} \;
此脚本执行后获取内容为:
[tmn@necpproxy1 ~]$ /xx/xxx/xxxhp/necp_login_test/check_nename.sh TAS ZTE
{"data":[
{"{#NENAME}":"CXXXXXXXXS7BXX","{#ROLENAME}":"root","{#USERNAME}":"TSZC","{#SUPPLIER}":"ZTE","{#NETYPE}":"TAS","{#IPADDR}":"1x.xxx.232.76"},
{"{#NENAME}":"CXXXXXXXXS5BXX","{#ROLENAME}":"root","{#USERNAME}":"TSZC","{#SUPPLIER}":"ZTE","{#NETYPE}":"TAS","{#IPADDR}":"1x.xxx.130.12"},
{"{#NENAME}":"CXXXXXXXXS4BXX","{#ROLENAME}":"root","{#USERNAME}":"TSZC","{#SUPPLIER}":"ZTE","{#NETYPE}":"TAS","{#IPADDR}":"1x.xxx.227.235"},
{"{#NENAME}":"CXXXXXXXXS9BXX","{#ROLENAME}":"root","{#USERNAME}":"TSZC","{#SUPPLIER}":"ZTE","{#NETYPE}":"TAS","{#IPADDR}":"1x.xxx.191.108"},
{"{#NENAME}":"CXXXXXXXXS6BXX","{#ROLENAME}":"root","{#USERNAME}":"TSZC","{#SUPPLIER}":"ZTE","{#NETYPE}":"TAS","{#IPADDR}":"1x.xxx.191.12"},
{"{#NENAME}":"CXXXXXXXXS8BXX","{#ROLENAME}":"root","{#USERNAME}":"TSZC","{#SUPPLIER}":"ZTE","{#NETYPE}":"TAS","{#IPADDR}":"1x.xxx.130.76"}]}
TAS为网元类型,ZTE为设备厂商
执行后返回json格式的网元信息,依次包含网元名称、角色、用户名、厂商、设备类型、IP地址
在zabbix_agent配置文件/usr/local/etc/zabbix_agentd.conf中添加自定义脚本
### Option: UserParameter
# User-defined parameter to monitor. There can be several user-defined parameters.
# Format: UserParameter=<key>,<shell command>
# See 'zabbix_agentd' directory for examples.
#
# Mandatory: no
# Default:
# UserParameter=
UserParameter=nename.discovery[*],/xx/xxx/xxxhp/necp_login_test/check_nename.sh $1 $2
UserParameter=ne.login[*],/xx/xxx/xxxhp/necp_login_test/check_nelogin.sh $1 $2
nename.discovery[*]为zabbix配置调用格式,check_nename.sh 1 2 中1 2为指定设备类型及厂商的两个参数。
ne.login[*],/xx/xxx/xxxhp/necp_login_test/check_nelogin.sh 1 2为登录检测脚本。
修改配置后执行systemctl restart zabbix_agentd.service重启zabbix_agent客户端
三、登录检测脚本
登录检测脚本 check_nelogin.sh
#!/bin/bash
tstr=`date '+%y%m%d%H%M'`
. /u1/tmn/nechk/nechk.env
if [ $# -lt 2 ]
then
echo "cp: Insufficient arguments ($#)"
echo "Usage: sh $0 nename role"
exit 1
fi
DOC_DIR=/xx/xxx/xxxhp/necp_login_test/doc
resultfile=${DOC_DIR}/$1_$2_${tstr}.unl
/xx/xxx/xxxhp/necp_login_test/getfile_proxy -nename $1 -username $2 > ${resultfile}
#echo `/xx/xxx/xxxhp/necp_login_test/getfile_proxy -nename $1 -username $2 | grep '网元登陆完毕' | wc -l`
success=`cat ${resultfile} | grep '网元登陆完毕' | wc -l`
if [ ${success} -eq 1 ]; then
echo ${success}
else
failcode=`cat ${resultfile} | awk '{if(NF==6)print $6}' | awk -F: '{print $2}'`
echo ${failcode}
fi
执行示例:
[tmn@necpproxy1 ~]$ /xx/xxx/xxxhp/necp_login_test/check_nelogin.sh CSGS1 root
1
如上执行成功返回1
[tmn@necpproxy1 ~]$ /xx/xxx/xxxhp/necp_login_test/check_nelogin.sh APP-HXXXXX-XXXXX012 root
-30
如上执行失败返回失败码-30 为网络连接超时
[tmn@necpproxy1 ~]$ /xx/xxx/xxxhp/necp_login_test/check_nelogin.sh XXXXX16BXX root
-40
如上执行失败返回失败码-40 为超出网元最大连接数
四、监控nxxx_xxxxx_ssh采集代理程序
目前部署了6套程序,区分业务,以防止单个代理程序出问题时影响其他业务的使用
通过zabbix内置端口监控来监控端口运行状态,如果端口不在监听状态,则重启代理程序。
1、配置监控项
2、配置触发器
3、配置触发器动作
使触发器动作能正常执行还得执行如下操作
root用户执行visudo添加如下配置,意为zabbix用户可免密码sudo执行其他用户下的脚本
%zabbix ALL=(ALL) NOPASSWD: ALL
启动脚本:
FTP::1x.xxx.xxx.134-tmn\//xx/xxx/XXD/ir|start.sh
#!/usr/bin/bash
. /u1/tmn/.bash_profile
ps -ef | grep -w nxxx_xxxxx_ssh_ir | grep -v grep | awk '{print "kill -9 "$2}' | sh
su tmn -c 'cd /xx/xxx/XXD/ir; ./nxxx_xxxxx_ssh_ir &'
如果触发动作后提示Remote commands are not enabled.则需要如下操作开启远程脚本
vi /usr/local/etc/zabbix_agentd.conf
EnableRemoteCommands=1
然后再执行如下命令重启zabbix_agent
systemctl restart zabbix_agentd.service
监控日志,当日志中出现错误信息,有明显提示代表采集代理不可用时,可自动重启代理程序,以确保程序的可用性。
1、配置监控项
2、配置触发器
3、配置触发器动作
同端口监控中的动作
两个触发器任何一个触发均执行重启动作。
五、zabbix配置自动发现
1、创建一个模板 Necp_proxy nelogin test
2、配置自动发现规则 此处网元类型及厂商配置的ALL,ALL
其中更新间隔为每两小时执行一次,用于发现新增的网元,或取消退网网元的监控项。
3、配置映射值
配置映射值的目的是为了使返回的失败码呈现真实的失败原因
4、配置监控原型
名称:
Nelogin test {#NENAME} IP {#IPADDR} of {#SUPPLIER} {#NETYPE} for role {#ROLENAME} by {#USERNAME}
监控项名称,呈现较多信息,网元名称、IP地址、厂商、网元类型、角色名称、网元登录时使用的用户名
键值:
ne.login[{#NENAME},{#ROLENAME}]
键值用于向zabbix客户端发送检查请求,请求参数为网元名称和角色名称,分别对应check_nelogin.sh XXXXX16BXX root中的XXXXX16BXX和root两个参数。
更新间隔:
每2小时检查一次登录情况,以尽早的发现网元登录失败。
5、配置触发器
名称:
失败原因:{ITEM.VALUE} {#NENAME} IP {#IPADDR} of {#SUPPLIER} {#NETYPE} for role {#ROLENAME} by {#USERNAME} login failed
其中{ITEM.VALUE}为实际返回的失败原因,后面是此网元的基本信息,方便问题处理人知晓具体的网元信息。
以上配置了两个依赖关系,就是当采集代理正常时才让这些触发器工作,因为采集代理出问题时,网元肯定是连不上的,采集代理出问题了,有采集代理的触发器及动作完成自动处理及通知。
6、给主机添加模板
配置了自动发现的模板后,需要将模板配置到主机上
可对自动发现规则执行测试或立即执行来测试自动规则的可用性
05 - 自动化效果
一、网元自动登录检查
仪表盘中可查看返回的失败原因
通知到的人员
收到的短信通知
以往收到的已解决短信
二、nxxx_xxxxx_ssh采集代理程序监控
历史问题
过程如下:
2020-06-29 19:14:52发现问题
2020-06-29 19:14:56发送短信
2020-06-29 19:15:01执行远程命令重启代理程序
2020-06-29 19:15:52监控到问题已解决
2020-06-29 19:15:55发送已解决短信通知
06 - 结语
很大程度上解决了人力耗费问题,检查过程几乎不需要人工干预,效率提升90%以上。
目前zabbix监控已可监测网元登录失败原因,另外还有IP地址,厂商,网元类型,用户名,目前短信发送到浪潮运维人员手机上,还可以配置发送到各域负责人、包机人、及对应厂商人员手机上。
前期需要收集接收者的手机号,我要将用户信息配置到系统中,然后再针对不同网元发到不同人进行配置。
目前已对789个网元+网元登录用户粒度 进行了监控。
07 - 功能升级
实际检查过程中,可能会因为网络闪断等原因造成的偶尔登录不上的情况,所以每隔6小时检查一次可能检查结果不是100%正确。
使用自动发现,发现了900+的监控项,每6小时执行一次,发现有问题时触发器触发动作发送短信告警。此监控结果存在偶发性问题的情况,想让监控到问题时,再5分钟内再自动调度执行一次,这个有办法吗?然后再依据前两次的结果都为失败才发短信告警。
我建议这个灵活确认异常机制应该添加到zabbix系统中去,应该有不少这种场景吧,正常大粒度巡检,有异常时小粒度多次确认。
Zabbix开源社区3群里有人建议用api调用checknow实现
通过观察后,在前台使用立即检查(checknow)功能后,实际上是往task及task_check_now表中插入数据,zabbix会调用执行立即检查。
知道之个之后,先通过problem表找到items这两个表的关联
select * from problem a left join triggers b on a.objectid = b.triggerid left join functions c on b.triggerid = c.triggerid left join items d on c.itemid = d.itemid
再关联历史表等查询问题监控项ID,直接往TASK及TASK_CHECK_NOW表中插入原始数据,用于更新实现立即检查
--往TASK及TASK_CHECK_NOW表中插入原始数据,用于更新实现立即检查
INSERT INTO TASK(TASKID, TYPE, STATUS , CLOCK, TTL)
SELECT ITEMID - 110000 AS TASKID,6 AS TYPE, 3 AS STATUS, 1596071602 AS CLOCK, 3600 AS TTL FROM ITEMS
WHERE HOSTID = 10737 AND NOT EXISTS ( SELECT 1 FROM TASK WHERE ITEMS.ITEMID - 110000 = TASK.TASKID)
INSERT INTO TASK_CHECK_NOW
SELECT ITEMID - 110000 AS TASKID,ITEMID FROM ITEMS
WHERE HOSTID = 10737 AND NOT EXISTS ( SELECT 1 FROM TASK_CHECK_NOW WHERE ITEMS.ITEMID - 110000 = TASK_CHECK_NOW.TASKID)
--查询问题中6小时内检查次数未超过3次的itemid
select d.itemid
from problem a left join triggers b on a.objectid = b.triggerid
left join functions c on b.triggerid = c.triggerid
left join items d on c.itemid = d.itemid
left join (select f.itemid,max(e.clock) as clock
from task e left join task_check_now f on e.taskid = f.taskid
where f.itemid is not null
group by f.itemid) e on d.itemid = e.itemid
left join history f on d.itemid = f.itemid
where d.hostid = 10737 and r_eventid is null
and f.clock >= UNIX_TIMESTAMP(now()) - 60*60*6 + 1
group by d.itemid having count(*) < 3
--更新状态及时间实现立即检查调度
update task set clock = (select max(clock)+ 60*5 from history where itemid = taskid +110000),status = 1
where taskid in (select itemid-110000 from task_check_now where itemid in (
select d.itemid
from problem a left join triggers b on a.objectid = b.triggerid
left join functions c on b.triggerid = c.triggerid
left join items d on c.itemid = d.itemid
left join (select f.itemid,max(e.clock) as clock
from task e left join task_check_now f on e.taskid = f.taskid
where f.itemid is not null
group by f.itemid) e on d.itemid = e.itemid
left join history f on d.itemid = f.itemid
where d.hostid = 10737 and r_eventid is null
and f.clock >= UNIX_TIMESTAMP(now()) - 60*60*6 + 1
group by d.itemid having count(*) < 3))
crontab定时任务执行更新脚本
FTP::10.xxx.xx.xxx-zabbix\//home/zabbix/********|rechek_nelogin.sh
#!/bin/bash
. /home/zabbix/.bash_profile
mysql -u zabbix -p'********' << EOF >/dev/null 2>&1
use zabbix
begin;
update task set clock = (select max(clock)+ 60*5 from history where itemid = taskid +110000),status = 1
where taskid in (select itemid-110000 from task_check_now where itemid in (
select d.itemid
from problem a left join triggers b on a.objectid = b.triggerid
left join functions c on b.triggerid = c.triggerid
left join items d on c.itemid = d.itemid
left join (select f.itemid,max(e.clock) as clock
from task e left join task_check_now f on e.taskid = f.taskid
where f.itemid is not null
group by f.itemid) e on d.itemid = e.itemid
left join history f on d.itemid = f.itemid
where d.hostid = 10737 and r_eventid is null
and f.clock >= UNIX_TIMESTAMP(now()) - 60*60*6 + 1
group by d.itemid having count(*) < 3));
commit;
EOF
echo $?
通过以上方式实现 正常大粒度巡检,有异常时小粒度多次确认后执行结果
至于发送短信告警,直接用首次检查异常的发送即可,如果后面两次确认检查正常了,会发送已解决短信,未恢复的话,就一直是问题状态,不需要重新配置触发器。