speedtest-cli が crontab で動作しなくて困る

インターネット速度計測サイトのSpeedtest.net というサイトがあります．

Speedtest by Ookla – The Global Broadband Speed Test

世界中にあるサーバのうち自分のアドレスから近いであろうサーバを選んで速度計測をしてくれるサービスです．

このサービスをcli で実行できるPython製 speedtest-cli というApache 2.0ライセンスのサードパーティのツールがあります．Debianだとパッケージもあるので導入も簡単です．

sivel/speedtest-cli: Command line interface for testing internet bandwidth using speedtest.net

$ sudo apt install speedtest-cli
$ speedtest-cli -h
usage: speedtest-cli [-h] [--no-download] [--no-upload] [--single] [--bytes] [--share] [--simple] [--csv] [--csv-delimiter CSV_DELIMITER]
[--csv-header] [--json] [--list] [--server SERVER] [--exclude EXCLUDE] [--mini MINI] [--source SOURCE] [--timeout TIMEOUT]
[--secure] [--no-pre-allocate] [--version]

Command line interface for testing internet bandwidth using speedtest.net.
-------------------------------------------------------------------------- https://github.com/sivel/speedtest-cli

optional arguments:
-h, --help show this help message and exit
--no-download Do not perform download test
--no-upload Do not perform upload test
--single Only use a single connection instead of multiple. This simulates a typical file transfer.
--bytes Display values in bytes instead of bits. Does not affect the image generated by --share, nor output from --json or
--csv
--share Generate and provide a URL to the speedtest.net share results image, not displayed with --csv
--simple Suppress verbose output, only show basic information
--csv Suppress verbose output, only show basic information in CSV format. Speeds listed in bit/s and not affected by --bytes
--csv-delimiter CSV_DELIMITER
Single character delimiter to use in CSV output. Default ","
--csv-header Print CSV headers
--json Suppress verbose output, only show basic information in JSON format. Speeds listed in bit/s and not affected by --bytes
--list Display a list of speedtest.net servers sorted by distance
--server SERVER Specify a server ID to test against. Can be supplied multiple times
--exclude EXCLUDE Exclude a server from selection. Can be supplied multiple times
--mini MINI URL of the Speedtest Mini server
--source SOURCE Source IP address to bind to
--timeout TIMEOUT HTTP timeout in seconds. Default 10
--secure Use HTTPS instead of HTTP when communicating with speedtest.net operated servers
--no-pre-allocate Do not pre allocate upload data. Pre allocation is enabled by default to improve upload performance. To support systems
with insufficient memory, use this option to avoid a MemoryError
--version Show the version number and exit
matoken@t430s:/media/matoken/rootfs/home/matoken/Videos$

出力オプションで，csvやjsonで書き出すことも可能です．

$ speedtest-cli (1)
Retrieving speedtest.net configuration...
Testing from freebit (203.0.113.0)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
Hosted by OpenGW (Shizuoka) [64.23 km]: 82.301 ms
Testing download speed................................................................................
Download: 1.51 Mbit/s
Testing upload speed......................................................................................................
Upload: 0.95 Mbit/s
$ speedtest-cli --simple (2)
Ping: 68.211 ms
Download: 8.11 Mbit/s
Upload: 0.84 Mbit/s
$ speedtest-cli --list | grep -i japan | grep -Ei 'kagoshima|miyazaki|kumamoto|ooita|fukuoka|saga|hitoyoshi' (3)
8407) Allied Telesis Capital Corporation (Sagamihara, Japan) [175.03 km]
35106) yoshis.jp (KDDI-NET) (Fukuoka, Japan) [687.23 km]
38134) NousagiNetwork(@_0rze) (Fukuoka, Japan) [687.23 km]
38947) Rikimoto (Fukuoka, Japan) [687.23 km]
18709) extride inc (Hitoyoshi, Japan) [705.48 km]
$ speedtest-cli --simple --server 18709 (4)
Ping: 122.31 ms
Download: 6.01 Mbit/s
Upload: 0.81 Mbit/s
$ speedtest-cli --csv-header (5)
Server ID,Sponsor,Server Name,Timestamp,Distance,Ping,Download,Upload,Share,IP Address
$ speedtest-cli --csv (6)
42842,Mamireimu Net Work's,Nara,2021-06-23T09:15:44.814808Z,177.32698372902544,86.096,8215354.331324884,1350756.2707027544,,203.0.113.0
$ speedtest-cli --json | jq . (7)
{
"download": 7961762.454176666,
"upload": 1054738.8634894243,
"ping": 73.207,
"server": {
"url": "http://speedtestooklaserverjapannagoyashizuoka.baobivawpvojawvianoipwqnpibvbqoubwuvbqasciboabowbcacacwcqcqx001.bar:8080/speedtest/upload.php",
"lat": "34.9756",
"lon": "138.3827",
"name": "Shizuoka",
"country": "Japan",
"cc": "JP",
"sponsor": "OpenGW",
"id": "42413",
"host": "speedtestooklaserverjapannagoyashizuoka.baobivawpvojawvianoipwqnpibvbqoubwuvbqasciboabowbcacacwcqcqx001.bar:8080",
"d": 64.2282382602239,
"latency": 73.207
},
"timestamp": "2021-06-23T09:19:28.880310Z",
"bytes_sent": 1515520,
"bytes_received": 10101900,
"share": null,
"client": {
"ip": "203.0.113.0",
"lat": "34.733",
"lon": "137.7439",
"isp": "freebit",
"isprating": "3.7",
"rating": "0",
"ispdlavg": "0",
"ispulavg": "0",
"loggedin": "0",
"country": "JP"
}
}

既定値で実行すると自分のipアドレスのgeoipで近いサーバにpingを打って近そうなサーバを探して速度テストする．(物理的には鹿児島だけどgeoipでは静岡扱いなのでその周りが使われる)

シンプルな表示

物理的に近そうな九州内のサーバを探す

物理的に一番近いサーバを指定

csvヘッダを表示(計測はしない)

csv形式で出力

json形式で出力(して jq で整形)

これをcrontabに設定して定期的に実行し，速度の変化を見てみようと思いました．

crontabに */30 * * * * speedtest-cli --csv >> ~/log/speedtest.csv を設定して30分毎に速度テストをして ~/log/speedtest.csv に書き出してみます．

$ mkdir ~/log (1)
$ speedtest-cli --csv-header > ~/log/speedtest.csv (2)
$ crontab -e (3)
$ crontab -l | grep speedtest-cli (4)
*/30 * * * * speedtest-cli --csv >> ~/log/speedtest.csv

ログ格納ディレクトリ作成

csvヘッダをログファイルに書き込み

crontab -e で以下の行を追加

crontabに登録されているのを確認

しかし，手動で実行時には失敗した頃がないのにcrontab 経由だとほぼ全てが失敗します．まれに成功することもありますが，10回に1回も成功しません．

以下のエラーが出力されます．

ERROR: Unable to connect to servers to test latency.

crontabでだけエラーとなるので，コマンドをshell script fileにしてそれを呼ぶようにしたり，リダイレクト方法を変更してみたり，sourceを見るとサーバリストの取得に失敗しているようなのでサーバを指定するようにしてみたけどサーバを指定してもサーバリストを取得するので意味がなかったりということを試していました．

もしかして毎0分，30分の実行するのが良くないのではと，crontabを以下のように書き換えて6分と36分に実行されるよう変更たところろ動作するようになりました．

$ crontab -l | grep speedtest-cli (1)
6,36 * * * * speedtest-cli --csv >> ~/log/speedtest.csv

手動でも0分丁度に実行するとエラーになることを確認しました．

$ speedtest-cli
Retrieving speedtest.net configuration...
Testing from freebit (180.131.110.140)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
ERROR: Unable to connect to servers to test latency.

ということでとりあえずきりのいい時間からずらすと動くようになりました．

実はSpeedTest公式のCLI ツールもありこれだと今回の問題は起こらないようです．
バイナリしか提供されていませんが，macOS/Windows/Linux/FreeBSD版が提供されていて，Linuxはi386, x86_64, armlf, armhf, arm64 が提供されています．

Speedtest CLI – Internet connection measurement for developers

こちらを使うと毎0分，30分に実行しても動作しました． csv, tsv, json, jsonl, json-pretty` での出力に対応しているしこちらを使うのもありかもしれません．ただsourceも無いし2019年のリリースからバージョンが上がっていないのでメンテされているのかちょっと不安です．

環境

$ dpkg-query -W speedtest-cli
speedtest-cli 2.1.3-2
$ lsb_release -dr
Description: Debian GNU/Linux 11 (bullseye)
Release: 11
$ arch
x86_64