相信大家在网上应该看到很多类似的东东,本文主要是整理总结下,并使用python脚本来实现,为什么要使用python,后面会说原因,当然要实现批量添加监控还是要用到zabbix的Discovery功能来实现,所以我们的脚本关键是要采集并返回指定格式的数据。下面来一步步走吧:
一、Zabbix批量监控WEB网站
1、编写python脚本
这个需求在生立环境中应该说用得太普遍了,如果你生产环境有成百上千个网站,你应该不会笨到一个一个去添加监控吧,zabbix已经提供了这个实现。首先当然是编写python脚本,脚本中有两个函数,web_site_discovery函数主要是用于返回zabbix创建监控所需要的数据,web_site_code函数主要用于判断返回码,脚本如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
#!/usr/bin/env python
#coding:utf-8
import
os,sys,json
#将要监控的web站点url添加到urllist列表
urllist
=
[
"http://baidu.com"
,
"http://www.qq.com"
,
"http://www.sina.com.cn/"
]
#这个函数主要是构造出一个特定格式的字典,用于zabbix
def
web_site_discovery():
web_list
=
[]
web_dict
=
{
"data"
:
None
}
for
url
in
urllist:
url_dict
=
{}
url_dict[
"{#SITENAME}"
]
=
url
web_list.append(url_dict)
web_dict[
"data"
]
=
web_list
jsonStr
=
json.dumps(web_dict, sort_keys
=
True
, indent
=
4
)
return
jsonStr
#这个函数用于测试站点返回的状态码,注意在cmd命令中如果有%{}这种字符要使用占位符代替,否则
#会报错
def
web_site_code():
cmd
=
'curl -o /dev/null -s -w %s %s'
%
(
"%{http_code}"
,sys.argv[
2
])
reply_code
=
os.popen(cmd).readlines()[
0
]
return
reply_code
if
__name__
=
=
"__main__"
:
try
:
if
sys.argv[
1
]
=
=
"web_site_discovery"
:
print
web_site_discovery()
elif
sys.argv[
1
]
=
=
"web_site_code"
:
print
web_site_code()
else
:
print
"Pls sys.argv[0] web_site_discovery | web_site_code[URL]"
except
Exception as msg:
print
msg
#这里对脚本传递进来的第一个参数做判断去执行不同的函数,为什么要这样,因为通过一个脚本写了两个功能
|
2、修改代理配置文件
然后在zabbix-server所在的主机的代理配置文件中zabbix_agentd.conf添加如下行:
1
2
3
|
UnsafeUserParameters
=
1
UserParameter
=
web_site_discovery,
/
etc
/
zabbix
/
scripts
/
web_site_moniter.py web_site_discovery
UserParameter
=
web_site_code[
*
],
/
etc
/
zabbix
/
scripts
/
web_site_moniter.py web_site_code $
1
|
这里要解释下,此处command使用同一个脚本,但又是不同的功能,因此通过传递第一个参数来区分不同的功能,怎么区分见脚本,然后web_site_code[*]这个key是一个弹性key,也就是可以向key传参数的,它传了一个参数做为脚本的第二个参数,显然是具体的站点url,做这个配置目的是添加key,格式如下:
1
|
UserParameter
=
key,command
|
key与command之间有逗号,command可以直接写命令,也可以写脚本,如果是脚本则command是脚本路径,zabbix提供了弹性key,也就是key[*],这个非常棒,可以是任意个参数,当然按位置传递参数,如下例子:
1
|
UserParameter
=
mysql.ping[
*
],mysqladmin –u$
1
–p$
2
ping|grep alive|wc –l
|
测试:
1
|
zabbix_get
-
s
127.0
.
0.1
-
p
10050
-
k mysql.ping[root,
123456
]
|
$1,$2表示分别要传递第一个和第二个参数,此处第一个是用户名,第二个为密码
3、测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#zabbix_get -s 192.168.153.110 -p 10050 -k web_site_discovery
{
"data"
: [
{
"{#SITENAME}"
:
"http://baidu.com"
},
{
"{#SITENAME}"
:
"http://www.qq.com"
},
{
"{#SITENAME}"
:
"http://www.sina.com.cn/"
}
]
}
|
这个字典格式是zabbix discovery要求的
1
2
|
# zabbix_get -s 192.168.153.110 -p 10050 -k web_site_code[http://baidu.com]
200
|
4、zabbix页面配置
创建模板
创建discovery rule,同时添加filter规则,这里的key要和zabbix_agentd.conf文件中的一致
添加item prototype,这里的key要和zabbix_agentd.conf文件中的一致,这里传递的参数是获取的站点utl值
添加trigger prototype,这里需要说明的是触发器的表达式,last(0)表示最近一次的值如果>399则触发报警。添加完后的结果如下:
二、Zabbix批量监控主机端口
1、编写python脚本
其实原理和监控web差不多,先要从被监控服务器采集需要监控端口的数据,记住是一个特点格式的字典,这也是为什么我们使用python编写脚本的原因,因为python很擅长处理字典类型的对象,如果使用shell,要写一堆格式,很麻烦,python可以让代码变得更简洁,首先看下脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#!/usr/bin/env python
#coding:utf-8
import
os, json
port_list
=
[]
port_dict
=
{
"data"
:
None
}
cmd
=
'''netstat -tnlp|egrep -i "$1"|awk {'print $4'}|awk -F':' '{if ($NF~/^[0-9]*$/) print $NF}'|sort |uniq 2>/dev/null'''
local_ports
=
os.popen(cmd).readlines()
for
port
in
local_ports:
pdict
=
{}
pdict[
"{#TCP_PORT}"
]
=
port.replace(
"\n"
, "")
port_list.append(pdict)
port_dict[
"data"
]
=
port_list
jsonStr
=
json.dumps(port_dict, sort_keys
=
True
, indent
=
4
)
print
jsonStr
|
2、在被监控的服务器修改代理配置文件
这里需要指出的是,只要是被监控端都需要上面的脚本,我也试图只在zabbix服务端实现,但好像有些问题,后面再深入研究下,不过就是把一个文件上传到客户端,也很容易用salt-stack分发下就可以了
在zabbix_agentd.conf增加以下内容:
1
2
|
UnsafeUserParameters
=
1
UserParameter
=
tcpportlisten,
/
etc
/
zabbix
/
scripts
/
check_port.sh
|
3、测试
在zabbix-server端测试下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
#zabbix_get -s 192.168.153.129 -p 10050 -k tcpportlisten
{
"data"
: [
{
"{#TCP_PORT}"
:
"10050"
},
{
"{#TCP_PORT}"
:
"22"
},
{
"{#TCP_PORT}"
:
"25"
},
{
"{#TCP_PORT}"
:
"4505"
},
{
"{#TCP_PORT}"
:
"4506"
},
{
"{#TCP_PORT}"
:
"8080"
},
{
"{#TCP_PORT}"
:
"9000"
}
]
}
|
4、Zabbix页面配置
创建item prototype这里key使用的是zabbix预定义的key,用于判断端口是否存活,如果存活则返回值为1,否则返回值为0
创建trigger prototype,注意这里的表态示count(#3,0,eq) > 1表示最近3次的返回值为0,这个条件触发一次则报警