pythonでping監視
はじめに
- あるプライベートネットワークの中に存在するクライアントにpingを打ち、常時監視するツールが欲しかった。
- メールでの通知とかも分かりづらいのでいろんな通知の方法が使いたかった(今回はLine Botで通知)。
- 良さげなツールが無かったので自分でプログラムを書いて実現することにした
PythonでPingを打つ
pythonではsubprocess
を使えばpingを打てるらしいです。
この関数をお借りしてpingを打ちます。
import subprocess def is_connectable(host): ping = subprocess.Popen(["ping", "-w", "3", "-c", "1", host], stdin=subprocess.PIPE, stdout=subprocess.PIPE) ping.communicate() return ping.returncode == 0
今回監視したい対象は、あるセグメントの中で固定IPを振られて存在しているクライアントが対象なので、クライアントのIPアドレスをcsvファイルから読み込みます。
取得したIPアドレスのリストをforループで回して全てにpingを打ち、NGだった場合は通知を送ります。
(今回はLine Botに通知させたいのでBotサーバのURLにリクエストしています。)
1,192.168.101.1 2,192.168.101.2 3,192.168.101.3 4,192.168.101.4 : :
import csv, subprocess, requests def is_connectable(host): ping = subprocess.Popen(["ping", "-W", "3", "-c", "1", host], stdin=subprocess.PIPE, stdout=subprocess.PIPE) ping.communicate() return ping.returncode == 0 while True: f = open('IPAdressTable.csv', 'r') reader = csv.reader(f) for index, row in enumerate(reader): print(row) result = is_connectable(row[1]) if result is not True: url = "https://my-line-bot-url.com/alert" + row[0] requests.get(url) f.close()
これで、まずは機能としては完成ですが、同セグメント内に存在する100個近くのクライアントにpingを打っていると、一周するのも時間がかかってしまい、あまり常時監視している感じがしなくなってしまいます。
そこで並列処理を導入して、複数スレッドで処理させようと思います。
joblibで並列処理
pythonの並列処理にはjoblib
が便利みたいです。
ここを参考にループ処理の部分を書き換えます。
import csv, subprocess, requests from joblib import Parallel, delayed def is_connectable(host): ping = subprocess.Popen(["ping", "-W", "3", "-c", "1", host], stdin=subprocess.PIPE, stdout=subprocess.PIPE) ping.communicate() return ping.returncode == 0 def send_connection_status(host, number): print(host) result = is_connectable(host) if result is not True: url = "https://my-line-bot-url.com/alert" + row[0] requests.get(url) while True: f = open('IPAdressTable.csv', 'r') reader = csv.reader(f) header = next(reader) Parallel(n_jobs=-1)( [delayed(send_connection_status)(row[1], row[0]) for index, row in enumerate(reader)] ) f.close()
これで複数スレッド立てて処理が出来るようです。
とりあえず実装しただけで細かいことはまだよくわかりませんが。
時間があるときにもう少し勉強したいと思います。