Ookla Speedtest CLIにより定期的にスピードテストを実行して、結果ログをFilebeat→Logstash→Elasticsearchと格納して、Kibanaで可視化する。インターネットが遅いときはPraeco (ElastAlert)でSlack通知することもできるようになる。
Kibanaダッシュボード
Slackアラート
監視構成
構成概要はこのようになっている。
Speedtest CLI
中核となるSpeedtest CLI。スピードテストができるサイトはUSEN、Measurement Lab、Netflix fast.comなど各種あるが、Ooklaから、Webブラウザ不要・各種OSでコマンド実行可能なSpeedtest CLIが提供されている。
初回実行時にEnd User License Agreementに同意する。
C:\app\ookla-speedtest>speedtest ============================================================================== You may only use this Speedtest software and information generated from it for personal, non-commercial use, through a command line interface on a personal computer. Your use of this software is subject to the End User License Agreement, Terms of Use and Privacy Policy at these URLs: https://www.speedtest.net/about/eula https://www.speedtest.net/about/terms https://www.speedtest.net/about/privacy ============================================================================== Do you accept the license? [type YES to accept]: YES License acceptance recorded. Continuing.
CLIからも同意可能
speedtest --accept-license
今回は、一般ユーザ環境のWindows PCで実行する。タスクスケジューラで定期実行させるためにbatファイルを作成する。
@echo off set YYYY=%date:~0,4% set MM=%date:~5,2% set YYYYMM=%YYYY%%MM% C:\app\ookla-speedtest\speedtest.exe -f json -v -s 48463 >> C:\app\ookla-speedtest\log\PC-speedtest_%YYYYMM%.log 2>&1
オプション | 内容 |
---|---|
-f json |
結果ログをJSON形式で出力させる。 |
-v |
エラー発生時などログが追いやすくなる。 |
-s 48463 |
テスト先を固定する。自動選択だとエラー率高い... |
このような結果が得られる。(整形済み)
{ "type": "result", "timestamp": "2022-04-29T11:57:36Z", "ping": { "jitter": 0.16800000000000001, "latency": 7.2350000000000003 }, "download": { "bandwidth": 25663582, "bytes": 233639723, "elapsed": 9102 }, "upload": { "bandwidth": 32094379, "bytes": 188270165, "elapsed": 5909 }, "packetLoss": 0, "isp": "Softbank BB", "interface": { "internalIp": "x.x.x.x", "name": "", "macAddr": "xx:xx:xx:xx:xx:xx", "isVpn": false, "externalIp": "x.x.x.x" }, "server": { "id": 48463, "host": "speed.udx.icscoe.jp", "port": 8080, "name": "IPA CyberLab 400G", "location": "Tokyo", "country": "Japan", "ip": "219.100.92.228" }, "result": { "id": "56bf915e-c442-4524-b2ee-a05203a8a4d2", "url": "https://www.speedtest.net/result/c/56bf915e-c442-4524-b2ee-a05203a8a4d2", "persisted": true } }
テスト先サーバは speedtest --servers
で確認できる。
>speedtest -v --servers Closest servers: ID Name Location Country ============================================================================== 20976 GLBB Japan Tokyo Japan 21569 i3D.net Tokyo Japan 38241 BudgetVM Tokyo Japan 28910 fdcservers.net Tokyo Japan 24333 Rakuten Mobile, Inc Tokyo Japan 44988 Misaka Network, Inc. Tokyo Japan 48463 IPA CyberLab 400G Tokyo Japan 14623 IPA CyberLab Bunkyo Japan 8407 Allied Telesis Capital Corporation Sagamihara Japan 6087 Allied Telesis Capital Corporation Fussa-shi Japan
ログローテーションの仕組みは割愛し、月次にしてファイル数を少なく抑える。
タスクスケジューラ
Windowsのタスクスケジューラでbatを5分間隔で定期実行する。Linuxの場合はshellスクリプトをcronなどで実行すればよい。
※数百MBのダウンロード/アップロードが発生し回線を圧迫する恐れがあるので注意。
Filebeat
Filebeatでbat実行で出力されるログを読み、Logstashに送信する。(インストール手順は割愛)
C:\app\filebeat --- filebeat.yml --- filebeat.config: modules: path: ${path.config}\\modules.d\\*.yml reload.enabled: false filebeat.inputs: - type: log enabled: true paths: - C:\app\ookla-speedtest\log\PC-speedtest_*.log fields: log_system: intra log_type: speedtest output.logstash: hosts: ["<LOGSTASH>:5044"] ssl.enabled: true ssl.verification_mode: certificate ssl.certificate_authorities: [C:\app\filebeat\certs\elasticsearch-ca.pem] logging: level: info to_files: true to_syslog: false json: true files: path: C:\app\filebeat\log name: 'filebeat' keepfiles: '7' permissions: '0644' metrics.enabled: false name: PC monitoring.enabled: true monitoring.cluster_uuid: <UUID> monitoring.elasticsearch: hosts: ["<ELASTICSEARCH>:9200"] username: "beats_system" password: "PASSWORD" protocol: "https" ssl.enabled: true ssl.verification_mode: certificate ssl.certificate_authorities: [C:\app\filebeat\certs\elasticsearch-ca.pem]
Logstash
LogstashでログをElasticsearch用にフィールド分けする。ログ形式をJSONとしているため、grokで正規表現によるパースは不要。Pipeline-to-Pipelineの機能でfilter設定ファイルを分割することで運用性を向上させている。
beats_server.conf
input { beats { port => 5044 ssl => true ssl_verify_mode => none ssl_key => "/etc/logstash/certs/logstash.p8.key" ssl_certificate => "/etc/logstash/certs/logstash.crt" } } output { if [fields][log_system] == "intra" { } else if [fields][log_type] == "speedtest" { pipeline { send_to => "intra.speedtest" } } } }
結果ログのdownload.bandwidth
, upload.bandwidth
はBytes per secのため、8倍してbits per secにする。
intra.speedtest.conf
input { pipeline { address => "intra.speedtest" } } filter { if [fields][log_type] == "speedtest" { json { source => "message" } if [download][bandwidth] { ruby { code => " event.set('[download][bps]',event.get('[download][bandwidth]').to_i*8) event.set('[upload][bps]',event.get('[upload][bandwidth]').to_i*8) " } } } mutate { add_field => { "[ecs][version]" => "1.10.0" "[event][kind]" => "event" "[event][category]" => "network" "[event][type]" => "info" "[event][outcome]" => "unknown" } } date { match => ["timestamp", "ISO8601", "MMM dd HH:mm:ss yyyy", "MMM d HH:mm:ss yyyy"] target => "@timestamp" #timezone => "Asia/Tokyo" } } output { elasticsearch { ssl => true ssl_certificate_verification => true cacert => "/etc/logstash/certs/elasticsearch-ca.pem" ilm_enabled => true ilm_rollover_alias => "intra.speedtest" ilm_policy => "intra.speedtest" hosts => ["<ELASTICSEARCH>:9200"] user => "elastic" password => "${ES_PWD}" manage_template => true ecs_compatibility => "v1" } }
Elasticsearch
個別の設定は不要。数値が期待通り扱われないような場合はIndex Templateでフィールド設定を調整する。
Kibana
冒頭の通り、このようなダッシュボードを作成した。
Windows Updateが配信されて急激にインターネット網が輻輳しており、朝7時から速度が低下していき、9時には2Mbps程度しか出ていない。輻輳はプロバイダー網内で発生していたため、従来のSNMPやMRTGによる帯域監視では、ただトラフィックが少ないようにしか見えない。NetFlowなどを活用すればコネクションが長時間化したり、TCP再送が増えていそう。
アクセス元回線グローバルIPの通り、回線を切り替えることで輻輳している網を回避した。
パネル | 対象フィールド | 備考 |
---|---|---|
ダウンロード速度[bps] | download.bps |
最新値 exists でフィルタしてエラー回避 |
アップロード速度[bps] | upload.bps |
同上 |
ダウンロード速度[bps] | download.bps |
平均値 |
アップロード速度[bps] | upload.bps |
平均値 |
パケットロス | packetLoss |
|
Ping遅延[ms] | ping.latency |
|
Pingゆらぎ[ms] | ping.jitter |
|
テスト先サーバ | server.host |
|
アクセス元回線グローバルIP | interface.externalIp |
|
warning: テスト失敗 | level |
テストに失敗状況を可視化 |
テスト結果リンク
Speedtest CLIでのテスト結果は result.url
から通常のWebブラウザ版と同様に確認できる。
このダッシュボードでは下記のScripted fieldsにより result.link
としている。
Scripted fieldsの機能で Format: Url
とすることでクリック可能なリンクのフィールドとなる。(deprecatedになっていますが...)
エラー時は result.link
は空になるので、存在チェックした上で取得。
if (doc['result.url'].size() == 0) { return "" } else { return doc['result.url'].value }
Praeco (ElastAlert)
情シスでイントラ環境を監視する場合、ユーザより先にインターネット遅延に気付く必要があるので、download.bps
でしきい値Slackアラートする。
Praecoについてはこちら ※記事中のバージョンは古いので最新版を要確認
生成されるElastAlert設定はこちらの通り。
filter: - query: query_string: query: 'download.bps:*' index: intra.speedtest metric_agg_key: download.bps metric_agg_type: avg min_threshold: 100000000 name: intra.speedtest.download.bps_slow query_key: agent.hostname
まとめ - Speedtest CLI & Elastic Stackで回線速度を可視化・監視する
Ookla Speedtest CLIを定期実行し、結果をElastic Stackに集約することで、インターネット回線の速度を可視化・監視することができるようになる。従来のSNMP・MRTG・NetFlowなどによる監視とは異なり、よりユーザ目線での監視ができるのが画期的で、ネットワークの運用レベル向上が期待できる。