Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
5
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

ZabbixAPI投げて障害情報をSlackに投げるpythonプログラム書いた

Zabbixサーバが乱立してしまった

諸事情によりZabbixサーバが数台立っており、それぞれ管理しないといけない事態になった。
日々のチェックが非常に面倒だったのでAPI使って一発で情報が受け取れるようなモノを作った。

image.png

優先度に応じて赤-黄-緑に色分けされる。見やすい…!
黒塗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が乱立するなんてことになる前に一元管理ができないか計画をしよう!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
5
Help us understand the problem. What are the problem?