speedtest-cliをcronで動かしてネットワーク速度のログをとる
そういうアプリがある気もしますがせっかくなのでやってみます。
https://www.speedtest.net を利用します。単発なら普通にウェブUIで計測できます。ここが提供している https://www.speedtest.net/apps/cli を利用してcliで計測できるようにします。
homebrew の tap が提供されているので案内の通りインストールします。ありがたいですね。
brew tap teamookla/speedtest
brew update
# Example how to remove conflicting or old versions using brew
# brew uninstall speedtest --force
brew install speedtest --force
インストールしたら試しに実行してみます。-f json
オプションでJSONとして出力できます。
% /usr/local/Cellar/speedtest/1.0.0/bin/speedtest -f json -u Mbps | jq
私の環境だと speedtest がPATHの通った場所にインストールされなかったのでフルパスで実行しています。何か設定を間違えているとかでしょうか。
実行すると以下のようなデータが出力されました。出力は一部マスクしています。
{
"type": "result",
"timestamp": "2021-05-02T05:54:31Z",
"ping": {
"jitter": 0.609,
"latency": 5.267
},
"download": {
"bandwidth": 11981913,
"bytes": 163142000,
"elapsed": 15003
},
"upload": {
"bandwidth": 11771331,
"bytes": 117455747,
"elapsed": 9802
},
"packetLoss": 0,
"isp": "xxxxxxxx",
"interface": {
"internalIp": "xxxxxxxx",
"name": "en0",
"macAddr": "xxxxxxxx",
"isVpn": false,
"externalIp": "xxxxxxxx"
},
"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": "xxxxxxxx",
"url": "xxxxxxxx"
}
}
cron に登録します。ログの場所はひとまず /var/log/speedtest
にしてownerをユーザにしました。ユーザのログを置いておくのってどこにするのが良いんでしょうね。
touch /var/log/speedtest # ログを記録するファイル
chown asa-taka:staff /var/log/speedtest
crontab -e # エディタが開く
crontab -e
で開いたエディタに以下の行を追加します。
*/10 * * * * /usr/local/Cellar/speedtest/1.0.0/bin/speedtest -f json >> /var/log/speedtest
これで定期実行されるようになります。
tail -f | jq
して簡易モニタリングしてみます。bandwidth
の単位がわからなかったのですがウェブUIの値と比べたところ bytes/sec な雰囲気だったので Mbps (Mbits/sec) に換算します。
tail -f /var/log/speedtest | jq '.download.bandwidth*=8/1000/1000 | { t: .timestamp, down: .download.bandwidth, up: .upload.bandwidth }' -c
ある程度時間が経つと以下のように表示されます。
{"t":"2021-05-02T05:25:27Z","down":31.30588,"up":8613088}
{"t":"2021-05-02T05:25:57Z","down":190.825168,"up":11672426}
{"t":"2021-05-02T05:30:24Z","down":178.068232,"up":7543841}
{"t":"2021-05-02T05:40:27Z","down":145.352656,"up":11128804}
:
フレッツ光の通常プランなので200Mbpsが上限ですが、割と上限いっぱい出ている感じがしますね。NUROが気になっていますが現状でそこまで不満が無いので、生活の質の向上具合で考えるとちょっと割高感があるんですよね。
OPEN Project って何だろう。
gnuplot でグラフにしてみたい。
とりあえず homebrew でインストールする。
brew install gnuplot
stackoverflow で紹介されていた alternatives
-
https://github.com/chriswolfvision/eplot
- パイプでgnuplotに渡すRubyスクリプト
-
https://github.com/glamp/bashplotlib
- Python製のグラフ描画ユーティリティ
bashplotlib を pip でインストールしてみたけどこれどこにインストールされたんだ…
hist と scatter が入っていた。
asa-taka@tailmoon ~ % pip show -v bashplotlib
Name: bashplotlib
Version: 0.6.5
Summary: plotting in the terminal
Home-page: https://github.com/glamp/bashplotlib
Author: Greg Lamp
Author-email: lamp.greg@gmail.com
License: BSD
Location: /usr/local/lib/python3.9/site-packages
Requires:
Required-by:
Metadata-Version: 2.1
Installer: pip
Classifiers:
Environment :: Console
Intended Audience :: End Users/Desktop
License :: OSI Approved :: BSD License
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
Entry-points:
[console_scripts]
hist = bashplotlib.histogram:main
scatter = bashplotlib.scatterplot:main
jq でcsvに整形する。
asa-taka@tailmoon ~ % tail /var/log/speedtest | jq -r '.download.bandwidth*=8/1000000| [.timestamp, .download.bandwidth] | @csv'
"2021-05-02T06:50:29Z",34.85248
"2021-05-02T07:00:22Z",184.470776
"2021-05-02T07:10:35Z",132.00067199999998
"2021-05-02T07:20:34Z",111.779984
"2021-05-02T07:30:25Z",170.27248
"2021-05-02T07:40:34Z",31.727864
"2021-05-02T07:50:26Z",71.454424
"2021-05-02T08:00:33Z",130.009232
"2021-05-02T08:10:28Z",159.37851999999998
"2021-05-02T08:20:18Z",191.119744
ちょっと改良。
asa-taka@tailmoon ~ % tail /var/log/speedtest | jq -r '[(.timestamp | fromdate), .download.bandwidth*8/1000000] | @csv'
1619938822,184.470776
1619939435,132.000672
scatter で出力できた。
asa-taka@tailmoon ~ % cat /var/log/speedtest | jq -r '[(.timestamp | fromdate), .download.bandwidth*8/1000000] | @csv' | scatter -c blue
------------------------------------------
| xxx x xx|
| x x |
| x |
| x x |
| |
| x |
| |
| x x |
| |
| x |
| |
| |
| |
| |
| x |
| |
| |
| x |
| x |
| x |
------------------------------------------
あまり見やすくはない。時刻文字列は受け取れないらしくて残念。あと目盛も出せない。
今度は https://github.com/chriswolfvision/eplot を使ってみた。
asa-taka@tailmoon ~ % cat /var/log/speedtest | jq -r '[.download.bandwidth*8/1000000] | @csv' | eplot -d
echo '
set style line 1 lt 1 lw 1 pt 1 ps 0.5;
set style line 2 lt 3 lw 1 pt 1 ps 0.5;
set style line 3 lt 7 lw 1 pt 1 ps 0.5;
set style line 4 lt 4 lw 1 pt 4 ps 0.5;
set style line 5 lt 5 lw 1 pt 4 ps 0.5;
set style line 6 lt 2 lw 1 pt 2 ps 0.5;
set style line 7 lt 6 lw 1 pt 4 ps 0.5;
set style line 8 lt 8 lw 1 pt 4 ps 0.5;
set style line 20 lt 7 lw 1 pt 4 ps 0.5;
set terminal dumb;
plot "/var/folders/v1/p225k3n12ds2h16xhxv0zjzc0000gn/T/eplot20210502-58630-la1u7e" with lines ls 1
'| gnuplot -persist
200 +--------------------------------------------------------------------+
| + .+ + + +..+ + |
180 |-+ +..+..+ : + : : +.....+-|
|: : : :: + : : |
160 |-: + : : :: : : : + +-|
| : ..: : : : : :: + : : |
| + : : : : : : : + : : |
140 |-+ : : : : : : : + : : +-|
| : : : : + : : + : : |
120 |-+ : : : : +: : : : : +-|
| : : : : + : : : : |
100 |-+ : : : : : : : : +-|
| : : : : : : : : |
80 |-+ : : : : : : : : +-|
| :: : : : + : : |
| : : : : : : : |
60 |-+ : : : : : : +-|
| + : :: : : |
40 |-+ + :: : : +-|
| + + + + +..+ |
20 +--------------------------------------------------------------------+
0 5 10 15 20 25
横軸を時間にできない。というか横軸をデータの出現順以外にできない。Mbpsは読み取れるようになった。
せっかくなので紹介されているもの全部試す。次は https://github.com/kroitor/asciichart これはリアルタイムで面白そうだけどシェルから流し込みづらいので一旦パス…しないで Go port の https://github.com/guptarohit/asciigraph が標準入力から流せるので試す。
asciigraph をインストールする。インストール対象はプロジェクトの cmd/asciigraph サブディレクトリ。
go install github.com/guptarohit/asciigraph/cmd/asciigraph
早速表示してみる。
asa-taka@tailmoon ~ % cat /var/log/speedtest | jq -r '[.download.bandwidth*8/1000000] | @csv' | asciigraph -h 10 -c 'Download Bandwidth (Mbps)'
192 ┤ ╭╮ ╭╮ ╭╮
176 ┼╮ ╭──╯│╭╮ │╰╮ ╭╮ │╰
159 ┤│╭╮│ │││ ╭╮ ╭╯ │ ╭─╯╰╮ │
143 ┤╰╯││ │││ ││ │ │ │ │ │
126 ┤ ││ ││╰╮││ ╭╯ │ │ │ │
109 ┤ ││ ││ ╰╯│ │ │ │ │ │
93 ┤ ││ ││ │ │ │ │ │ │
76 ┤ ││ ││ │ │ │ │ │ │
60 ┤ ││ ││ │╭╯ │ │ │ │
43 ┤ ╰╯ ││ ││ │ │ ╰╮│
27 ┤ ╰╯ ╰╯ ╰─╯ ╰╯
Download Bandwidth (Mbps)
できた。けど tail -f でリアルタイム描画が行えない。デモだとできそうなんだけど。
feedgnuplot を使ってみる。brew
で入る。
とりあえず動かしてみる。データは適当。
asa-taka@tailmoon asciigraph % seq 5 | awk '{print 2*$1, $1*$1}' | feedgnuplot --terminal 'dumb' --unset grid
25 +---------------------------------------------------------------------+
| + + + + + + + |
| |
| |
20 |-+ +-|
| |
| |
| B |
15 |-+ +-|
| |
| |
| |
10 |-+ +-|
| B |
| A |
| A |
5 |-+ +-|
| B |
| |
| + + + + + + + |
0 +---------------------------------------------------------------------+
1 1.5 2 2.5 3 3.5 4 4.5 5
feedgnuplot は eplot よりも多くのオプションを gnuplot にそのまま渡せる。
asa-taka@tailmoon asciigraph % cat /var/log/speedtest | jq -r '[.timestamp, .download.bandwidth*8/1000000] | @csv' | feedgnuplot --line --terminal 'dumb' --set 'datafile separator ","' --unset grid --ymin=0 --ymax=220
+--------------------------------------------------------------------+
| + + + + + + |
200 |-+ +-|
| ****** * *** ** ****** ** |
| * * * * * * * * * * |
| * * * * ** * * * *** * * |
150 |-+* ** * * ** * * * * * * +-|
| * * * * * * ** * * * * * |
| * * * * * * * * * * * * |
| * * * * ** * * * * * * |
| * * * * * * * * * * * |
100 |-+ * * * * * * * * * * +-|
| * * * * * * * * * * |
| * * * * * * * * * |
| * * * * * * * * |
50 |-+ * * ** * * * * +-|
| * ** * * *** |
| * * *** |
| * |
| + + + + + + |
0 +--------------------------------------------------------------------+
0 5 10 15 20 25 30 35
あとは横軸を時刻にしたい。
feedgnuplotでもasciigraphでもリアルタイム系の処理ができないのはmacのせいなのかな。
一応出力はできた。gnuplotで ,
区切りのデータを受け取ろうと --set 'detafile separater ","'
したけれどうまく動かなかったのでスペース区切りにした。
asa-taka@tailmoon asciigraph % cat /var/log/speedtest | jq -r '[.timestamp, .download.bandwidth*8/1000000] | join(" ")' | feedgnuplot --terminal dumb --unset grid --domain --line --timefmt "%Y-%m-%dT%H:%M:%SZ" --set 'format x "%H:%M"'
200 +--------------------------------------------------------------------+
| + +* + + + *** + * + **** +* * |
180 |-+ ****** * * * * * * **** * +-|
|* * * * * * * * * * * * * |
160 |*+ * * * ** * * * *** * * * * *-|
| *** * * ** ** * * * * * * * * |
| * * * * ** ** * * * * * * * * * |
140 |-+ * * * * * * * * * * * * * * * *+-|
| * * * * * * * * * * * * * * * * |
120 |-+ * * * * ** * * * * * * * * * *+-|
| * * * * * * * * * * * * * * * |
100 |-+ * * * * * * * * * * * * * *+-|
| * * * * * * * * * * * * * * |
80 |-+ * * * * * * * * * * * * * *+-|
| * ** * * * * * * * ** |
| * * * * * * * * * * |
60 |-+ * * ** ** * * * * +-|
| * * ** ** *** * * |
40 |-+ * * ** * * * +-|
| + + + + * + + ** + + + + + |
20 +--------------------------------------------------------------------+
05:30 06:00 06:3007:00 07:30 08:00 08:3009:00 09:30 10:00 10:3011:00 11:30
結局欲しい時にすぐに思い出せる方法が一番使いやすいので jq で適当に簡易スパークライン的なものを作るのが良いのではという結論になる。
asa-taka@tailmoon asciigraph % tail -f /var/log/speedtest | jq -r '.bar="=" * (.download.bandwidth*8/1000000/10) | "\(.timestamp) | \(.bar) \(.download.bandwidth*8/1000000)"'
2021-05-02T10:00:27Z | =================== 192.32652
2021-05-02T10:10:22Z | ================== 189.49224
2021-05-02T10:20:23Z | ================== 182.50232
2021-05-02T10:30:22Z | ================= 177.598632
2021-05-02T10:40:24Z | ================== 189.188096
2021-05-02T10:50:34Z | === 37.60528
2021-05-02T11:00:21Z | =================== 190.045992
2021-05-02T11:10:29Z | === 39.5848
2021-05-02T11:20:23Z | ================ 169.244216
2021-05-02T11:30:24Z | ================= 179.323128
jq に固定長で数字を出力する方法があれば嬉しい。
スパークラインは文字通り折れ線グラフのことで、この場合はデータバーというらしい。
macだと電源を入れている時以外cronが動かなかったので、Raspberry Pi 2をセットアップしてそこで動かすことにした。
Raspberry Pi 2 のネットワークインタフェースのスペックはこんな感じ。
Settings for eth0:
Supported ports: [ TP MII ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Supported pause frame use: Symmetric Receive-only
Supports auto-negotiation: Yes
Supported FEC modes: Not reported
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Advertised pause frame use: No
Advertised auto-negotiation: Yes
Advertised FEC modes: Not reported
Link partner advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Link partner advertised pause frame use: Symmetric Receive-only
Link partner advertised auto-negotiation: Yes
Link partner advertised FEC modes: Not reported
Speed: 100Mb/s
Duplex: Full
Port: MII
PHYAD: 1
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: pumbag
Wake-on: d
Current message level: 0x00000007 (7)
drv probe link
Link detected: yes
100baseT なので 100Mbps が最高値になる。契約では200Mbpsまで出るので最高値が頭打ちになってしまうが、100Mbpsを切った時間帯が把握できれば十分な気がするのでひとまずこれで良いものとする。
せっかくなのでlogrotateの設定をしてみる。音に効いたプログラムだけれど初めて使う。
別にRaspberry Piなので /
以下で実行してもいいのだけれど、ちょっと試しに実行ファイルも設定もログも ~pi
内に置くようにしてみる。
設定ファイルが以下の通りで、/etc
にあったものの構成を参考に一部そのまま持ってきた。
pi@pi2a:~ $ tree ~/.config
/home/pi/.config
├── logrotate.conf
├── logrotate.d
│ └── speedtest
pi@pi2a:~ $ cat ~/.config/logrotate.conf
# see "man logrotate" for details
# rotate log files weekly
weekly
# keep 4 weeks worth of backlogs
rotate 4
# create new (empty) log files after rotating old ones
create
# use date as a suffix of the rotated file
#dateext
# uncomment this if you want your log files compressed
#compress
# packages drop log rotation information into this directory
include /home/pi/.config/logrotate.d
# system-specific logs may be also be configured here.
pi@pi2a:~ $ cat ~/.config/logrotate.d/speedtest
~/var/log/speedtest {
rotate 8
}
include
は ~
を認識してくれなかった。~/var/log/speedtest
は認識してくれたんだけど
ログファイルが以下の通り。いい置き場が見つからなかったので /var
の構成をそのまま再現。
pi@pi2a:~ $ tree ~/var
/home/pi/var
├── lib
│ └── logrotate
│ └── status.tmp
└── log
├── speedtest
└── speedtest.1
pi@pi2a:~ $ cat ~/var/lib/logrotate/status.tmp
logrotate state -- version 2
"/home/pi/var/log/speedtest" 2021-5-4-23:45:47
speedtest.1は設定の確認のため logrotate -f
で出力したもの。 status.tmpのtmpは要らなかったかも。
crontabには以下のように登録する。10分おきに実行する。
pi@pi2a:~ $ crontab -l
*/10 * * * * /home/pi/bin/speedtest -f json >> /home/pi/var/log/speedtest
0 0 * * 0 logrotate -s ~/var/lib/logrotate/status.tmp ~/.config/logrotate.conf
ユーザのcronのログ置き場とか設定置き場って $HOME
下にするとしたらどこがいいんだろう。あまりそういうことはしないのかな。