TWSNMPのPING処理
PINGについて
TWSNMPに限らずネットワーク監視のシステムの基本的なノードの監視方法は、PINGです。PINGはICMPというプロトコルで対象のノードにechoリクエストを送り、相手からの応答を確認するという単純な仕組みですが、
・相手が活きていることがわかる
・相手との間の応答時間がわかる
・相手との経路にあるルータがわかる
・相手との間の回線の通信速度がわかる
という、すぐれものです。SNMPの仕様を決めたCase博士が"Universal Network Management Tool=PING"と言っていたことを30年近くたった今でも覚えています。
コマンドで実行すれば、
$ ping www.twise.co.jp
PING twise.co.jp (219.118.71.18): 56 data bytes
64 bytes from 219.118.71.18: icmp_seq=0 ttl=54 time=5.436 ms
64 bytes from 219.118.71.18: icmp_seq=1 ttl=54 time=5.400 ms
64 bytes from 219.118.71.18: icmp_seq=2 ttl=54 time=4.797 ms
64 bytes from 219.118.71.18: icmp_seq=3 ttl=54 time=4.738 ms
64 bytes from 219.118.71.18: icmp_seq=4 ttl=54 time=5.284 ms
--- twise.co.jp ping statistics ---
5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 4.738/5.131/5.436/0.302 ms
のような感じです。こういう黒い画面を開いて、コマンドを実行しているだけで、すごいハッカーと思われるものです。
PINGをどう実現するか?
オリジナルの TWSNMPでは、PINGを実現するプログラムを自分で作りました。今、見返してもよくできています。(自画自賛)また、自分で作ってもよいのですが、せっかくGO言語で開発するので、何かよいものはないかと探していたら、ありました、
ありがとう! これで、1週間ぐらい開発期間を短縮できました。
使い方は、
package main
import (
"encoding/json"
"log"
"os"
"time"
ping "github.com/sparrc/go-ping"
)
func main() {
pinger, err := ping.NewPinger("www.twise.co.jp")
if err != nil {
log.Println(err)
}
pinger.Count = 10
pinger.Timeout = time.Second * 1
pinger.Run()
stats := pinger.Statistics()
json.NewEncoder(os.Stderr).Encode(stats)
}
実行すれば、
$ go run main.go
{"PacketsRecv":1,"PacketsSent":1,"PacketLoss":0,"IPAddr":{"IP":"219.118.71.18","Zone":""},"Addr":"www.twise.co.jp","Rtts":[7366000],"MinRtt":7366000,"MaxRtt":7366000,"AvgRtt":7366000,"StdDevRtt":0}
TWSNMPで使うために、いろいろ試してみまいしたが、いくつか問題がみつかりました。
・応答のない対象ノードに実施するとプログラムの動作がとまる
・沢山の対象リクエストを同時に送るとリソース不足でエラーになる
この問題は、TWSNMPに組み込む時に自分で解決できる仕組みを作ることにしました。
その後PING処理
PINGの処理は、最初に利用したパッケージではうまく動作しない部分があり、かなり悩んだすえ、最終的には、このパッケージなどを参考に、自分で作ることになりました。結果は以下のリンク
https://github.com/twsnmp/twsnmp/blob/master/src/ping.go
つづく
開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。 ソフトウェアのマニュアルをnoteの記事で提供しています。 サポートによりnoteの運営にも貢献できるのでよろしくお願います。