Rabbit Slide Show

シェルスクリプトで簡易ping監視

2013-08-24

Description

200行ぐらいの行数のシェルスクリプトでping監視をして、その結果を簡易な画像にまとめるものを作ってみた話をします。

Text

Page: 1

シェルスクリプトで
簡易ping監視
西山和広 (@znz)
LLまつり
2013/08/24

Page: 2

背景
背景
集合住宅向けの高速インターネットサー
ビス (B-CUBIC)
VPN で遠隔からルーターなどの状態確
認や設定変更
目的
その VPN の接続状態を監視したい

Page: 3

監視
Zabbix などを併用
SNMP などで詳細情報

Page: 4

Zabbix の問題点 (1)
大量ホストの登録が大変
ホスト自体の追加
これは自動登録やAPIである程度省力化可能
まとめて見るためのグラフなどの追加
特に複数ホストをまとめるのは大変

Page: 5

Zabbix の問題点 (2)
監視自体も重い
ホストごとにfpingを実行 (ping監視)
同時実行数を増やす → データベースの
コネクション数があふれる

Page: 6

簡易ping監視
登録が簡単
依存は最小限
bash, GNU coreutils, fping,
ImageMagick の convert
結果表示
単純な画像で全体像の把握だけ

Page: 7

単純な画像
ping 応答の有無のみ
応答時間なし
IPアドレスも出さない
IPアドレス順にはしている
時刻も出さない
cron で定期実行している

Page: 8

summary.html

Page: 9

画像の説明
緑: alive, 赤: unreachable
X軸: IPアドレス, Y軸: 時刻 (上が0時
で下が新しい)
最近の画像は symlink で先ほどの
summary.html から参照

Page: 10

実装 (1) データ収集
複数ホストの指定方法は bash の
brace expansion
例1: 172.16.{0..255}.254
例2: 192.168.1.{1..254}
ping 送信は fping -r 0
-r 0 でリトライせずにすぐに終わる

Page: 11

実装 (2) データ収集
collect () {
IP_PREFIX=$1
IP_RANGE=${2:-"{1..254}"}
OUT_FILE="data/$IP_PREFIX/$(date '+%Y%m%d/%H%M%S').out"
trap "rm -f $OUT_FILE" 1 2 3 15
mkdir -p "$(dirname "$OUT_FILE")"
{
eval set -- $IP_PREFIX.$IP_RANGE
for ip; do
echo "$ip"
done
} | fping -r 0 >"$OUT_FILE"
trap "" 1 2 3 15
}

Page: 12

fping の出力例
192.168.253.1 is alive
192.168.253.24 is alive
192.168.253.29 is alive
192.168.253.108 is alive
192.168.253.109 is alive
192.168.253.112 is alive
192.168.253.113 is alive
192.168.253.114 is alive
192.168.253.2 is unreachable
192.168.253.3 is unreachable
192.168.253.4 is unreachable
192.168.253.5 is unreachable
192.168.253.6 is unreachable
192.168.253.7 is unreachable
192.168.253.8 is unreachable
192.168.253.9 is unreachable
192.168.253.10 is unreachable

Page: 13

実装 (3) 画像生成
IPアドレス順は sort -V
GNU coreutils のバージョンソート
ls -v と同じ機能
画像生成
シェルスクリプトで xpm 生成
xpm はブラウザの対応に難あり
convert で png に変換

Page: 14

実装 (4) 画像生成
to_xpm () {
OUT_DIR="$1"
WIDTH=0
HEIGHT=0
for f in "$OUT_DIR"/*.out; do
HEIGHT=$[$HEIGHT + 1]
done
WIDTH="$(wc -l < "$f")"
cat <<EOF
static const char* const xpm[] = {
"$WIDTH $HEIGHT 3 1",
" c None",
"A c #00FF00",
"U c #FF0000",
EOF
for f in "$OUT_DIR"/*.out; do
echo -n '
"'
sort -V $f | awk -v ORS= '/alive/{print "A"}/unreachable/{print "U"}'
echo '",'
done
echo '};'
}

Page: 15

シェル便利
簡易なものにシェルは便利
このシステムで 200 行ぐらい
ポータブルにするため複雑な機能は避け
たい
と思ったら declare -A が bash4 依存だ
った
sort と gsort とか .../sbin/fping とか
複雑なら ruby とか使う

Page: 16

デモ

Page: 17

trap "echo $URL" 0
https://github.com/znz/
simple-ping-summary

Other slides