目次
- 目的
- 方法
- 設定
- 動作確認
- 運用設定
目的
Raspberry Pi に装着した温湿度センサーで情報を取得できるようになったので Zabbix で監視してみる。
方法
過去の記事で書いたが、Raspberry Pi では現在 Zabbix Proxy と Zabbix Agent が動作している。
想定としては以下の流れで温湿度データを監視するようにしたい。
- Raspberry Pi で温湿度情報を取得
- 取得した情報を Zabbix Sender で Raspberry Pi 自身の Zabbix Proxy に送信
- 温湿度情報が Zabbix サーバーに送信され監視される
温湿度情報を監視するために Zabbix にそれぞれの監視アイテムを作成する必要がある。
監視アイテムはホストに作成する必要があるが、今回は Raspberry Pi のエージェント監視を行っているホストに温湿度用の監視アイテムを作成してみる。
設定
Raspberry Pi 側
ZabbixSender 0.2.7 のインストール
温度センサーの情報は Python のスクリプトで取得していることから、Zabbix にデータを送信する部分も Python で実施したい。
そこでぐぐって見つけたのが以下の ZabbixSender 0.2.7 である。
https://pypi.org/project/ZabbixSender/
pip を使ってインストールして利用できる状態にしてみる。
コマンド
pip install ZabbixSender
ログ
amegon@raspberrypi:~ $ pip install ZabbixSender Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple Collecting ZabbixSender Downloading https://www.piwheels.org/simple/zabbixsender/ZabbixSender-0.2.7-py3-none-any.whl (5.2 kB) Installing collected packages: ZabbixSender Successfully installed ZabbixSender-0.2.7 amegon@raspberrypi:~ $
インストールの確認
amegon@raspberrypi:~ $ pip list |grep ZabbixSender ZabbixSender 0.2.7 amegon@raspberrypi:~ $
無事にインストールできた。
Python スクリプトの修正
次に、監視データを Zabbix Sender で送信する部分をスクリプトに実装する。
前回作成したコードに追加する。以下のような感じ。
コード
import Adafruit_DHT as DHT import time from ZabbixSender import ZabbixSender, ZabbixPacket # センサーの定義 SENSOR_TYPE = DHT.DHT22 # GPIO 番号の定義 DHT_GPIO = 4 # 温湿度の取得 exec_time = int(time.time()) hum,temp = DHT.read_retry(SENSOR_TYPE, DHT_GPIO) # データは小数点第2位を四捨五入して第1位まで表示。 print('Temp={0:0.1f}*C Humidity={1:0.1f}%'.format(temp, hum)) temp = '{0:0.1f}'.format(temp) hum = '{0:0.1f}'.format(hum) print(temp) print(hum) # Zabbix Sender で送信 # 送信先 Zabbix Server or Zabix Proxy の IP アドレス ZBX_SVR = '127.0.0.1' # 送信先 Zabbix Server or Zabix Proxy の ポート番号(デフォルト 10051) ZBX_SVR_PORT = 10051 # 監視データのアイテムを持つ Zabbix 上のホスト名 ZBX_HOST_NAME = 'RasPi_01' # 監視データ用アイテムのキー文字列:温度 ZBX_ITEM_KEY_TEMP = 'raspberrypi.temperature' # 監視データ用アイテムのキー文字列:湿度 ZBX_ITEM_KEY_HUM = 'raspberrypi.hummidity' # ZabbixSender オブジェクトと packet オブジェクトを作成 server = ZabbixSender(ZBX_SVR, ZBX_SVR_PORT) packet = ZabbixPacket() # packet オブジェクトに送信するデータの組みあわせをセット packet.add(ZBX_HOST_NAME, ZBX_ITEM_KEY_TEMP, temp, exec_time) packet.add(ZBX_HOST_NAME, ZBX_ITEM_KEY_HUM, hum, exec_time) # データを送信 server.send(packet) # 送信したデータを表示 print(server.status)
実行したらエラー。
amegon@raspberrypi:~/work/scripts/sensor/samples $ python3 test5.py Temp=28.8*C Humidity=60.9% 28.8 60.9 Traceback (most recent call last): File "/home/amegon/work/scripts/sensor/samples/test5.py", line 42, in <module> server.send(packet) File "/home/amegon/.local/lib/python3.9/site-packages/ZabbixSender/ZabbixSender.py", line 36, in send status = re_status.search(status).groups()[0] AttributeError: 'NoneType' object has no attribute 'groups' amegon@raspberrypi:~/work/scripts/sensor/samples $
zabbix_proxy.log にも以下のログが書かれていることを発見。
Message from 127.0.0.1 is missing header. Message ignored.
ググってみると Zabbix サーバーと Zabbix エージェントのバージョンが不一致の場合に missing header
のログが記録されるらしい。
ということは python ライブラリの方で Header に設定情報が足りていないのかな?と思い申すコスググる。
そうしましたら以下の記事を発見。
https://www.happylifecreators.com/blog/20220323/
す、すごい。。。
コード ZabbixSender.py の保存場所を find で探して以下のように修正。
自分の環境では上記URLの修正のままだと動作しなかったので、struct の import 部分と pack の仕様部部分を書き換えています。
import json import re import socket import time from struct import * class ZabbixSender: def __init__(self, server='127.0.0.1', port='10051', config=None): if config is not None: conf_file = open(config, 'r') re_server = re.compile('\\nServer=(\S*)\\n\\n') temp_server = re_server.search(conf_file.read()) conf_file.close() self.server = temp_server.groups()[0] else: self.server = server self.port = port self.status = '' def __str__(self): return json.dumps({'server': self.server, 'port': self.port}, indent=4) def send(self, packet): packet = str(packet).encode('utf-8') s = socket.socket() try: s.connect((self.server, int(self.port))) except Exception as e: # TODO: Horrible! Rewrite immediately. print(e) # Add Header (2023-09-07) header = pack(b'<4sBQ', b'ZBXD', 1, len(packet)) packet = header + packet s.send(packet) time.sleep(0.5) status = s.recv(1024).decode('utf-8') re_status = re.compile('(\{.*\})') status = re_status.search(status).groups()[0] self.status = json.loads(status) s.close()
ログ
amegon@raspberrypi:~/work/scripts/sensor/samples $ python3 test5.py Temp=24.2*C Humidity=58.1% 24.2 58.1 {'response': 'success', 'info': 'processed: 2; failed: 0; total: 2; seconds spent: 0.000316'} amegon@raspberrypi:~/work/scripts/sensor/samples $
動きました。
Zabbix 側
以下のようなアイテムを作成。
キーは先述のスクリプトに設定した文字列をあわせる。
温度
湿度
動作確認
データの受信も確認できた。
運用設定
作成したスクリプトの名前を変更して、cron で定期実行するようにして Zabbix での監視を行う。
cron の設定内容
# every 1 minute
* * * * * python3 /home/amegon/work/scripts/sensor/sendSensorData.py
Zabbix でも1分ごとにデータが受信できていることが確認できた。