相信大家在網上應該看到很多類似的東東,本文主要是整理總結下,並使用python腳本來實現,爲什麼要使用python,後面會說原因,當然要實現批量添加監控還是要用到zabbix的Discovery功能來實現,所以我們的腳本關鍵是要採集並返回指定格式的數據。下面來一步步走吧:
一、Zabbix批量監控WEB網站
1、編寫python腳本
這個需求在生立環境中應該說用得太普遍了,如果你生產環境有成百上千個網站,你應該不會笨到一個一個去添加監控吧,zabbix已經提供了這個實現。首先當然是編寫python腳本,腳本中有兩個函數,web_site_discovery函數主要是用於返回zabbix創建監控所需要的數據,web_site_code函數主要用於判斷返回碼,腳本如下:
#!/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添加如下行:
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,格式如下:
UserParameter=key,command
key與command之間有逗號,command可以直接寫命令,也可以寫腳本,如果是腳本則command是腳本路徑,zabbix提供了彈性key,也就是key[*],這個非常棒,可以是任意個參數,當然按位置傳遞參數,如下例子:
UserParameter=mysql.ping[*],mysqladmin –u$1 –p$2 ping|grep alive|wc –l
測試:
zabbix_get -s 127.0.0.1 -p 10050 -k mysql.ping[root,123456]
$1,$2表示分別要傳遞第一個和第二個參數,此處第一個是用戶名,第二個爲密碼
3、測試
#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要求的
# 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可以讓代碼變得更簡潔,首先看下腳本:
#!/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增加以下內容:
UnsafeUserParameters=1 UserParameter=tcpportlisten,/etc/zabbix/scripts/check_port.sh
3、測試
在zabbix-server端測試下:
#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,這個條件觸發一次則報警