ZabbixAPI 던져서 오류 정보를 Slack에 던지는 파이썬 프로그램

17946 단어 슬랙Python3zabbix

Zabbix 서버가 난립했습니다.



여러 사정에 의해 Zabbix 서버가 몇 대 서 있고, 각각 관리하지 않으면 안되는 사태가 되었다.
매일의 체크가 매우 귀찮았기 때문에 API를 사용해 한발로 정보를 받을 수 있는 물건을 만들었다.



우선순위에 따라 적색-황-녹색으로 구분된다. 보기 쉬운 ...!
검은색 도장 r###

전제


  • python3
  • SlackAPI 사용 가능

  • 했던 일



    ZabbixAPI 두드리는



    Zabbix API의 작동 방식 이해
    이 기사의 ZabbixAPI 클래스를 사용하여 각 Zabbix의 API를 두드린다.

    선인의 코드는 위대하다. 고맙습니다 ...!

    trigger.get 로 "filter": {"status": 0,"value": 1} 를 지정하는 것으로 현재 일어나고 있는 장해만을 취득할 수 있다.
    또한 "selectHosts": ["name"]를 지정하여 호스트 이름도 가져옵니다.
    # http://qiita.com/Trickey/items/d51d93d525443baa496f
    # のZabbixAPIクラスを利用。
     zabapi= ZabbixApi(url,"Admin","zabbix")
     zabapi.request('trigger.get', {
            "output": ["triggerid","description","priority","lastchange"],
            "selectHosts": ["name"],
            "monitored": "true",
            "filter": {
            "status": 0,
            "value": 1
            }})
        if 'result' in response:
            for alert in response['result']:
                if int(alert['lastchange']) < time.time()-(31*24*60*60):
                    # 一ヶ月以上前のアラートを無視
                    continue
                # 加工してリストに追加
                datetime_s = str(datetime.fromtimestamp(float(alert['lastchange'])))  # UNIXTIMEなので変換
                hostname = alert['hosts'][0]['name']                                  # ホスト名はlistの下にdictがぶら下がっているので[0]を噛ませる
                description = alert['description'].replace('{HOST.NAME}', hostname)
                uri = "http://{0}/".format(url)
                ret.append({"description": description, "hostname": hostname, "time":datetime_s, "priority":alert['priority'],"url":uri})
        return ret
    

    우선도별로 분류하고 싶었기 때문에 소트 함수 자작.


    from functools import cmp_to_key
    
    ## カスタムソート機構
    def cmp(a,b):
        a = int(a)
        b = int(b)
        return (a>b)-(a<b)
    
    def cmp_len(s1, s2):
        # 優先度順、同じならホスト名の頭一文字コード順
        ret = cmp(s1['priority'], s2['priority'])
        if ret == 0:
            return cmp(s1['hostname'].encode('utf-8')[0], s2['hostname'].encode('utf-8')[0])
        else:
            return ret
    
    def main():
        <>
        # 優先度順にソート
        errlist = sorted(errlist, key=cmp_to_key(cmp_len), reverse=True)
    

    Slack의 Attachment 기능을 사용하여 쉽게 볼 수 있습니다.



    Attaching content and links to messages
    json으로 던지는 것만으로 서두의 이미지 같은 표시가 되어 준다.

    dict 형식으로 반환하는 함수이므로 사용할 때는 퍼스를 잊지 마세요.
    def createAttachment(hostname,description,time_s,priority,uri=""):
        """ Slackに投げるAttachmentを作成する """
        # 優先度別で色を付ける
        colorlist = {
            '5':"#FF2222",
            '4':"#FF9922",
            '3':"#FFFF22",
            '2':"#CCFF22",
            '1':"#22FF22"
        }
        color = colorlist[priority]
    
        # https://api.slack.com/docs/message-attachments
        return {
            "color": color,
            "author_name": hostname,
            "author_link": uri,
            "text": description,
            "fields": [
                {
                    "title": "time",
                    "value": time_s,
                    "short": True
                },
                {
                    "title": "Priority",
                    "value": priority,
                    "short": True
                }
            ]
        }
    

    후에는 집계하여 SlackAPI에 퐁.


    def main():
        # 調査するZabbixのURLリスト
        serverlist = [  "url/to/zabbix1",
                        "url/to/zabbix2"
                     ]
        errlist = []
    
        # 障害をリストして優先度順にソート
        for srv in serverlist:
            errlist.extend(getErrorSummary(srv))
        errlist = sorted(errlist, key=cmp_to_key(cmp_len), reverse=True)
    
        # Attachment作成ついでに優先度別に集計
        att = []
        priority_count = [0,0,0,0,0]
        for err in errlist:
            priority_count[int(err["priority"])-1] += 1
            att.append(createAttachment(err["hostname"],err["description"],err["time"],err["priority"],err["url"]))
    
        # メッセージ作成
        mes = "いまのZabbixアラートだよ!\n Summary : "
        for pcidx in range(4, -1, -1):
            if priority_count[pcidx] > 0:
                mes = mes + (str(pcidx+1)+':'+str(priority_count[pcidx])+' ')
    
        # SlackへPOST (自作関数)
        post_message(username="ZabbixSummary",message=mes,attachments=att)
    

    정기적으로 확인



    linux 기계에 돌진하고 cron에 등록하기만 하면 됩니다.

    끝.



    Tips적으로 쓰고 있기 때문에 모든 코드는 타지 않습니다.
    움직이는 코드에서 발췌하거나 코멘트를 추가하여 게시하고 있으므로,
    이용할 때는 각자 부족분 보충해 주세요(둥근 던지기)

    마지막으로



    Zabbix가 난립하는 일이 되기 전에 중앙 관리를 할 수 없는지 계획을 하자!

    좋은 웹페이지 즐겨찾기