ThousandEyesを使って快適なAPEX Legendsライフを実現する


<h1>はじめに</h1>
この記事はシスコの有志による Cisco Systems Japan Advent Calendar 2021 (2枚目）の 22日目の記事です。
　2021年版 1枚目: https://qiita.com/advent-calendar/2021/cisco
　2021年版 2枚目: https://qiita.com/advent-calendar/2021/cisco2 (これ)

今年は私の趣味であるゲーム、特にAPEX Legendsというタイトルについてなんとか記事を書いてみたいというのもあり、今流行りのFull Stack Observabilityの一翼を担う製品である<b><a href="https://www.cisco.com/c/ja_jp/products/cloud-systems-management/thousandeyes-network-application-synthetics/index.html">「ThousandEyes」</a></b>を活用できないか考えてみました。

余談ですが、社会人e-sportsリーグのAfter 6 Leagueという大会のAPEX Legends部門にシスコとして参加しているので、ぜひ応援をお願いします！

<h1>ThousandEyesとは</h1>

![TE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/196f12a7-6e32-2499-1fee-6223729320e0.png)

これまでのネットワーク監視はSNMP, NetFlow, Syslog, パケットキャプチャなど、ネットワーク機器から送られてきた情報を収集し、主にイントラネット内のネットワークの監視を行ってきました。

しかし、これだけではあくまでイントラネット内しか見ることはできず、インターネット側の情報は得ることができません。

昨今SaaS利用が増加し、Microsoft365を初め数々のWebアプリケーションに接続する機会が増えてきたのにイントラだけ監視しても、、、。

そこでThousandEyesの登場です！

ThousandEyesは”エージェント”と呼ばれる、監視用トラフィックを送信し、ユーザーアプリの動作をシミュレーションする自発検知型の監視ツールを利用することで、TCP, ICMPトラフィックを監視対象に送信、パストレースや遅延・パケロスの監視を行います。

エージェントは主に3種類に分けられます。
<img width="900" alt="Agent.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/6eb530db-062e-3568-612f-1c0368dd112b.png">

こちらの画像にあるようにユーザー端末・仮想マシン・ネットワーク機器内にエージェントをインストールするだけでなく、すでに各国のクラウド上に配置されているThousandEyesのエージェントもあり、利用することが可能になっています。


<h1>ThousandEyesを使ってやってみたこと</h1>
今回はThousandEyesのエンタープライズエージェントを使ってAPEX Legendsへのネットワーク品質の確認をやってみようと思います。

実際にゲームをしていると日によって遅延がひどく、ミリ秒単位の遅延によって勝敗が左右されることもあるAPEX Legendsにおいて、ネットワーク品質は非常に重要な要素となっていることを痛感します。

もしパケロス・遅延が発生した場合、サーバ側の問題だけではなく、途中の経路に問題がある可能性も考えられますので、退勤後から寝るまで一分一秒も無駄にしたくない社会人ゲーマーの方々はすぐさまサーバー変更をし、最適なサーバー選択をする必要があるということです。

:::note info
APEX Legendsでは東京に複数のサーバーが存在し、ユーザーはゲーム内で最適なサーバーにアクセスするようにデフォルトでは設定されていますが、ユーザー側で任意のサーバーを選択することもできます。
:::

これらの問題に対して能動的に対処できる仕組みが作れれば、より快適なAPEX Legends環境を整備し、勝率も上がるのではないでしょうか！？

今回は単純にネットワークの品質確認を行うだけでなく、申し訳程度に結果をシスコのメッセージングツールであるWebexにAPIを利用して表示するといった連携をしてみました。

<h1>エージェントのインストール</h1>

先述したようにThousandEyesには主に三種類のエージェントを利用することができます。

今回は

<b>①自宅に設置されたエージェントからAPEX Legendsのサーバーまで</b>
　→　エンタープライズエージェント
<b>②自宅とは別の回線事業者のエージェントからAPEX Legendsのサーバーまで</b>
　→　クラウドエージェント

この二種類のエージェントを利用し、APEX Legendsへの通信品質監視を行いたいと思います。

<br>

まず最初に自宅にエンタープライズエージェントを設置してみようと思います。

エンタープライズエージェントは様々なインストール方法を選択することができますが、昔自宅の家電をIoT化した時に使っていたRaspberry Pi 3がころがっていたのでこれを使ってみようとしましたが、、、。

https://blog.thousandeyes.jp/installing-an-enterprise-agent-on-a-raspberry-pi-device

<img width="600" alt="RP4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/dd9cd0fc-1d10-0666-af06-4f5ebf5f35b9.png">

このようにThousandEyesではRaspberry Pi 4が対応しているようです、、、。

これはCPUアーキテクチャの問題かなと思いますが、面倒なので別の手段を模索しました。

<br>

次に考えたのがWindows 10 Proで使えるHyper-Vを利用する方法です。

https://docs.thousandeyes.com/product-documentation/global-vantage-points/enterprise-agents/installing/enterprise-agents-hypervisor-installation

今までWindows 10 ProのHyper-Vなるものを使ったことがなかったのですが、備忘録的にも方法を記載させていただきます。

<br>

<details><summary>Hyper-Vへのエージェントインストール方法</summary><div>

<br>

まず、ThousandEyesのダッシュボードより[Cloud & Enterprise Agents] → [Agent Settings] → [Add New Enterprise Agent]でHyper-V用のインストールファイル（zipファイルで圧縮されています）を入手します。

その後Hyper-V Managerより先ほどのインストールファイルを用いて仮想マシンをインポートします。

:::note info
Hyper-Vを有効にするためにはBIOSでIntel CPUだとVirtualization Technology、AMD CPUだとAMD Virtualization(AMD-V, AMD SVM)を有効にする必要がありますのでご注意ください。（ここで少しハマりましたｗｗ）
:::

このような画面でインストールがスタート。

<img width="600" alt="Agent起動.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/62636555-33e2-47b9-099e-aaf5eeb5d21a.png">

Nを押してネットワーク設定をしてくださいとのガイド画面が出てきます。（NかMかわかりづらい）

<img width="800" alt="ネットワーク設定.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/b1b1589f-b503-e954-54f0-c6418a44a7c8.png">

ホスト名を設定し

![Hostnamee.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/c979d0ca-4efe-9bf1-be52-00a130eadf38.png)

DHCPを利用するかStaticでIPアドレスを割り当てるかを選択します。

![DHCP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/8d2b8de1-b174-9a3a-57af-ab7d7a712b76.png)

IPv6設定を選択

![v6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/09294695-c946-7296-4a17-af30f531763c.png)

その後DNSをどうするかといったことを聞かれ、環境通りに答えるとネットワークインターフェースの設定が始まります。
この間しばらく待ちます。

![NetworkConfig.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/a2126ff8-fe33-80a3-d7bd-63fd6b2fc27f.png)

ここでトラブル発生で、そもそも仮想マシンがDHCPでIPアドレスを取得できないような設定になっていました。
VMWareのESXiとも同じで仮想スイッチがあり、その設定で接続ネットワークをどこにするか選べるんですね。

![vSwitch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/e35793d5-581c-c637-498e-134168cb9735.png)

以上でやっと仮想アプライアンスにIPアドレスが割り振られました！

![Success.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/1fc0e941-ea3a-2479-8c42-b999aa61c54a.png)

割り振られたIPアドレスに対しブラウザからログインをしろと書いてあるのでログインしてみます。
書いてあるとおりユーザー名は"admin"、パスワードは"welcome"がデフォルトになっているようです。
ログイン後新たなパスワードの設定を求められます。

<img width="600" alt="GUI.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/f62b3709-a153-8a01-51df-f60b2ba5a8da.png">

Accout Group Tokenとやらを求められるのですが、これはThousandEyesのダッシュボード上から取得する必要があります。

<img width="600" alt="Token.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/fe49663b-5a3a-ac2f-0bd9-ec35c7b0441d.png">

場所は簡単で、先ほどのHyper-V用仮想マシンインストーラーのダウンロードページからトークンは取得できます。

<img width="600" alt="Token1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/8b725cad-b991-994c-974d-afb3d6476012.png">

最後に自動的にチェックが走り、インストール完了です！

<img width="600" alt="Review.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/94745d4c-5b8b-1f99-3c52-0add8cc50659.png">

しばらくするとThousandEyesのダッシュボード上にもエンタープライズエージェントを確認することができます。

<img width="600" alt="Windows10Agent.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/bf8a7a2f-c73c-9679-69c3-cdc652317375.png">

</div></detail>

<h1>テスト作成</h1>

エージェントのインストールが終了したらテストを作成します。

テストの内容は下の画像のような形で設定でき、”どれくらいの間隔でテストをするか”　”どの通信先に対してテストをするか”などといった項目を選択していきます。

APEX LegendsのサーバーについてはAPEX Legendsの運営を行っているEAのコミュニティに記載されていました。

https://answers.ea.com/t5/General-Discussion/Packet-loss-need-server-IP-for-ISP/td-p/10035564

また、コミュニティ内に記載されていたIPアドレスと実際のゲーム内で利用されているIPアドレスの整合性を確認するためにWiresharkでパケットキャプチャも実施し、確認を取りました。

![Testconfig.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/ab06df93-708f-982a-c353-c70f9112871d.png)

このように、日本国内に配置されているサーバー6つに対してICMPを1分単位で送信し、ネットワーク品質を確認するテストを作成しました。

通信の送信元・送信先としては

自宅のエンタープライズエージェント　→　APEX Legends Server
NTTに配置されたクラウドエージェント　→　APEX Legends Server
KDDIに配置されたクラウドエージェント　→　APEX Legends Server

これら3種類でテストを実施します。

![Test一覧.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/ff7dbeb3-6fcf-80b9-b33c-d25aa7161ea0.png)

<h1>アラート作成</h1>


ここまでできれば、各エージェントがAPEX Legendsのサーバーに対して設定したテスト内容を元に定期的にテストを実行するようになります。

これらの情報はThousandEyesのダッシュボード上で確認することができます。

![Result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/572b736c-cd68-4a8e-349d-3e6bf1d96a0c.png)

![T2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/b3e21448-f00c-3192-3da5-a22c0c045133.png)

テストの詳細を確認するとテストを実行しているエージェントからサーバーまでの経路情報や各ホップ間の遅延も確認が可能です。

エージェントからサーバーまでの経路内で”どこ”に障害が発生して"どのくらい"遅延やパケットロスが発生しているのかといった情報がひと目でわかるようなGUIになっています。

<br>

これらのテスト結果でもし障害が発生していることがわかった場合、メールやAPIによる通知を行うことができます。

Alert Ruleというアラートのための条件を事前に設定することで、環境に合ったアラートを独自に設定することが可能なのですが、今回はテスト用ということで非常に厳しい条件でアラートを設定してみました。

・下記いずれかの条件に合致した場合アラートを出す
・パケットロスが3%以上
・遅延が5ms以上

![Alert Rule.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/e793f195-89eb-fc29-ab30-fc847cdc1433.png)

パケットロスが○%以上になったら・・・
遅延が○ミリ秒以上になったら・・・

といった条件をAND, ORなどで設定することも可能で、複数のエージェントで監視を行っている場合、その中のエージェントの○○台が条件に合致したらといったような細かい条件設定を行うことも可能になっています。

現在Activeのアラートについては下のように表示されます。

![Alert詳細.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225281/8873a66c-a14a-b5bc-f8b7-246bfe7b9c69.png)

<h1>API連携</h1>

ThousandEyesのAPI連携は非常に簡単です。

ThousandEyes Developer ReferenceというドキュメントにThousandEyesで利用できるAPIとその利用方法などが記載されています。

https://developer.thousandeyes.com/

今回はThousandEyesのアラートを取得し、WebexのBOT機能でスマートフォンなどに通知するような連携を行おうと思います。

<br>

アラートのAPIについては下記Referenceで説明されています。

https://developer.thousandeyes.com/v6/alerts/#/alerts

アラートを取得するのは非常に簡単で↓のようなコマンドで確認することができます。

```
$ curl https://api.thousandeyes.com/v6/alerts.json \
  -u noreply@thousandeyes.com:g351mw5xqhvkmh1vq6zfm51c62wyzib2
```

noreply@thousandeyes.comはThousandEyesに登録されているユーザーID（メールアドレス）、コロン以下の文字列に関してはAPIのトークンになっており、ThousandEyesのダッシュボードより[Users and Roles] → [User API Tokens]より生成することが可能です。

実行すると↓のようなBodyが返ってきます。

```json
{
    "alert": [
        {
            "alertId": 2783,
            "testId": 822,
            "ruleId": 142,
            "testName": "thousandeyes.com A",
            "active": 1,
            "ruleExpression": "((probDetail != \"\"))",
            "dateStart": "2012-12-13 13:15:00",
            "violationCount": 6,
            "ruleName": "Default DNSSEC Alert Rule",
            "createLinks": true,
            "permalink": "https://app.thousandeyes.com/alerts/list?__a=75&alertId=2783",
            "type": "DNSSEC",
            "agents": [
                {
                    "agentId": 12,
                    "agentName": "Hong Kong",
                    "dateStart": "2012-12-13 13:15:00",
                    "active": 1,
                    "metricsAtStart": "Error details: \"No DNSSEC public key(s) for thousandeyes.com A\"",
                    "metricsAtEnd": "Error details: \"No DNSSEC public key(s) for thousandeyes.com A\"",
                    "permalink": "https://app.thousandeyes.com/alerts/list?__a=75&alertId=2783&agentId=12"
                },
                ...
            ],
            "apiLinks": [...]
        }
    ],
    "pages": {
        "current": 1
    }
}
```
<br>

本当はjsonを成型しようと思ったのですが、今回はとりあえずそのままの状態でWebexに投稿するBOTプログラムを作成します。

Webexでのメッセージ生成のAPIは下記ドキュメントにまとめられています。

https://developer.webex.com/docs/api/v1/messages/create-a-message

メッセージ生成をBOTにやらせるためにはWebexのRoom IDやBOTのAccess Tokenの取得などをしなければならないのですが、様々な記事でまとめられているため今回は割愛させていただきます。

最終的に利用したスクリプトは下記になります。

今回はPythonで書いてみました。

```python
#!/usr/bin/env python3
from webexteamssdk import WebexTeamsAPI
import requests
import json

BOT_ACCESS_TOKEN = "利用するBOTのAccess Token"
ROOM_ID = "投稿するRoomのID"

response = requests.get('https://api.thousandeyes.com/v6/alerts.json', auth=('ThousandEyesのID', 'ThousandEyesのAPIトークン'))

api = WebexTeamsAPI(access_token=BOT_ACCESS_TOKEN)
messages = api.messages.create(roomId=ROOM_ID, text=response.text)
print(messages)
```
実行結果としては↓のような形になり、WebexにBOTからアラート内容の投稿が行われます。
無事アラート内容を取得できていることがわかります。

```json
{
	"alert": [
		{
			"active": 1,
			"agents": [
				{
					"active": 1,
					"metricsAtStart": "Packet Loss: 100%",
					"metricsAtEnd": "",
					"agentId": 390046,
					"agentName": "Windows10",
					"dateStart": "2021-12-20 16:25:00",
					"permalink": "https://app.thousandeyes.com/alerts/list/?__a=213626&alertId=101408959&agentId=390046"
				}
			],
			"alertId": 101408959,
			"dateStart": "2021-12-20 16:25:00",
			"apiLinks": [
				{
					"rel": "related",
					"href": "https://api.thousandeyes.com/v6/tests/2493589"
				},
				{
					"rel": "data",
					"href": "https://api.thousandeyes.com/v6/net/metrics/2493589"
				}
			],
			"permalink": "https://app.thousandeyes.com/alerts/list/?__a=213626&alertId=101408959",
			"ruleExpression": "((loss >= 3%) || (Auto(avgLatency >= 5 ms)))",
			"ruleId": 1839939,
			"ruleName": "APEX Legends",
			"testId": 2493589,
			"testName": "APEX Legends Tokyo-GCE1",
			"violationCount": 1,
			"type": "End-to-End (Server)"
		},
＜後略＞
```

<h1>最後に</h1>

jsonの成型などまだまだ改善の余地があるのですが、ThousandEyesのAPI自体は非常に多く用意されており、まだまだ活用の可能性は多いと思っています。

前々からやりたいと思っていた記事の内容として「Network as a Trap - ネットワーク機器で狩猟してみた」という記事を書こうと思っていたのですが、コロナの影響で実現できずで、来年こそは実現したいと考えています、、、。

<h1>免責事項</h1>
本サイトおよび対応するコメントにおいて表明される意見は、投稿者本人の個人的意見であり、私の所属する組織の意見ではありません。本サイトの内容は、情報の提供のみを目的として掲載されており、私の所属する組織や他の関係者による推奨や表明を目的としたものではありません。各利用者は、本Webサイトへの掲載により、投稿、リンクその他の方法でアップロードした全ての情報の内容に対して全責任を負い、本Web サイトの利用に関するあらゆる責任から私の所属する組織を免責することに同意したものとします。