ネットワーク監視のため、pingで対象機器の応答時間とNG個数、NG割合を測定します。
python3-rrdtoolを使う方法もあるようなのですが、ここでは原始的にsubprocessを使います。
主なハードウェア
主なソフトウェア
- Raspberry Pi OS Buster
RRDtoolデータベース作成
RRDtoolデータベースを作成します。
応答時間
rrdtool create /home/user/rrdtool/pingtime.rrd --step 10 DS:pingtime:GAUGE:600:U:U RRA:AVERAGE:0.5:30:69120 RRA:MAX:0.5:30:69120 RRA:MIN:0.5:30:69120
NG個数
rrdtool create /home/user/rrdtool/pingng.rrd --step 300 DS:pingng:GAUGE:600:U:U RRA:MAX:0.5:1:69120
NG割合
rrdtool create /home/user/rrdtool/pingngratio.rrd --step 300 DS:pingngratio:GAUGE:600:U:U RRA:MAX:0.5:1:69120
Pythonプログラム
Pythonプログラムです。
#!/usr/bin/env python3 # -*- coding: utf-8 -*- ########## # インポート ########## import datetime import subprocess import time ########## # メイン ########## # メイン関数 # 引数:なし # 返値:なし def main(): # 変数定義、初期化 counter = 0 all_counter = 0 # コマンド作成 cmd = ["ping", "-c", "1", "-W", "1", "192.168.1.254"] # ping試し打ち(NG回避) for i in range(10): subprocess.run(cmd) time.sleep(1) # ping NGカウンタリセット時刻 m_expire = datetime.datetime.now() minute = (int(m_expire.minute / 5) + 1) * 5 if 59 < minute: expire = datetime.datetime(m_expire.year, m_expire.month, m_expire.day, m_expire.hour) + datetime.timedelta(hours=1) else: expire = datetime.datetime(m_expire.year, m_expire.month, m_expire.day, m_expire.hour, minute) try: while True: # ping NGカウンタリセット時刻を超過していた場合 if expire <= datetime.datetime.now(): # カウンタ値を記録する subprocess.run(["rrdtool", "update", "/home/user/rrdtool/pingng.rrd", "-t", "pingng", str(int(expire.timestamp())) + ":" + str(counter)]) subprocess.run(["rrdtool", "update", "/home/user/rrdtool/pingngratio.rrd", "-t", "pingngratio", str(int(expire.timestamp())) + ":" + str(counter * 100.0 / all_counter)]) # カウンタをリセットする counter = 0 all_counter = 0 # ping NGカウンタリセット時刻を更新する m_expire = datetime.datetime.now() minute = (int(m_expire.minute / 5) + 1) * 5 if 59 < minute: expire = datetime.datetime(m_expire.year, m_expire.month, m_expire.day, m_expire.hour) + datetime.timedelta(hours=1) else: expire = datetime.datetime(m_expire.year, m_expire.month, m_expire.day, m_expire.hour, minute) # ping実行(stdout:保存、stderr:破棄) response = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) # カウンタを増分する all_counter += 1 # ping結果 result = response.stdout.decode("utf-8") # ping OKの場合 if "1 received" in result: idx = result.find("rtt") avg = result[idx:].split("/")[4] print(avg) subprocess.run(["rrdtool", "update", "/home/user/rrdtool/pingtime.rrd", "-t", "pingtime", "N:" + avg]) # ping NGの場合 else: print("PING NG") # ping NGカウンタを増分する counter += 1 # 休む time.sleep(1) except KeyboardInterrupt: pass return # メイン関数 # 備考:main()に投げるだけ if __name__ == "__main__": main()
cron設定
5分毎にグラフ作成するcronです。
応答時間
1-56/5 * * * * /usr/bin/rrdtool graph /home/user/public_html/rrdtool/pingtime.png --title "ping RESPONSE TIME - 192.168.1.254 [ms]" --height 200 --width 800 --lower-limit 100 --upper-limit 500 --rigid --start end-50h --x-grid HOUR:1:HOUR:6:HOUR:6:0:"\%m/\%d \%H:\%M" --slope-mode DEF:px=/home/user/rrdtool/pingtime.rrd:pingtime:MAX DEF:pa=/home/user/rrdtool/pingtime.rrd:pingtime:AVERAGE DEF:pn=/home/user/rrdtool/pingtime.rrd:pingtime:MIN LINE2:px#FF0000:"5min(Max)" GPRINT:px:LAST:"Cur\: \%.1lf [ms]" GPRINT:px:MIN:"Min\: \%.1lf [ms]" GPRINT:px:MAX:"Max\: \%.1lf [ms]\n" LINE2:pa#00FF00:"5min(Ave)" GPRINT:pa:LAST:"Cur\: \%.1lf [ms]" GPRINT:pa:MIN:"Min\: \%.1lf [ms]" GPRINT:pa:MAX:"Max\: \%.1lf [ms]\n" LINE2:pn#0000FF:"5min(Min)" GPRINT:pn:LAST:"Cur\: \%.1lf [ms]" GPRINT:pn:MIN:"Min\: \%.1lf [ms]" GPRINT:pn:MAX:"Max\: \%.1lf [ms]" TEXTALIGN:left
NG個数
1-56/5 * * * * /usr/bin/rrdtool graph /home/user/public_html/rrdtool/pingng.png --title "ping NG count - 192.168.1.254" --height 200 --width 800 --start end-50h --x-grid HOUR:1:HOUR:6:HOUR:6:0:"\%m/\%d \%H:\%M" --slope-mode DEF:pingngmax=/home/user/rrdtool/pingng.rrd:pingng:MAX LINE2:pingngmax#FF0000:"5min" GPRINT:pingngmax:LAST:"Cur\: \%.0lf " GPRINT:pingngmax:MIN:"Min\: \%.0lf " GPRINT:pingngmax:MAX:"Max\: \%.0lf" TEXTALIGN:left
NG割合
1-56/5 * * * * /usr/bin/rrdtool graph /home/user/public_html/rrdtool/pingngratio.png --title "ping NG RATIO [\%] - 192.168.1.254" --height 200 --width 800 --start end-50h --x-grid HOUR:1:HOUR:6:HOUR:6:0:"\%m/\%d \%H:\%M" --slope-mode DEF:pingngratiomax=/home/user/rrdtool/pingngratio.rrd:pingngratio:MAX LINE2:pingngratiomax#FF0000:"5min" GPRINT:pingngratiomax:LAST:"Cur\: \%.2lf [\%\%] " GPRINT:pingngratiomax:MIN:"Min\: \%.2lf [\%\%] " GPRINT:pingngratiomax:MAX:"Max\: \%.2lf [\%\%]" TEXTALIGN:left
ランキングに参加しています。下記バナーをクリックしていただけるとありがたいです。