Zabbixで自宅のインターネット回線速度を監視する – Speedtest CLI
こんにちは。プラットフォーム技術部の飯出(いいで)です。
新型コロナウイルス感染症の対応・対策で在宅勤務が始まって早1年が経とうとしています。そのような中、オンラインでのミーティングや商談によるWeb会議も増えたわけですが、自宅のインターネット回線速度が遅く、ストレスを感じている方もいらっしゃると思います。
そして、自宅のインターネット回線速度はどの程度出ているのだろうと気になるわけですが、世間一般に出回っているツールだとWeb画面上などから操作したタイミングの速度しか計測できません。24時間365日、自宅のインターネット回線速度はどの程度出ているのだろうと思い、Zabbixを使って定期的に回線速度を監視してみます。
Speedtest CLI を使って、Linux上で回線速度を取得する
Linux上でインターネットの回線速度を取得するには、Speedtest CLI を使う方法が簡単だと思います。Speedtest を使ったことがある方は結構いらっしゃると思いますが、このツールには CLI 版がリリースされています。
Speedtest CLI のダウンロードとインストール
Speedtest CLI のページの中段、「インストールオプション」欄にサポートされているOSについて記載がありますので、こちらを参考にダウンロードとインストールを進めていきます。今回は、CentOS Stream 8 上で作業をしますので、「Fedora/Centos/Redhat」に記載された手順を参考にします。
以下の手順は、root ユーザーで実施しています。
# cd /tmp
# curl -OL https://ookla.bintray.com/rhel/ookla-speedtest-1.0.0-x86_64-linux.rpm
・・・中略・・・
# dnf install ookla-speedtest-1.0.0-x86_64-linux.rpm
・・・中略・・・
完了しました!
# which speedtest
/usr/bin/speedtest
Speedtest CLI の使い方
まずは、そのまま起動します。
# speedtest
Speedtest by Ookla
Server: fdcservers.net - Tokyo (id = 28910)
ISP: JPNE
Latency: 8.85 ms (2.03 ms jitter)
Download: 327.04 Mbps (data used: 302.7 MB)
Upload: 225.17 Mbps (data used: 396.5 MB)
Packet Loss: Not available.
Result URL: https://www.speedtest.net/result/c/********-****-****-****-************
早速、回線速度が取得できました。続いて、ヘルプを見てみましょう。
# speedtest -h
Speedtest by Ookla is the official command line client for testing the speed and performance of your internet connection.
Version: speedtest 1.0.0.2
Usage: speedtest [<options>]
-h, --help Print usage information
-V, --version Print version number
-L, --servers List nearest servers
-s, --server-id=# Specify a server from the server list using its id
-I, --interface=ARG Attempt to bind to the specified interface when connecting to servers
-i, --ip=ARG Attempt to bind to the specified IP address when connecting to servers
-o, --host=ARG Specify a server, from the server list, using its host's fully qualified domain name
-p, --progress=yes|no Enable or disable progress bar (Note: only available for 'human-readable'
or 'json' and defaults to yes when interactive)
-P, --precision=# Number of decimals to use (0-8, default=2)
-f, --format=ARG Output format (see below for valid formats)
-u, --unit[=ARG] Output unit for displaying speeds (Note: this is only applicable
for ‘human-readable’ output format and the default unit is Mbps)
-a Shortcut for [-u auto-decimal-bits]
-A Shortcut for [-u auto-decimal-bytes]
-b Shortcut for [-u auto-binary-bits]
-B Shortcut for [-u auto-binary-bytes]
--selection-details Show server selection details
--ca-certificate=ARG CA Certificate bundle path
-v Logging verbosity. Specify multiple times for higher verbosity
--output-header Show output header for CSV and TSV formats
Valid output formats: human-readable (default), csv, tsv, json, jsonl, json-pretty
Machine readable formats (csv, tsv, json, jsonl, json-pretty) use bytes as the unit of measure with max precision
Valid units for [-u] flag:
Decimal prefix, bits per second: bps, kbps, Mbps, Gbps
Decimal prefix, bytes per second: B/s, kB/s, MB/s, GB/s
Binary prefix, bits per second: kibps, Mibps, Gibps
Binary prefix, bytes per second: kiB/s, MiB/s, GiB/s
Auto-scaled prefix: auto-binary-bits, auto-binary-bytes, auto-decimal-bits, auto-decimal-bytes
[-s, –server-id=#] で計測対象サーバーを固定し、[-f, –format-ARG] で出力フォーマットを選択できますね。このオプションを使っていきたいと思います。
計測対象サーバーを固定する
[-s, –server-id=#] オプションに、計測対象サーバーのIDを指定するようです。計測対象サーバーを調べるには、[-L, –servers] オプションを使います。
# speedtest -L
Closest servers:
ID Name Location Country
==============================================================================
8407 Allied Telesis Capital Corporation Sagamihara Japan
6492 denpa893 Tokyo Japan
20976 GLBB Japan Tokyo Japan
28910 fdcservers.net Tokyo Japan
24333 Rakuten Mobile, Inc Tokyo Japan
32907 KFNET Tokyo Japan
15047 OPEN Project (via 20G SINET) Tokyo Japan
19256 Love4Taylor AT ikedatenten Lab Tokyo Japan
38241 BudgetVM Tokyo Japan
14623 IPA CyberLab Bunkyo Japan
計測対象サーバーの一覧が取得できましたので、IDを指定して回線速度を取得してみます。ここからは「OPEN Project (via 20G SINET)」サーバーを使用していきます。
# speedtest -s 15047
Speedtest by Ookla
Server: OPEN Project (via 20G SINET) - Tokyo (id = 15047)
ISP: JPNE
Latency: 8.94 ms (0.72 ms jitter)
Download: 35.33 Mbps (data used: 47.8 MB)
Upload: 36.90 Mbps (data used: 67.7 MB)
Packet Loss: 1.4%
Result URL: https://www.speedtest.net/result/c/********-****-****-****-************
計測対象サーバーを固定できましたね。
出力フォーマットに JSON 形式を選択する
[-f, –format-ARG] オプションの説明には、以下の記載があります。
Valid output formats: human-readable (default), csv, tsv, json, jsonl, json-pretty
Machine readable formats (csv, tsv, json, jsonl, json-pretty) use bytes as the unit of measure with max precision
この後、Zabbixに計測結果データを送りますので JSON 形式を指定します。
# speedtest -s 15047 -f json
{"type":"result","timestamp":"2021-02-20T10:10:54Z","ping":{"jitter":1.004,"latency":7.3579999999999997},"download":{"bandwidth":6284122,"bytes":65834040,"elapsed":10315},"upload":{"bandwidth":6623104,"bytes":90835728,"elapsed":15000},"packetLoss":4.3689320388349513,"isp":"JPNE","interface":{"internalIp":"192.168.10.100","name":"******","macAddr":"**:**:**:**:**:**","isVpn":false,"externalIp":"106.73.80.0"},"server":{"id":15047,"name":"OPEN Project (via 20G SINET)","location":"Tokyo","country":"Japan","host":"speed.open.ad.jp","port":8080,"ip":"202.222.12.78"},"result":{"id":"********-****-****-****-************","url":"https://www.speedtest.net/result/c/********-****-****-****-************"}}
Zabbix サーバーに計測結果データを送信する
ここまでの手順をバッチ化して、Zabbix サーバーに計測結果データを送信します。送信には、zabbix_sender コマンドを用います。zabbix_sender コマンドの説明はこちらです。
ここまでの手順をバッチ化する
以下のような感じで、スクリプトを書いていきます。
#!/bin/bash
SPEEDTEST_SERVER_ID=`/usr/bin/speedtest -L | grep "OPEN Project" | sed 's/^ *\| *$//' | cut -d " " -f 1`
SPEEDTEST_RESULT=`/usr/bin/speedtest -s $SPEEDTEST_SERVER_ID -f json`
ZABBIX_SERVER=127.0.0.1
ZABBIX_HOSTNAME=speedtest.net
ZABBIX_ITEMKEY=speedtest.json
/usr/bin/zabbix_sender -z $ZABBIX_SERVER -s $ZABBIX_HOSTNAME -k $ZABBIX_ITEMKEY -o "$SPEEDTEST_RESULT"
処理の流れとしては、
- 計測対象サーバーの一覧を取得し、特定のサーバー名で絞り込む。その後、ID 部分のみ抽出する。
- 抽出した ID を用いて計測を実行し、計測結果データを JSON 形式で取得する。
- zabbix_sender コマンドを使って、Zabbix サーバーに送信する。計測結果データはペイロード部に設定する。
となっています。
スクリプトを定期的に実行する
作成したスクリプトを、crontab で定期実行します。とりあえず、5分間隔で実行してみます。
*/5 * * * * /bin/bash /usr/lib/zabbix/scripts/zabbix_sender_speedtest.sh
Zabbix サーバーの設定
ここからは取得した計測結果データを、Zabbix フロントエンドで確認できるように設定していきます。Zabbix のバージョンは、5.0.8 を使っています。
アイテムの設定
まず、ホスト名を「speedtest.net」として準備します。これからの手順は、テンプレートとして作成するのがセオリーですね。(手順は割愛します)
Zabbix トラッパーを準備し、JSON 形式のデータを受け取る
アイテムを新規に作成し、次の設定をします。
- 名前: ご自由にどうぞ
- タイプ: 「Zabbix トラッパー」を選択します
- キー: 「speedtest.json」としています。zabbix_sender の -k オプションに合わせてください
- データ型: 「テキスト」を選択します
- ヒストリの保存期間: ご自由にどうぞ
依存アイテムを準備し、各フィールドの値をアイテム化する(帯域幅)
アイテムを新規に作成し、次の設定をします。
- 名前: 「Download: Bandwidth」としています(ご自由にどうぞ)
- タイプ: 「依存アイテム」を選択します
- キー: 「speedtest.download.bandwidth」としています(ご自由にどうぞ)
- マスターアイテム: 上記「Zabbix トラッパー」で設定した名前を必ず指定します
- データ型: 「数値 (整数)」を選択します
- 単位: 「bps」を記載します
- ヒストリの保存期間 / トレンドの保存期間: ご自由にどうぞ
続いて、保存前処理を設定します。
- 名前: 「JSON Path」、パラメータ: 「$.download.bandwidth」を設定します
- 名前: 「乗数」、パラメータ: 「8」を設定します
JSON Path は zabbix_sender コマンドのペイロード部に設定した JSON 形式データの階層に合わせて設定します。
また、乗数は帯域幅のみ設定します。これは、Speedtest CLI が JSON 形式で値を返す際に byte 値であるため、bps 値に変換するためには8倍する必要があるからです。
Valid output formats: human-readable (default), csv, tsv, json, jsonl, json-pretty
Machine readable formats (csv, tsv, json, jsonl, json-pretty) use bytes as the unit of measure with max precision
ダウンロード帯域幅に加え、アップロード帯域幅も追加しましょう。
名前 | キー | データ型 | 単位 | JSON Path(保存前処理) | 乗数(保存前処理) |
---|---|---|---|---|---|
Download: Bandwidth | speedtest.download.bandwidth | 数値 (整数) | bps | $.download.bandwidth | 8 |
Upload: Bandwidth | speedtest.upload.bandwidth | 数値 (整数) | bps | $.upload.bandwidth | 8 |
依存アイテムを準備し、各フィールドの値をアイテム化する(その他の値)
その他の値も、一つひとつアイテム化していきます。
名前 | キー | データ型 | 単位 | JSON Path(保存前処理) |
---|---|---|---|---|
Download: Bytes | speedtest.download.bytes | 数値 (整数) | B | $.download.bytes |
Download: Elapsed | speedtest.download.elapsed | 数値 (整数) | ms | $.download.elapsed |
Interface: External IP Address | speedtest.interface.externalip | 文字列 | $.interface.externalIp | |
Interface: Internal IP Address | speedtest.interface.internalip | 文字列 | $.interface.internalIp | |
Interface: Mac Address | speedtest.interface.macaddr | 文字列 | $.interface.macAddr | |
Interface: Name | speedtest.interface.name | 文字列 | $.interface.name | |
Interface: VPN | speedtest.interface.isvpn | 文字列 | $.interface.isVpn | |
ISP | speedtest.isp | 文字列 | $.isp | |
Packet Loss | speedtest.packetloss | 数値 (浮動小数) | % | $.packetLoss |
Ping: Jitter | speedtest.ping.jitter | 数値 (浮動小数) | ms | $.ping.jitter |
Ping: Latency | speedtest.ping.latency | 数値 (浮動小数) | ms | $.ping.latency |
Result: ID | speedtest.result.id | 文字列 | $.result.id | |
Result: URL | speedtest.result.url | 文字列 | $.result.url | |
Server: Country | speedtest.server.country | 文字列 | $.server.country | |
Server: Host | speedtest.server.host | 文字列 | $.server.host | |
Server: IP Address | speedtest.server.ip | 文字列 | $.server.ip | |
Server: Location | speedtest.server.location | 文字列 | $.server.location | |
Server: Name | speedtest.server.name | 文字列 | $.server.name | |
Server: Port | speedtest.server.port | 文字列 | $.server.port | |
Timestamp | speedtest.timestamp | 文字列 | $.timestamp | |
Upload: Bytes | speedtest.upload.bytes | 数値 (整数) | B | $.upload.bytes |
Upload: Elapsed | speedtest.upload.elapsed | 数値 (整数) | ms | $.upload.elapsed |
グラフも作ればさらに見やすく
Download: Bandwidth と Upload: Bandwidth に加え、Ping: Latency もグラフ化してみました。
雑記
この記事のテーマとはあまり関係ありませんが、以下に記載する方式にて Zabbix に監視データを送付するサンプルをよく見かけます。あまりお勧めできませんので、簡単に解説します。
外部チェック(externalscript)を使う
Zabbix のアイテム単位にバッチ処理を設定して、監視データを取得する方法です。監視間隔を Zabbix 側で設定できるメリットがありますが、1アイテム毎にバッチ処理が起動するため、Zabbix サーバーのリソースを結構消費します。
特に外部チェック用スクリプトを bash で実装した場合は、各コマンドがサブプロセスとして起動するためにプロセス起動のオーバーヘッドが掛かりますので、注意が必要です。(Python で実装すれば、多少マシになります。)
zabbix_sender をハックして、自力で送信データを組み立てる
zabbix_sender は、簡単な JSON 形式のデータを Zabbix サーバーに送信しています。
この JSON 形式のフォーマットに Zabbix のプロトコルに準拠したヘッダー部を付与することで、zabbix_sender 無しでも監視データを送信できます。
ヘッダー部は Zabbix のバージョンアップなどによって変更になる可能性もありますので、ご自身で実装する際はご注意ください。
pyzabbix.sender や ZabbixSender · PyPI というモノもございますが、Zabbix 公式のツール以外で実装する場合も、自己責任でお願いします。
Zabbixに関するお問い合わせはこちらからお願いいたします。