yanfangsheng123 发表于 2019-1-25 10:25:23

线上使用zabbix报警脚本(含图片)

  分享一个线上使用的自定义zabbix报警脚本,脚本思路大致如下:
  1.使用爬虫获取报警图片(前提是要获得报警的item)

  2.将图片与邮件内容整合

  3.发送邮件

  4.日志记录

  

  脚本内容如下:
#!/usr/bin/python
#coding:utf-8
import sys,time,re,os,glob
import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
import urllib,urllib2,cookielib
import zlib
mail_host = '************'            # 邮件发送方相关信息
mail_user = '************'
mail_pass = '************'
mail_postfix = '************'
zabbix_user = "********"            # zabbix-web相关信息
zabbix_pass = "********"
url = "http://***********/"
alartscript_path="/**********/alertscripts/"      # 邮件脚本及日志位置
line = "ItemID"
me = "zabbix"+''
######### 利用爬虫获取图片,保证cookie的可用性
def get_graph(itemID):
      login_url = url + "index.php"
      post_value = {"request":"",
                        "name":zabbix_user,
                        "password":zabbix_pass,
                        "autologin":"1",                #注意这个是否记住密码的选项,将造成生成的cookie长度不一样,短的能查看到图但没有数据
                        "enter":"Sign in"
                }
      post_data = urllib.urlencode(post_value)
      headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0",
                   "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
                   "Accept-Encoding":"gzip, deflate",
                   "Accept-Language":"zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
                   "Connection":"Keep-Alive",
                   "Host":"**************",
                   "Referer":login_url,
                   ###########这个cookie很重要,要求当前cookie正在浏览器上正常使用,才能顺利取图
                   "Cookie":"******** zbx_sessionid=*********"
                }
      request = urllib2.Request(login_url,post_data,headers)
      cj = cookielib.CookieJar()
      opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
      urllib2.install_opener(opener)
      result = opener.open(request)
      print result.info()                                              #查看下内容信息,如果是gzip要解压写入文件
      result_html = zlib.decompress(result.read(), 16+zlib.MAX_WBITS)
      global graph_url                            # 构建用于访问图片的URL
      graph_url = url+"chart.php"+"?itemids="+str(itemID)
      graph_data = urllib2.urlopen(graph_url)
      print graph_data.info()#.get('Content-Encoding')
      #graph_html = zlib.decompress(graph_data.read(), 16+zlib.MAX_WBITS)
      print graph_data.info().get('Content-Type')
      image_data = graph_data.read()
      if graph_data.info().get('Content-Type') == "image/png":
                image_file = open('last_%s.pnj'%itemID,'wb')
                image_file.write(image_data)
                image_file.close()
      else:
                trigged = open('zabbix.png','rb')            # 如果获取图片data失败,打开一张事先准备好的图,这里使用的是zabbix的logo,在邮件中很直接的反应出获取图片失败
                image_data = trigged.read()
                trigged.close()
      print "Graph_URL:",graph_url
      return image_data
def mail_con(txtData,imageData):                  # 重写邮件内容(添加图片)
      msg = MIMEMultipart('related')
      msg['Subject'] = subject
      msg['From'] = me
      msg['to'] = receiver
      con_txt = MIMEText(txtData,_subtype='html',_charset='utf-8')
      msg.attach(con_txt)
      con_img = MIMEImage(imageData)
      con_img.add_header('Content-ID','digglife')      # 将要发送的图片嵌入到邮件头部,重写邮件内容
      msg.attach(con_img)
      return msg.as_string()
def send_mail(receiver,subject,contents):                # 邮件发送,并将结果记录
      logfile = open('alarm_mail.log','a')
      try:
                s = smtplib.SMTP()
                s.connect(mail_host)
                s.login(mail_user,mail_pass)
                s.sendmail(me,receiver,contents)
                s.close()
                log = time.ctime() + "\tOK\t" + subject +"\t"+ receiver + "\n"
      except Exception,e:
                log = time.ctime() + "\tFail\t" + subject +"\t"+ receiver + "\n"
      logfile.write("\n"+"\t"+graph_url+"\n")
      logfile.write(log)
      logfile.close()
if __name__ == "__main__":
      cur_pwd = os.getcwd()
      print cur_pwd
      os.chdir(alartscript_path)                # zabbix-server工作的路径为/,在这里切换邮件脚本路径,可以写入日志和图片处理,减少出错
      old_pnjs = glob.glob('last_*.pnj')
      for old_file in old_pnjs:
                os.remove(old_file)
      receiver = sys.argv
      subject = sys.argv
      src_mail_con = sys.argv
      try:
                ItemID = re.match(r'.*ItemID:(\d+)[^\d]+.*',src_mail_con.replace('\n',''),re.S).group(1)      # 利用正则从邮件内容中获取itemID
      except:
                ItemID = 0000                # item为0000的是一张空图,减少异常情况
      print "ItemID:",ItemID
      ImageData = get_graph(ItemID)
      MailCon = mail_con(src_mail_con,ImageData)
      send_mail(receiver,subject,MailCon)  脚本中‘********’部分出于个人信息安全进行隐藏,读者可根据具体环境修改(发件箱信息,zabbix-web登陆信息及cookie)
  

  脚本首先要获得报警itemID,以及邮件内容放置图片信息,因此还要自定义报警邮件内容,如下:
  邮件内容:
   
    故障通知
    触发器: {TRIGGER.NAME}
    主机名:{HOST.NAME}({IPADDRESS})
    状态: {TRIGGER.STATUS}
    告警级别: {TRIGGER.SEVERITY}
    URL: {TRIGGER.URL}
   
    告警项目:
   
    {ITEM.NAME1} ({HOST.NAME1}:{ITEM.KEY1}): {ITEM.VALUE1}
   
   
   
   
    ItemID:{ITEM.ID}
    EventID: {EVENT.ID}
    告警时间:{EVENT.DATE} {EVENT.TIME}
   
    详细信息:登录查看
      

  效果如下:
  QQ邮箱接收邮件,显示内容:

http://s5.运维网.com/wyfs02/M02/82/C5/wKiom1dgvSuS1qFvAAF8YigS1no396.png-wh_500x0-wm_3-wmp_4-s_2327714890.png
  日志记录:

http://s2.运维网.com/wyfs02/M00/82/C5/wKiom1dgwZ2yT6UNAAARijI_uhU972.png



页: [1]
查看完整版本: 线上使用zabbix报警脚本(含图片)