基于python3 zabbix api方式,达到批量创建指定机器业务端口的监控项和触发器的创建的效果,目前不支持并发处理,只支持串行处理
zabbix-net-server.py 内容 ,放到zabbix服务器上,然后执行python3 zabbix-net-server.py 启动socket监听
#!/usr/bin/python3
import socket, sys, time
import json
import requests
import pymysql
#当前master监听
host = 'xxxx'
port = 2443
#自定义监控项所在的应用集名称
zabbix_app = "netstat"
#禁止的监控的服务列表,比如sshd,master,ntpd
deny_server = ["sshd", "hblog", "zabbix_agentd", "master", "staragent-core", "DragoonAgent", "filebeat", "agent"]
deny_port = ["32000"]
#触发器告警级别,(0:未分类; 1:信息; 2:警告; 3:一般严重 ...)
trigger_pri = 4
#zabbix服务器的IP地址
zabbix_ip = "10.99.1.240"
#zabbix的用户名
zabbix_user = "xxxx"
#zabbix的密码
zabbix_pass = "xxxx"
#zabbix api接口地址
url = "http://" + zabbix_ip + "/api_jsonrpc.php"
#zabbix api定义的访问头部信息
post_header = {'Content-Type': 'application/json'}
#调用rds查询
def get_hostname(host_ip):
con = pymysql.connect(host='xxxxx.mysql.rds.aliyuncs.com', user='xxxx', password='xxxxxxx', db='heroes',
# 需要这台负载均衡上开下3306透传,访问控制白名单先去掉
charset='utf8')
CURSOR = con.cursor()
sql = "SELECT host_name FROM hosts where host_ip='%s'; " % host_ip
CURSOR.execute(sql)
result = CURSOR.fetchone()[0]
return result
#调用zabbix api需要身份令牌auth
def get_auth():
post_data = {
"jsonrpc": "2.0",
"method": "user.login",
"params": {
"user": zabbix_user,
"password": zabbix_pass
},
"id": "1"
}
ret = requests.post(url, data=json.dumps(post_data), headers=post_header)
zabbix_ret = json.loads(ret.text)
if 'result' not in zabbix_ret:
print('login error')
else:
return zabbix_ret.get('result')
#用于给api提交并提交
def post_info(values, id_name):
zabbix_req = requests.post(url, data=json.dumps(values), headers=post_header)
zabbix_req = zabbix_req.json()
try:
req_error = zabbix_req['error']['data'] #如果获取不到就说明成功了,则返回信息
except:
req_info = zabbix_req['result'][id_name]
return req_info
#以hostname信息获取主机id
def get_hostid(auth, host_ip):
values = {
"jsonrpc": "2.0",
"method": "host.get",
"params": {
"output": "extend",
"filter": {
"host": [host_ip]
}
},
"auth": auth,
"id": 2,
}
zabbix_req = requests.post(url, data=json.dumps(values), headers=post_header)
zabbix_req = zabbix_req.json()
zabbix_req = zabbix_req['result']
try:
host_id = zabbix_req[0]['hostid']
return host_id
except:
return 1
def get_interfaces(auth,host_id):
values = {
"jsonrpc":"2.0",
"method":"host.get",
"params":{
"output":['name','host_id'],
"filter":{
'hostids':[host_id]
},
"selectInterfaces":[
"interfaceid",
"ip"
],
},
"auth":auth,
"id":1
}
zabbix_req = requests.post(url, data=json.dumps(values), headers=post_header)
zabbix_req = zabbix_req.json()
zabbix_req = zabbix_req['result']
for i in range(len(zabbix_req)):
if zabbix_req[i]['hostid'] == host_id:
return zabbix_req[i]['interfaces'][0]['interfaceid']
#根据主机id和interfaceid定位,传入端口号来添加监控端口,成功返回监控项id
def post_item(auth,host_id,host_interfaceid,server_name,host_port,app_id):
item_name = server_name + "的" + host_port + "端口-gd"
item_key = 'net.tcp.listen[' + host_port + ']'
values = {
"jsonrpc":"2.0",
"method":"item.create",
"params": {
"name": item_name,
"key_": item_key,
"hostid": host_id,
"interfaceid": host_interfaceid,
"applications": [app_id],
"type": 0,
"value_type": 3,
"delay": "60s"
},
"auth": auth,
"id": 1
}
zabbix_req = requests.post(url,data=json.dumps(values),headers=post_header)
zabbix_req = zabbix_req.json()
print(zabbix_req)
return zabbix_req['result']['itemids'][0]
#根据主机ip来定位,传入端口号和服务名来添加触发器,成功返回触发器id
def post_trigger(auth, host_name, server_name, host_port):
description = server_name + "的" + host_port + "端口关闭"
expression = '{' + host_name + ':net.tcp.listen[' + host_port + '].last()}<>1'
values = {
"jsonrpc": "2.0",
"method": "trigger.create",
"params": {
"description": description,
"expression": expression,
"priority": trigger_pri
},
"auth": auth,
"id": 4
}
return post_info(values, 'triggerids')
#创建主机的应用集,成功返回应用集id
def post_app(auth,zabbix_app,host_id):
values = {
"jsonrpc": "2.0",
"method": "application.create",
"params": {
"name": zabbix_app,
"hostid": host_id
},
"auth": auth,
"id": 1
}
return post_info(values, 'applicationids')
#根据host_id返回应用集列表,
def get_appid(auth, zabbix_app, host_id):
values = {
"jsonrpc": "2.0",
"method": "application.get",
"params": {
"output": "extend",
"hostids": host_id,
"sortfield": "name"
},
"auth": auth,
"id": 1
}
zabbix_req = requests.post(url, data=json.dumps(values), headers=post_header)
zabbix_req = zabbix_req.json()
zabbix_req = zabbix_req['result']
for i in range(len(zabbix_req)):
if zabbix_req[i]['name'] == zabbix_app:
return zabbix_req[i]['applicationid']
#正式步骤
def post_all(host_ip,dict_info):
host_name = get_hostname(host_ip)
print(host_name + "开始添加监控项和对应触发器,并加入到应用集" + zabbix_app)
auth = get_auth()
host_id = get_hostid(auth,host_name)
host_interfaceid = get_interfaces(auth,host_id)
#先创建应用集,如果已经存在则从循环中里找出id
app_id = post_app(auth,zabbix_app,host_id)
if app_id is None:
app_id = get_appid(auth,zabbix_app,host_id)
print(app_id)
for k,v in dict_info.items():
if v[1] in deny_server:
continue
elif v[0] in deny_port:
continue
else:
item_id = post_item(auth, host_id, host_interfaceid, v[1], v[0], app_id)
trigger_id = post_trigger(auth, host_name, v[1], v[0])
print(item_id,trigger_id)
print(str(item_id))
if item_id:
print("添加" + v[1] + "的" + v[0] + "端口监控完成")
else:
print("跳过" + v[1] + "的" + v[0] + "监控添加")
print(" ")
#持续监听端口,对客户端传入的数据进行监控项和触发器的添加
def main(host,port):
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind((host, port))
serversocket.listen(200) # 最大连接数
while True:
print('服务器启动,监听客户端链接')
clientsocket, addr = serversocket.accept()
host_ip = addr[0]
data = clientsocket.recv(1024)
try:
dict_info = eval(data.decode('utf-8')) # 变成字典
except Exception as e:
print(e)
exit(1) #直接退出
post_all(host_ip, dict_info)
clientsocket.close()
serversocket.close()
if __name__ == '__main__':
main(host,port)
zabbix-net-agent.py,发放文件到指定需要被监控的服务器上
#!/usr/bin/python
#coding=utf-8
#通过netstat -unltp命令收集监听端口,需要客户端安装net-tools
#发送的字典结构:{'序号',['端口号', '进程名']},pid号主要用于去重,因为一个进程可能监控多个端口
#本脚本适用于单区服id下的服务器范围内执行agent脚本
import json, subprocess, string
import socket, sys
import json
import requests
#填写服务端地址和端口
host = "xxxx"
port = 2443
# slsk一组区服部署了2个gw的情况,gw的serverid对应slb健康检查的端口
slsk_gw_port_map = {'10111': '22111', '10112': '22121', '10121': '22211', '10122': '22221'}
#qiuqiu一组区服部署1个gw的情况,gw的serverid对应slb健康检查的端口
qiuqiu_gw_port_map = {'10011':'22111','10012':'22121'}
# slsk一组区服部署了2个bt的情况,bt的serverid对应slb健康检查的端口
slsk_bt_port_map = {'1010001': '20011', '1010002': '20021'}
#qiuqiu一组区服部署了1个bt的情况,bt的serverid对应slb健康检查的端口
qiuqiu_bt_port_map = {'1000001':'20011'}
# #常用端口列表,防止临时端口
# eternal_port = ["8889","8120"]
def get_gw_bt_map(port_list,s,project):
num = 0
if s == "GW":
print("GW类型")
gwinfo = subprocess.getstatusoutput("ls -l /data/app/ |grep GW |awk '{print $9}' |awk -F '_' '{print $2}' ")[1].split('\n')
for gw in gwinfo:
num += 1
proc_name = "GW_" + gw
if project == "slsk":
port = slsk_gw_port_map.get(gw,'')
elif project == "qiuqiu":
port = qiuqiu_gw_port_map.get(gw,'')
if port:
port_list[num] = [port, proc_name]
if s == "BT":
print("BT类型")
btinfo = subprocess.getstatusoutput("ls -l /data/app/ |grep BT |awk '{print $9}' |awk -F '_' '{print $2}'")[1].split('\n')
for bt in btinfo:
num += 1
proc_name = "BT_" + bt
if project == "slsk":
port = slsk_bt_port_map.get(bt, '')
elif project == "qiuqiu":
port = qiuqiu_bt_port_map.get(bt,'')
if port:
port_list[num] = [port, proc_name]
#返回当前机器 {'序号',['端口号', '进程名']}
def get_port():
n = 0 # type: int
i = 0
port_list = {} # 最终返回结果
#获取内网ip
# try:
# ipstr = subprocess.getstatusoutput("ip a |grep eth0 |grep inet |awk '{print $2}'|awk -F '/' '{print $1}'")[1]
# except:
# ipstr = ''
# if not ipstr:
# raise SystemExit(1) #异常退出
# con = pymysql.connect(host='47.114.80.9', user='heroes', password='GtspI0KxouLvHcb3', db='heroes', #需要这台负载均衡上开下3306透传,访问控制白名单先去掉
# charset='utf8')
# CURSOR = con.cursor()
# sql = "SELECT host_name FROM hosts where host_ip='%s'; "%ipstr
# CURSOR.execute(sql)
# try:
# result = CURSOR.fetchone()[0]
# except:
# raise SystemExit(1) #异常退出
hostnameinfo = requests.get("http://xxxx:5000/query/hostname").text
hostnameinfo = json.loads(hostnameinfo)
statu = hostnameinfo['success']
if statu:
result = hostnameinfo['msg'][0]['host_name']
else:
raise SystemExit(1) #异常退出
project = result.split('_')[0].strip() #获取项目
server_type = result.split('_')[4].strip().split('-') #获取服务类型
#server_num = CURSOR.fetchone()[0].split('_')[5].strip() #获取服务num数
if project == "qiuqiu":
for s in server_type:
if s == "AU":
n += 1
proc = "AC" + str(n)
port_list[n] = ['9522',proc] #保证key的唯一性就行
elif s == "CR":
n += 1
proc = "CR" + str(n)
port_list[n] = ['9523',proc]
get_gw_bt_map(port_list,s,project)
if project == "slsk":
for s in server_type:
if s == "AC":
p_list = ['9522','9523']
for j in range(0,len(p_list)):
i+=1
proc = "AC"+str(i)
port_list[i] = [p_list[j],proc]
get_gw_bt_map(port_list,s,project)
return port_list
# #返回当前机器 {'pid号',['端口号', '进程名']}
# def get_port():
# prostr = subprocess.getstatusoutput('netstat -unltp')
# prostr = str(prostr)
# prolist = prostr.split('\\n') #用两个\才行
# del prolist[0]
# del prolist[0]
# prolist = prolist[::-1]
# port_list = {}
# lock_pid = [] #用于锁定pid
#
# for info in prolist:
# port_info = info.split()
# if len(port_info) >= 7:
# tmp_port = port_info[3].split(':')
# tmp_port = tmp_port.pop()
# tmp_info = port_info[6].split('/')
# tmp_pid = tmp_info[0]
# try:
# tmp_name = tmp_info[1]
# except:
# continue
#
# if tmp_pid in lock_pid: #如果端口是常用端口组里,就跳过这个,只监控常用端口
# continue
#
# if tmp_port in eternal_port: #如果在表里就把pid锁定了,加入到锁定数组里
# lock_pid = lock_pid + [tmp_pid]
#
# port_list[tmp_pid] = [tmp_port, tmp_name]
# return port_list
#向master程序提交信息
def post_port(host, port):
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
host=host
port=port
s.connect((host,port))
data = get_port()
if data != {}:
data = str(data)
print(data)
s.send(data.encode('utf-8'))
s.close()
if __name__ == "__main__":
post_port(host, port)
#print(get_port())
最后在跳板机上批量串行执行被监控机器上的zabbix-net-agent.py脚本
标签:name,示例,req,zabbix,port,host,api,id From: https://blog.51cto.com/u_15703497/6251924