定义预警分为几个步骤
- 定义预警媒介
- 定义预警用户
- 定义预警动作
触发器达到阈值,调用预警动作,预警动作调用预警用户,预警用户调用预警媒介
预警媒介
配置-报警媒介类型,这里有两个要素
报警媒介类型
类型有很多种,比如邮件,自定义脚本,这里我们选自定义脚本,来定义一个企业微信预警
脚本需要接收三个参数:
{ALERT.SENDTO}:收件人
{ALERT.SUBJECT}:主题
{ALERT.MESSAGE}:内容
我们一般只用{ALERT.SENDTO}和{ALERT.MESSAGE}即可
信息模板
定义信息模板,一般我们定义告警模板/恢复模板/自动注册模板
告警模板如图:
【[骷髅]】=》{TRIGGER.SEVERITY} 事件 : {EVENT.ID}
【问题时间】: {EVENT.DATE} {EVENT.TIME}
【问题名字】: {EVENT.NAME}
【问题主机】: {HOST.NAME}
【问题级别】: {EVENT.SEVERITY}
【阈值信息】: {TRIGGER.NAME}
【阈值项目】: {TRIGGER.KEY1}
【问题详情】: {ITEM.NAME}:{ITEM.VALUE}
【当前状态】: {TRIGGER.STATUS}:{ITEM.VALUE1}
【Operational data】: {EVENT.OPDATA}
{TRIGGER.URL}
恢复模板如图:
【[OK]】=》{TRIGGER.SEVERITY} 事件 : {EVENT.ID}
【问题时间】: {EVENT.DATE} {EVENT.TIME}
【问题恢复时间】: {EVENT.RECOVERY.DATE} {EVENT.RECOVERY.TIME}
【问题名字】: {EVENT.NAME}
【问题主机】: {HOST.NAME}
【问题级别】: {EVENT.SEVERITY}
【阈值信息】: {TRIGGER.NAME}
【阈值项目】: {TRIGGER.KEY1}
【问题详情】: {ITEM.NAME}:{ITEM.VALUE}
【当前状态】: {TRIGGER.STATUS}:{ITEM.VALUE1}
【Operational data】: {EVENT.OPDATA}
{TRIGGER.URL}
自动注册模板如图:
自动注册:
主机名: {HOST.HOST}
主机ip: {HOST.IP}
代理端口: {HOST.PORT}
放置发送信息的脚本
具体位置以zb server的安装和配置为基准.
#!/usr/bin/env python3
"""
@author: zyh
@contact: [email protected]
@software: vscode
@file: sendchat.py
@time: 2020/02/05
@use: pip3 install requests configparser
"""
import sys, os, requests, pathlib, json, configparser
import logging
import logging.handlers
from datetime import datetime
class PySendchat():
def __init__(self, corpid, agentid, secret, touser, content):
self.corpid=corpid
self.agentid=agentid
self.secret=secret
self.touser=touser
self.content=content
LOG_PATHDIR=os.path.dirname(os.path.abspath(__file__))
LOG_FILENAME = '{0}/sendchat.log'.format(LOG_PATHDIR)
self.my_logger = logging.getLogger('SendChat')
self.my_logger.setLevel(logging.INFO)
# Add the log message handler to the logger
handler = logging.handlers.RotatingFileHandler(LOG_FILENAME, maxBytes=102400000, backupCount=5)
# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
self.my_logger.addHandler(handler)
def gettoken(self):
self.my_logger.info('-----------------------------------------------------------------------------------------')
pwd=os.path.dirname(os.path.abspath(__file__))
tokenfile='{0}/wechat.{1}'.format(pwd,self.agentid)
if pathlib.Path(tokenfile).exists():
tokenfilectime=os.path.getctime(tokenfile)
currenttime=datetime.now().timestamp()
dtime=currenttime-tokenfilectime
self.my_logger.info('{0} lived {1}s.'.format(tokenfile, dtime))
if dtime >= 7200:
try:
os.remove(tokenfile)
self.my_logger.info('Token file {0}: delete success'.format(tokenfile))
except Exception as e:
self.my_logger.error('Token file:{0} delete error.Reason:{1}'.format(tokenfile,e))
exit
# check token file
try:
tokensize = os.path.getsize(tokenfile)
except Exception as e:
self.my_logger.info('Token file is not exist.Reason:{0}'.format(e))
tokensize = 0
# get token from token file
if tokensize != 0:
with open(tokenfile, 'rb') as fd:
token = fd.read() # get token success
self.my_logger.info('Get token from token file.')
jsonObject = json.loads(token.decode(encoding='utf8'))
access_token = jsonObject.get("access_token")
return access_token
# get token from weixin api
else:
try:
self.my_logger.info('New Token Create.')
f = requests.get('https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={0}&corpsecret={1}'.format(self.corpid, self.secret))
token = f.content
self.my_logger.info('Get token from weixin api.')
jsonObject = json.loads(token.decode(encoding='utf8'))
errcode=int(jsonObject.get("errcode"))
if errcode != 0:
errmsg=jsonObject.get("errmsg")
self.my_logger.error('Get token error!Reason:{0}'.format(errmsg))
exit()
except Exception as e:
self.my_logger.error('Get token error!Reason:{0}'.format(e))
exit()
try:
self.my_logger.info('Write token to {0}.'.format(tokenfile))
with open(tokenfile, 'wb') as fd:
fd.write(token)
except Exception as e:
self.my_logger.error('Write {0} error!Reason:{1}'.format(tokenfile,e))
exit()
access_token = jsonObject.get("access_token")
return access_token
def sendmsg(self):
accessToken = self.gettoken()
self.my_logger.info('Token:{0}'.format(accessToken))
sendMapDirectroy = {}
sendMapDirectroy["agentid"] = self.agentid
sendMapDirectroy["touser"] = self.touser
sendMapDirectroy["msgtype"] = "text"
sendMapDirectroy["safe"] = "0"
contentDirectory = {}
sendMapDirectroy["text"] = contentDirectory
contentDirectory["content"] = self.content
bodyStr = json.dumps(sendMapDirectroy, ensure_ascii=False).encode(encoding="utf-8")
try:
f = requests.post(url="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s" % accessToken,
data=bodyStr, timeout=5)
self.my_logger.info(f.content)
except Exception as e:
self.my_logger.error('Send chat network error!Reason:{0}'.format(e))
if __name__ == '__main__':
appname = sys.argv[1]
content = sys.argv[3]
# read conf.ini
conf = configparser.ConfigParser()
conf_path = os.path.dirname(os.path.abspath(__file__))
conf_ini = "{0}/conf.ini".format(conf_path)
if pathlib.Path(conf_ini).exists():
conf.read(conf_ini)
corpid = conf.get("wechat", "corpid")
appinfo = conf.get("app", appname)
agentid = appinfo.split(':')[0]
secret = appinfo.split(':')[1]
groupname = conf.get("group", appname)
touser = groupname.split(':')[0]
chatobj = PySendchat(corpid, agentid, secret, touser, content)
else:
print('conf.ini error')
exit()
try:
chatobj.sendmsg()
except:
chatobj.my_logger.error("Send chat failure!")
# conf.ini
[wechat]
corpid =
[app]
it = <app_agent_id>:<app_secret>
[group]
it = usera|userb
eg:
python3 wechat.py it ‘’ <预警内容>
因 zabbix 调用脚本并非 root 用户,所以给脚本附加 x 权限,避免权限问题。
chmod a+x wechat.py
# 因脚本会生成其它文件
# 所以还需要给脚本所在的目录添加其它用户的写入权限
chmod 757 alertscripts
预警用户
管理-用户-添加用户,这里有三要素
用户
你无需登陆这个用户,所以密码可以尽量的复杂
报警媒介
我们定义这个用户被调用的时候,将会发送信息给it组,至于it组包含哪些人员,则由脚本定义。
权限
预警动作
配置-动作-左上角(触发器动作Trigger actions),这里我们需要定义两个要素
- 什么条件下执行动作
- 动作的实际行为
条件
需要注意的是计算方式
问题没有被制止的意思:没有人为的关闭预警