zabbix☞预警

阅读量: zyh 2020-09-02 14:27:54
Categories: > Tags:

定义预警分为几个步骤

  1. 定义预警媒介
  2. 定义预警用户
  3. 定义预警动作

触发器达到阈值,调用预警动作,预警动作调用预警用户,预警用户调用预警媒介

预警媒介

配置-报警媒介类型,这里有两个要素

报警媒介类型

类型有很多种,比如邮件,自定义脚本,这里我们选自定义脚本,来定义一个企业微信预警

image-20200902144015196

脚本需要接收三个参数:

{ALERT.SENDTO}:收件人

{ALERT.SUBJECT}:主题

{ALERT.MESSAGE}:内容

我们一般只用{ALERT.SENDTO}和{ALERT.MESSAGE}即可

信息模板

定义信息模板,一般我们定义告警模板/恢复模板/自动注册模板

告警模板如图:

image-20200902144408513

【[骷髅]】=》{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}

恢复模板如图:

image-20200902144504865

【[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}

自动注册模板如图:

image-20200902144535568

自动注册: 
主机名: {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

预警用户

管理-用户-添加用户,这里有三要素

用户

你无需登陆这个用户,所以密码可以尽量的复杂

image-20200902150131147

报警媒介

image-20200902150145022

我们定义这个用户被调用的时候,将会发送信息给it组,至于it组包含哪些人员,则由脚本定义。

权限

image-20200902150153011

预警动作

配置-动作-左上角(触发器动作Trigger actions),这里我们需要定义两个要素

  1. 什么条件下执行动作
  2. 动作的实际行为

条件

需要注意的是计算方式

问题没有被制止的意思:没有人为的关闭预警

image-20200902150806009

操作

image-20200902151037597