Freetel SIM の通信量を Web サイトから取得し,ログに記録して,Zabbix 2.4 でグラフ化する。
Freetel SIM の通信量と料金が Web サイトから取得できるようになったので (nlog(n): Freetel のサイトをスクレイピング),これをグラフ化することにする。グラフ化ツールとしては,かつては MRTG を使っていた (Linux サーバの温度,Windows XP マシンの温度,ADSL モデムのリンクアップ速度)。最近はもっぱら Zabbix ばかりになってしまったので,今回も Zabbix を使う。
Zabbix 3.0 からは,ログファイルから数値を取得できるという新機能が搭載されたので (Zabbix 3.0の新機能:ログファイルから数値を取得 - Qiita),この機能を直接使えばできそうだが,今回のサーバは Zabbix 2.4 なので,Zabbix agent を使う従来の方式にする。エージェントがサーバとは異なる環境もあるだろうから,まだこの方式の需要はありそう。
動作環境は,Vine Linux 6.2, Apache 2.2.31, PHP 5.5.36, MySQL 5.1.73, Zabbix 2.4.8 である。Zabbix は先日アップグレードした (nlog(n): Zabbix のアップグレード (2.0.9 → 2.4.8))。Zabbix サーバと Zabbix エージェントは同じ Linux サーバ上で動作している。MVNO 業者の Freetel SIM のマイページをスクレイプする。
次のような方針とする。まず Freetel の Web サイトから数値をスクレイプしてきて (nlog(n): Freetel のサイトをスクレイピング),ログファイルに追記する。間隔は1時間に1回とする。Zabbix エージェントにログファイルの最終行を読み取らせる。Zabbix サーバでエージェントからの数値を取得してグラフ化する。この間隔はデフォルトの30秒に1回。
ログは,次のような Zabbix 風の形式にすることにした。Zabbix 風にしたからといって,特に Zabbix で取得しやすいかというと,そういうわけでもない。あくまで一例として。
pppp:YYYYmmdd:HHMMSS.NNN Phone Bytes Charge
ここで,pppp: プロセス番号,YYYYmmdd: 年月日,HHMMSS.NNN: 時刻,Phone: 電話番号 (ハイフン付き),Bytes: 通信量,Charge 料金である。
プロセス番号とかまったく意味ない。これをキーにして何かを辿れるというものではない。あくまで形式。あくまで気分。
Perl プログラムは,前回書いたものにログ出力を追加しただけである。
若干残念な点がある。Zabbix 風のログ出力では,ミリ秒までの時刻を記録している。Perl で時刻を取得するとき,よく strftime 関数を使う。これは POSIX モジュールの関数なのだが,ミリ秒の取得ができない。そこで,ミリ秒が取得できる DateTime モジュールを使うことにして,%3N というフォーマットで記録したのだが,常に値が「000」になってしまうことが分かった。DateTime を読み込んだ意味がない。だからといって,POSIX にして ".000" を追加するのもバカみたいだし,若干というよりかなり残念。
この Perl プログラムは値を標準出力するので,別途シェルスクリプトでファイルに書き込んでやる必要がある。次のようなシェルスクリプトを用意する。
これを crontab に登録して定期実行する。Freetel のサーバの負荷にならないように,1時間に1回でいいだろう。例えば freetel.sh という名前で保存する。
crontab は例えば
のように書いておくと,1時間に1回,00分のときにプログラムが起動される。
Zabbix エージェントでログファイルの最終行を取得することにする。ここでは電話番号を指定することで,その電話番号に該当する行の最新の数値をピックアップすることにした。つまり,ログファイルには複数回線の情報が書き込まれていてもよい。/usr/local/etc/zabbix_agentd.conf に設定を追記する。UserParameter の書式については 4 ユーザーパラメータ [Zabbix Documentation 2.2] を参照 (バージョン 2.4 の日本語訳は今のところ用意されていない)。
やっていることは,「*」で受け取ったパラメータが「$1」にセットされるので,これを grep の引数として使う。「*」にはハイフンつきの電話番号が入る。grep の出力で最後の1行だけを取り出し,gawk で第3フィールドだけを取り出す。gawk ではフィールドの出力は「$3」を指定するのだが,Zabbix の設定ファイル内では「$$3」とする。これが通信量である。「$$4」は料金。フィールドの番号は上で決めたログファイルの書式による。
Zabbix サーバでは,エージェントの値を受け取る設定を行う。受け取る値それぞれに Item を設定する。例えば,通信量なら,ホスト名が「Zabbix server」の Items を開いて「Create item」をし,項目には次のように記述する。
Key は Agentd の設定と合わせる必要がある。引数には電話番号を特定できる文字列を指定する。指定に失敗すると予想外の動作になる (後述)。
複数回線を契約しているなら,その Item も作成する。料金も同様に Item を作成する。
実際に実行して出来あがったグラフは以下のようなものである。これは今月分である。
通信量の推移グラフ。月の途中まで,グラフにおかしな点があることに気づく。1日に1回ずつ落ち込みがあるのだ。これは,Zabbix サーバのアイテム取得の設定で,電話番号に「070」を指定していたのが原因である。「070」にマッチする文字列は電話番号だけでなく,他にもあったのである。実は朝の7時0分は「0700」なので,これにマッチしてしまっていた。そして,「0700」を含む行は,別の回線にもあるのでその値が取得されていたのである。ここは「070-」または,正確には電話番号そのものを指定するのがよい。これは設定のミスであり,少しばかり恥ずかしいが,自戒を込めてこのまま公開する。
こちらは料金の推移グラフ。2回線分を同時に表示している。通信量のときと同様に,月の半ばまで1日1回のディップが生じている。
Freetel の Web サイトから通信量と料金を取得し,Zabbix でグラフ化した。結構面倒だが,ご利益はある。後は眺めるだけだからである。
グラフを見ていると,月の半ばで通信量が急激に上がっていることに気がついた。原因はスマホの充電と Dropbox だった。Pokemon Go のやりすぎでスマホのバッテリーが切れそうだったので,Mac の USB ポートに接続して充電をした。この時,Mac の Wi-Fi インジケータは接続を示していたが,スマホ経由のネットワークが優先されていたのである。しかも,このときに Dropbox の同期が始まっていたのを気がつかなかったので,知らないうちに大量の通信が行われていたのである。Mac でもネットワークの優先順位がつけられるとか,Wi-Fi のアイコンのあたりに何を経由して通信が行われているかの表示ができればいいのに。そうすればこのような「事故」は防げるのに…。囧rz
細かい問題点としては,Freetel から MB, GB で取得した数値は 1024 ベースでバイトに変換してログ保存するようになっているが,Zabbix で MB, GB に戻すときには自動的に 1000 ベースになってしまっていることが挙げられる。
2016年11月11日追記:
freetel.jp のウェブサイトが変更され,上記スクリプトは動作しなくなりました。最新版を GitHub に置きました (nlogcode/freetel-usage-charge)。
Master Archive Index
Total Entry Count: 1957