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という名前空間を作成します。

![azure_tsi_1.png](https://qiita-image-store.s3.amazonaws.com/0/45851/c17491b2-c226-2fdc-0f49-70466f32b30f.png)

***EventHubの新規作成***

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

![azure_tsi_2.png](https://qiita-image-store.s3.amazonaws.com/0/45851/e0aae03d-abf8-140c-f6a9-a8bc685d45bf.png)

***SASポリシーを新規追加***

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


イベントハブのAPIをプログラムから実行してイベントデータを登録するためには、ここで生成したポリシーにセットされている、SharedAccessKeyName、SHaredAccessKey、Endpointの情報を元にSAS Tokenを生成する必要があります。
この値の生成の仕方はAzureの[公式ドキュメント](https://docs.microsoft.com/en-us/rest/api/eventhub/generate-sas-token)に記載の通りとなります。
今回はPythonで作成したので、以下のような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の新規作成***

![azure_tsi_3.png](https://qiita-image-store.s3.amazonaws.com/0/45851/55bf6084-7966-932d-8c7a-778bc4f295a4.png)

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

![azure_tsi_4.png](https://qiita-image-store.s3.amazonaws.com/0/45851/6b2d1018-e61b-91a2-29e7-65f2b53a03ab.png)

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

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

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

![azure_tsi_5.png](https://qiita-image-store.s3.amazonaws.com/0/45851/55caad0c-f887-e91f-9992-fce75a840bc6.png)

これで設定は完了です。

# Time Series Insightsの画面にアクセス

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

![azure_tsi_6.png](https://qiita-image-store.s3.amazonaws.com/0/45851/90dc597e-500c-07fc-23f8-201f6c1945b7.png)

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

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

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

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

```python: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の画面を確認すると、以下の感じで値が連携されてきているのがわかります。

![azure_tsi_7-2.png](https://qiita-image-store.s3.amazonaws.com/0/45851/8120aa6e-f902-531c-9e4d-14cbbcc02557.png)

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

![azure_tsi_8-2.png](https://qiita-image-store.s3.amazonaws.com/0/45851/79d41502-6e2c-08db-c407-7c301f93c8c7.png)

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

![azure_tsi_9.png](https://qiita-image-store.s3.amazonaws.com/0/45851/6412c0fb-2d10-1472-616e-0b353c48e5e0.png)


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