Zabbixで収集した監視データをAzure Time Series Insightsで時系列分析


監視運用を行っていると、より高度に監視データを分析し、異常がないかをチェックしたいといったことがあるかと思います。
MicrosoftのAzureには、Azure Time Series Insightsという時系列データの分析に特化したサービスがあります。
Zabbixは分析機能としては弱いところがあるのでZabbixで収集したデータをこのような分析系のサービスと組み合わせることで有効に働くケースもあるかと思います。

今回はそんなAzure Time Series Insightsを試してみるため、Zabbixの監視データの情報を登録してみました。
ZabbixからAzure Time Series Insightsまでのデータの流れは以下になります。

Zabbix
↓ 
今回実装したスクリプト(Zabbix API経由でデータ収集)
↓
EventHub
↓ 
Azure Time Series Insights

Azure Time Series InsightsはIoT HubやEvent HubというAzureのサービスに入ってきたデータをピックアップして分析できるようにしてくれます。なので、Zabbixで収集したデータをEventHubに登録するという処理を実装すれば簡単に連携できます。

Event Hubの登録

まず、データの受け手となるEventHubを定義します。

EventHubの名前空間を新規作成

ここではサンプルとしてzabbix-historyという名前空間を作成します。

EventHubの新規作成

test1というイベントハブを作成します。

SASポリシーを新規追加

次に、このEventHubの名前空間に対して、SASポリシーを新規追加します。
これはEventHubに対してAPI経由でデータを登録する際にチェックされる権限ポリシーの定義です。
sampleという名称で「送信」「リッスン」権限を持ったポリシーを追加します。

イベントハブのAPIをプログラムから実行してイベントデータを登録するためには、ここで生成したポリシーにセットされている、SharedAccessKeyName、SHaredAccessKey、Endpointの情報を元にSAS Tokenを生成する必要があります。
この値の生成の仕方はAzureの公式ドキュメントに記載の通りとなります。
今回はPythonで作成したので、以下のようなpythonスクリプトを実行して生成しました。

get-sas-token.py

import time
import urllib.parse
import hmac
import hashlib
import base64

def get_auth_token(sb_name, eh_name, sas_name, sas_value):
    """
    Returns an authorization token dictionary
    for making calls to Event Hubs REST API.
    """
    uri = urllib.parse.quote_plus("https://{}.servicebus.windows.net/{}" \
                                  .format(sb_name, eh_name))
    sas = sas_value.encode('utf-8')
    expiry = str(int(time.time() + 10000))
    string_to_sign = (uri + '\n' + expiry).encode('utf-8')
    signed_hmac_sha256 = hmac.HMAC(sas, string_to_sign, hashlib.sha256)
    signature = urllib.parse.quote(base64.b64encode(signed_hmac_sha256.digest()))
    return  {"sb_name": sb_name,
             "eh_name": eh_name,
             "token":'SharedAccessSignature sr={}&sig={}&se={}&skn={}' \
                     .format(uri, signature, expiry, sas_name)
            }

result = get_auth_token("作成したEventHub名前空間", "作成したEventHub名", "SASポリシー名", "主キーの値")
print(result['token'])

実行すると以下のようなSAS Tokenが提示されます。

SharedAccessSignature sr=https%3A%2F%2Fzabbix-history.servicebus.windows.net%2Ftest1&sig=NAB.....%2......vzXYUAsr.......%3D&se=15......&skn=sample

この値を使ってcurlコマンドでEventHubにメッセージ登録してみます。
SAS TokenはAuthorizationヘッダーに設定してPOSTリクエストを送ればOKです。
送付するデータはjson型で送ります。

curl -XPOST -H "Authorization: SharedAccessSignature sr=https%3A%2F%2Fzabbix-history.servicebus.windows.net%2Ftest1&sig=NAB.....%2......vzXYUAsr.......%3D&se=15......&skn=sample" -d '{"value1":123,"value2":10}' "https://zabbix-history.servicebus.windows.net/test1/messages"

これでEventHub側の設定はOKです。

Time Series Insightsの登録

次にTSIの設定に移ります。

Time Series Insightsの新規作成

データソースとして先程作成したEventHubを選択

データアクセスポリシーを追加

初期状態だと、このTime Series Insightsに対してどのユーザもアクセス権が割り当てられていないため、特定のユーザに権限を付与します。

今回は自分のアカウントに所有者権限を付与しました。

これで設定は完了です。

Time Series Insightsの画面にアクセス

作成したTime Series Insightsの概要ページからTime Series InsightsエクスプローラのURLがわかるのでそこからアクセスします。

アクセスするとEventHubから収集されたデータが自動的に集計してグラフが表示されます。

Zabbixから情報を収集するスクリプトを実装

Pythonを使ってZabbixから収集し、EventHubにAPIでデータを登録してみます。

今回作成したスクリプトは以下です。

send_azure_eventhub.py
from zabbix_api import ZabbixAPI
from datetime import datetime
import requests
import time

def get_zabbix_history(itemid):
    api = ZabbixAPI(server="http://localhost/zabbix")
    api.login("Admin", "zabbix")

    time_from = int(datetime.now().timestamp()) - 30 #現在時刻の30秒前の時間をunixtimeを設定

    result = api.history.get({
        "history": 0,
        "itemids": [itemid],
        "time_from": time_from})
    return result

def send_azure_eventhub():
    SAS_TOKEN = 'SharedAccessSignature sr=https%3A%2F%2Fzabbix-history.servicebus.windows.net%2Ftest1&sig=NAB.....%2......vzXYUAsr.......%3D&se=15......&skn=sample'
    headers = {'Authorization': SAS_TOKEN}

    data = get_zabbix_history(23305) # itemid 23305の監視データを連携してみる
    requests.post('https://zabbix-history-2.servicebus.windows.net/test1/messages', headers=headers, json=data)

while True:
    send_azure_eventhub()
    time.sleep(30)

30秒間隔でループし、直近30秒間に登録されたZabbixの監視データを収集しEventHubに送り続けるというものです。

Time Series Insightsの画面を確認すると、以下の感じで値が連携されてきているのがわかります。

詳細を確認したいEventsを右クリックしメニューを表示し、「Explore Events」を実行すると実際にEventHubに入ってきている項目や値の内容が確認できます。

さらにSTATSタブを選択すると統計情報が確認できます。

データを集計して確認したりするのには便利につかえそうな感じです。
Azure Time Series Insightsの細かい使い方はまだ確認中なので、今回はここまで。