ネットワークの遅延状況をずっと監視したい

## はじめに
リモートで働いているときは良いものの、出社するとネットの通信が重い時ありませんか？
人が多いときは特にひどくなったり。

社内・社外とのMTGは原則すべてWeb会議ツールを使っている弊社では、これはとても深刻な問題だったのです。
そこで新人の私はこのネットワーク環境の監視＆その結果報告を仰せつかり、今ではこの結果をもとにネットワーク環境を変え、どのように改善したかを観察しています。

色々と改善余地のある計測方法だと思いますが、少ない準備で誰でも手軽にできる方法ですので、お役に立てればと思い設定を記事に残します。

## 概要
Web会議を行うにあたってより重要なのは速度よりも「遅延の発生頻度と時間を抑えること」であり、Googleも300ms以上の遅延ではメディアの画質が低下すると記載があります。
[Googleのサポートページ](https://support.google.com/a/answer/7582554?hl=ja#zippy=%2C%E9%81%85%E5%BB%B6%E3%83%AC%E3%82%A4%E3%83%86%E3%83%B3%E3%82%B7%E3%82%92%E6%B8%AC%E5%AE%9A%E3%81%99%E3%82%8B)に記載されている測定をずっと行いたいため、以下ような形になりました。

* PCにUbuntuを入れ、ひたすらpingを打ち、その応答時刻をひたすら保存します。
* pingは毎秒打ちます。
* 結果は毎日S3にアップロードします。

レガシーなやり方ではあるのですが、上記に加えて諸々の背景があり末端PCとできるだけ同じ条件のデータが収集できるこのやり方にしました。
* ネットワーク機器の負荷状況収集だけでは、末端の端末がWi-Fiの状況含めどのように遅延しているか把握しにくい。
* アプライアンスの計測ツールは高スペックだがコストも高い。
* 新人のLinux/シェルスクリプトの実践の場にちょうどよかった。
* もう用途のないPCがたくさんあった...笑

以下の画像はpingの応答時刻を集めた情報の加工後のイメージです。切り替え後に応答時間が大幅に短縮されていることがすぐに分かります。
![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516891/dea849a7-b245-d506-f6a3-e8c96e2cff0e.png)

## 必要なもの
* 他の業務では使用されないPC
* 空のUSB（4GB以上）→Ubuntuインストールで使います

## 1\. PCにUbuntuをインストールする

WindowsOS上でUbuntuを稼働させる方法もありますが、WindowsUpdateなどで強制再起動がかかり、一時的にストップがかかってしまうのでオススメできません。
巷にはWindowsUpdateを防ぐ手立てがいろいろ紹介されていますし、私も最初はそれを試していたのですが、月単位で更新を防ぐ方法は見つけられず。

Ubuntuを入れる方法を紹介している記事はたくさんあるので、そちらを参考にしました。
私は日本語版でSecurity Violationエラーが出たので、英語が苦手でなければ本家からのダウンロードが安全でしょう。

## 2\. Ubuntuの設定をする

#### ①デフォルトではすぐサスペンド状態になるため、その自動サスペンドを無効にします。
```bash:terminal
$ sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
```
```/etc/systemd/logind.conf
# 以下の行を追加
HandleLidSwitch=ignore
```
```/etc/gdm3/greeter.dconf-defaults
[org / gnome / settings-daemon / plugins / power]
# 上の行があるはずなので、その直後に以下を追加
sleep-inactive-ac-timeout = 0
sleep-inactive-battery-timeout = 0
sleep-inactive-battery-type = 'nothing'
```

#### ②勝手な再起動が起こらないように自動更新を無効にします。

```/etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "0";
APT::Periodic::Unattended-Upgrade "0";
```
```/etc/apt/apt.conf.d/50unattended-upgrades
// 以下の行があるはずなのでコメントアウトする
// "${distro_id}:${distro_codename}-security"
```

蓋を閉じて放置してもサスペンドしない・電源が落ちない状態であればOKです。

## 3\. S3の設定をする
S3に任意の非公開バケットを作成し、そのバケット内への書き込み権限を持つIAMユーザーを作成します。
その後ubuntuを設定しているPCに戻り、awscliを入れてこのIAMユーザーを紐づけます。

```bash:terminal
$ sudo apt-get update
$ sudo apt-get install awscli
$ aws configure
```
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,default region nameを聞かれたら、作成したIAMユーザーのものを入力してください。output formatはtextでよいでしょう。

## 4\. シェルスクリプトを書く

シェルスクリプト初めての私はここで大いに手間取りました。"="の前後にはスペースを入れてはならないなど、シェルスクリプト特有のルールにご注意を。
置き場所は適当でよいです。今回は説明のため/home/user下に置いたこととします。

#### ①pingを1回打った結果を出力するスクリプトを書く。
sleepを挟む方法ですとpingの応答時間分の遅延が発生するので、1秒に1回実行する設定はcronで後程行います。（私のシェルスクリプトの理解が浅いだけで、遅延なくコマンドを打つ方法もあるかもしれません。）

```bash:/home/user/ping.sh
#!/bin/bash

ping_target="lens.l.google.com"
place="[計測を行う場所]"

today=$(date +"%Y%m%d")
now=$(date +"%F\t%T")

ping_result=$(ping -c 1 -w 10000 $ping_target | grep -m1 time= | cut -d "=" -f4 | cut -d " " -f1)

echo -e "$ping_target\t$now\t$ping_result\t$place" | tee -a /home/user/pinglog/${today}.txt
```

pingの確認先が[lens.l.google.com]()である理由は[グーグルのサポートページ](https://support.google.com/a/answer/7582554?hl=ja)参照です。

#### ②結果をS3にアップロードするスクリプトを書く。

以下では1日に1回、前日分をS3に送る前提で設定をしています。

```bash:/home/user/uploadtos3.sh
#!/bin/bash

yesterday=$(date +"%Y%m%d" --date '1 day ago')

LOCAL_FILE="/home/user/pinglog/${yesterday}.txt"
S3_BUCKET="s3://{格納したい場所へのパス}"

aws s3 cp $LOCAL_FILE $S3_BUCKET
```


#### ③txtファイルを保存するディレクトリを作成する。

```bash:terminal
$ mkdir /home/user/pinglog
```

## 5\. cronの設定をする

ターミナルに入り、書いたスクリプトに実行権限を与えます。（私はここが分からずかなり悩みました）

```bash:terminal
$ chmod +x /home/user/ping.sh
$ chmod +x /home/user/uploadtos3.sh
```

cronをスタートさせます。
```bash:terminal
$ sudo service cron start
```

cronの設定は以下の2行を追加することで行いました。
1行目で1分間に60回ping.shを実行する設定、2行目で毎日朝2時にuploadtos3.shを実行する設定をしています。

```bash:/etc/crontab
* * * * * user for i in `seq 0 1 59`;do (sleep ${i}; /home/user/ping.sh ) & done;
0 2 * * * user /home/user/uploadtos3.sh
```

cronを再起動します。

```bash:terminal
$ sudo service cron restart
```

## 6\. 再起動し動作を確認する

ここまで設定して再起動すれば、あとはPCを電源を確保できるところで放置するだけでよいはずです。

## 7\. さいごに

このようなPCを何台か用意すれば、改善案実行前後の比較・有線無線の比較などが容易になります。
最初にご紹介した画像は取得したデータをTableau加工したもので、横軸に時間・縦軸に応答時間を置き、設置場所の情報を色分けしています。
![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516891/dea849a7-b245-d506-f6a3-e8c96e2cff0e.png)

もっともっと良い方法もあるかと思いますが、初心者エンジニアが頑張った結果として温かく見守っていただければ幸いです。使わないPCをセットアップするだけでお手軽ですので、ぜひお試しいただければと思います。
また、