鱧技術

hamo_daisukiの技術メモ

grafana と influxDB で作る、ping 生死確認ダッシュボード

 経時 Ping の結果を見える化しなきゃ

お仕事をしていると「自分だけわかっていればいい」と思っていたことが、人にも分かるようにしなきゃいけないことがあるんです、結構たくさん。それで、説明なり何なり時間を使ってやってみるのですが、まぁこれが上手くいかない。お互いの普段使っている言葉や見ているものが違うと、日本人同士でも全然通じない。うんざりします。

そこで、グラフ化、見える化です。絵で見て一言「〇〇な感じのときは△△なんですよねー、だからそういう時は…」で大分説明が少なくなる。そういうわけで、一定時間ごとにPingして生死確認している結果を見える化してみました。

通常時のdashboard

通常運転dashboard

危険時のdashboard

危険なときのdashboard

上図のように、パネルに ping の返り値と経時グラフが表示され、警告値を上回るとパネルの色が変わります。完全に不通になるとそれっぽい表示になります(運用中なんでスクショとれませんでした)

バックエンドの InfluxDB へは、調査用の pc で ping して返り値を curl に乗っけてインサートしています。3日分で上書きしていきます(古いものから消えていく)

InfluxDB_webインターフェースの図

InfluxDBの状態

一応、データ提供できるように考えていたんですが、ダッシュボードで皆さん満足しているらしく「データください」とは言われたことないです。なので、本当は表示区間のみデータを残せばよいのですが、自分の休み中の状況確認用として3日間データを持たせています(え!連休って3日しか連続で取れないんですか、というのは置いといて)

超ザックリした作り方

環境づくり

まず、適当な Debian 系ディストリをそのへんの他課から流れてきた型落ちのPCにインストールします。自分はMX-18を入れました。

そして、リポジトリから InfluxDB をインストールします。influxDB、stableのリポジトリではすっごく古いんですけど、お手軽インストールしたいのでそのまま使います。(ちゃんと使うときにはマイグレーションするさ、と思っています)

grafana はリポジトリにないので、仕方ないですが Grafana Labs に取りに行きます。そして、説明にあるとおり

wget https://dl.grafana.com/oss/release/grafana_6.2.5_amd64.deb 
sudo dpkg -i grafana_6.2.5_amd64.deb 

します。ネットワークに繋がっていればさくっとインストールが終わります。シス管に話が通っていれば、簡単です。

influxDB と grafana のサービスが走っているかチェックします。systemctl なんかで見るのが筋なんですが、おっさんなので

sudo /etc/init.d/influxdb status
sudo /etc/int.d/grafana-server status

で確認します。grafana は su じゃないと「アクセスできない」とゴネられるので、はなっから sudo で実行してください。走っていないときは start してサービスを動かしてみてください。warning がでなければ(まず出ないんですが)設定の準備を始めます。

influxDBにテスト用DBを作る

curl をつかって、influxDBにテスト登録用のデータベースとメジャーメントを作ります。メジャーメントっていうのはデータベースのテーブルのようなものです。ちなみにスキーマは無いので、適当にデータを投げるとそれに合わせたデータベースとテーブルが自動生成されます。(定義は?)

例えば、test データベースの test_table メジャーメントにある hoge 列に 2 という値をインサートしたいとすると、

curl -i -XPOST 'http://localhost:8086/write?db=test&precision=s' --data-binary 'test_table hoge=2'

なんかでインサートできます。そうすると、time 列(日付&時間) と hoge 列を持ったtest_table というメジャーメントが test データベースに生成されます。time 列は必ず生成されます。ちなみに UNIX 時間を指定することで time 列の内容も指定できます。

ちゃんとインサートできたかどうか、Webインターフェースで確認できます。ブラウザで localhost:8083 にアクセスすると influxDB の Web インターフェースが開くので、右上の「database」で作成したデータベースを選び、Query で

show measurements

すると、先ほど作成したデータの measurement 名が表示されると思います。

その後、おもむろに

show * from test_table limit 10

とかって SQL的なものを書くと、データが表示されます。

うまくいかないときは、curl の内容が間違っている、とか、入力するデータが数字じゃない(テストなんでとりあえず数字を入れるのが楽です。grafanaでグラフ化するわけで、入力データは数値が想定されているっぽいです。当然 str も入りますが)また、localhost ではなく ip を使わなきゃ上手く動かないなど、色々あるかもしれません。

grafana から influxDB に接続しよう

実は自分、はじめ grafana と influxDB を docker で構成したんです、別コンテナで。その際、grafana から influxDB への接続が上手くいかなくて http access を browser で接続したんですが、ちょっと緻密なデータをぶち込んだらトラブルだらけ(grafana が落ちる)を喰らいました。で、同じコンテナにgrafana&influxDBを動かすとそれほど落ちない(あぁ、それでもなんか色々落ちましたよ)なので、接続に関して初めてトライするなら同じサーバー、または、コンテナでやるのが楽です。

Using InfluxDB in Grafana | Grafana Documentation

で、丁寧に接続の方法が書いてあるので、だいたいそのとおり(環境による)やれば接続できます。

データベース毎(なんならメジャーメントごと)にデータソースとして接続情報を作成します。test時は関係ないんですが、ちょっと凝ったことをしようとすると、メジャーメントの列構成が下手くそだとデータソースが増えてすごく面倒です。influxQL(SQL的な何か)で上手く検索できるように index を使って measurements をまとめるなどすると良いです。検索速度は…まぁ、遅くはないと思うんで。

やっと、ping の返り値を influxDBに投げてみる。

これはもう単純に shell スクリプトを cron で回すだけです。

自分はめんどくさがりなんで、ping するサーバーのリストを list ファイルに書いておいて

(適当な名前.sh)

#!/bin/bash
while read line
    do
        grep -v "#"|awk '{exec_data="ping -c 1 -q "$1;system(exec_data);}'

    done < ./list

ping を実行します。listのコメント行(文頭#)を grep -v で飛ばし、awkping -c 1 -q xxx.xxx.xxx.xxx というコマンド行を生成し、system()で実行します。ちゃんとやるときは stream を close() 使って閉じますが、省略しました。list ファイルの最終行まで1行づつ読んで実行します。

その出力をパイプで受けて AWKスクリプトで処理して、curlに投げます。ping をパイプで受けたのは、作っている時に作業を分けたというのもあるのですが、パイプのバッファを使うことでpingの値にその後の処理の影響を与えないという意味もあるんじゃないかなーと思って、作ったままそのままにしました。

curl で投げた insert 文的なものは、stat という db の pinger という measurement にデータが入るようにしました。

(適当な名前2.awk)

BEGIN{

    mesurement = "pinger";

    header="curl -i -XPOST 'http://localhost:8086/write?db=stat' --data-binary '" mesurement;

}

 

/PING/{

    exec_str=header " site=\"" $2 "\",";0

}

 

/received/{

    if($4==1){

        exec_str=exec_str "comm=" $4 ",";

    }else{

        exec_str=exec_str "comm=0,rtt=9999'";

        system(exec_str);

    }

}

 

/rtt/{

    split($4,tmp,"/");

    exec_str=exec_str "rtt=" tmp[2] "'";

    system(exec_str);

}

BEGIN で curl で投げる文章の定形部分を決めます。measurement を テストと本番用に切り替える予定があったので変数に入れています。(大規模になったら measurement を分けて…という野望もあったのですが)その後、ping の出力行に合わせて処理を書いていきます。

ping 先が生きているときに最終行は 文頭に "rtt" がつくので、マッチしたときは上手くいった出力をします。

ping 先が死んでいるときは recieved のマッチする行の 4 レコード目が "0" ( 0 received ) となるので rtt="9999" として出力します。

このスクリプトをつなぐ shell スクリプトをちょろっと書いて(機能を増やす予定)、こいつを crontab -e で cron に登録します。自分は1分毎にしました。運用していて1分毎くらいだと変化が分かりやすかったです。5分おきだと通信ロスト - 復旧が拾えないことがありました(無線区間など)。環境によると思うのでお好みで。

grafana で画面を作ろう(画面って!)

会社の人達は「ダッシュボード」って呼んでくれず「画面」って言ってきます。力尽きたので、後日書きます。ざっくりいうと、データソースえらんで、クエリ書いて、singlestat でオプション色々設定して、dashboard で配置しておしまいです。続き書きます。