Zabbixで自宅のインターネット回線速度を監視する – Speedtest CLI

Zabbix

こんにちは。プラットフォーム技術部の飯出(いいで)です。

新型コロナウイルス感染症の対応・対策で在宅勤務が始まって早1年が経とうとしています。そのような中、オンラインでのミーティングや商談によるWeb会議も増えたわけですが、自宅のインターネット回線速度が遅く、ストレスを感じている方もいらっしゃると思います。

そして、自宅のインターネット回線速度はどの程度出ているのだろうと気になるわけですが、世間一般に出回っているツールだとWeb画面上などから操作したタイミングの速度しか計測できません。24時間365日、自宅のインターネット回線速度はどの程度出ているのだろうと思い、Zabbixを使って定期的に回線速度を監視してみます。

Speedtest CLI を使って、Linux上で回線速度を取得する

Linux上でインターネットの回線速度を取得するには、Speedtest CLI を使う方法が簡単だと思います。Speedtest を使ったことがある方は結構いらっしゃると思いますが、このツールには CLI 版がリリースされています。

Speedtestの回線速度計測画面

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"

処理の流れとしては、

  1. 計測対象サーバーの一覧を取得し、特定のサーバー名で絞り込む。その後、ID 部分のみ抽出する。
  2. 抽出した ID を用いて計測を実行し、計測結果データを JSON 形式で取得する。
  3. 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 オプションに合わせてください
  • データ型: 「テキスト」を選択します
  • ヒストリの保存期間: ご自由にどうぞ
アイテム画面でZabbixトラッパーを設定する

依存アイテムを準備し、各フィールドの値をアイテム化する(帯域幅)

アイテムを新規に作成し、次の設定をします。

  • 名前: 「Download: Bandwidth」としています(ご自由にどうぞ)
  • タイプ: 「依存アイテム」を選択します
  • キー: 「speedtest.download.bandwidth」としています(ご自由にどうぞ)
  • マスターアイテム: 上記「Zabbix トラッパー」で設定した名前を必ず指定します
  • データ型: 「数値 (整数)」を選択します
  • 単位: 「bps」を記載します
  • ヒストリの保存期間 / トレンドの保存期間: ご自由にどうぞ
アイテム画面でZabbixトラッパーに依存するアイテムを設定する

続いて、保存前処理を設定します。

  1. 名前: 「JSON Path」、パラメータ: 「$.download.bandwidth」を設定します
  2. 名前: 「乗数」、パラメータ: 「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: Bandwidthspeedtest.download.bandwidth数値 (整数)bps$.download.bandwidth8
Upload: Bandwidthspeedtest.upload.bandwidth数値 (整数)bps$.upload.bandwidth8

依存アイテムを準備し、各フィールドの値をアイテム化する(その他の値)

その他の値も、一つひとつアイテム化していきます。

名前キーデータ型単位JSON Path(保存前処理)
Download: Bytesspeedtest.download.bytes数値 (整数)B$.download.bytes
Download: Elapsedspeedtest.download.elapsed数値 (整数)ms$.download.elapsed
Interface: External IP Addressspeedtest.interface.externalip文字列$.interface.externalIp
Interface: Internal IP Addressspeedtest.interface.internalip文字列$.interface.internalIp
Interface: Mac Addressspeedtest.interface.macaddr文字列$.interface.macAddr
Interface: Namespeedtest.interface.name文字列$.interface.name
Interface: VPNspeedtest.interface.isvpn文字列$.interface.isVpn
ISPspeedtest.isp文字列$.isp
Packet Lossspeedtest.packetloss数値 (浮動小数)%$.packetLoss
Ping: Jitterspeedtest.ping.jitter数値 (浮動小数)ms$.ping.jitter
Ping: Latencyspeedtest.ping.latency数値 (浮動小数)ms$.ping.latency
Result: IDspeedtest.result.id文字列$.result.id
Result: URLspeedtest.result.url文字列$.result.url
Server: Countryspeedtest.server.country文字列$.server.country
Server: Hostspeedtest.server.host文字列$.server.host
Server: IP Addressspeedtest.server.ip文字列$.server.ip
Server: Locationspeedtest.server.location文字列$.server.location
Server: Namespeedtest.server.name文字列$.server.name
Server: Portspeedtest.server.port文字列$.server.port
Timestampspeedtest.timestamp文字列$.timestamp
Upload: Bytesspeedtest.upload.bytes数値 (整数)B$.upload.bytes
Upload: Elapsedspeedtest.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.senderZabbixSender · PyPI というモノもございますが、Zabbix 公式のツール以外で実装する場合も、自己責任でお願いします。

アークシステムは Zabbix Japan LLC の認定パートナー企業です。 当社はZabbixバージョン1.1の時代から監視ソリューションの活用を進め、Zabbixに関する製品・サービスの販売に加え、Zabbix関連サービスの提供を行っています。

Zabbixに関するお問い合わせはこちらからお願いいたします。
  • 株式会社アークシステムの予約・来訪管理システム BRoomHubs
  • 低コスト・短納期で提供するまるごとおまかせZabbix