APM on Elastic Cloud on Azure による Python アプリケーションの計測と可視化


皆様こんにちは！Elastic PMM/Eva の鈴木章太郎です。
この記事は、[求ム！Pythonを使ってAzureで開発する時のTips！【PR】日本マイクロソフト Advent Calendar 2020](https://qiita.com/advent-calendar/2020/azure-python)の11日目の記事です。
※　MS マーケの ◯◯ さん(元同僚でこのアドベントカレンダーのオーナー）、投稿が遅くなり申し訳ないです！
##このコンテンツの射程

今回は、Python アプリケーションの APM (Application Performance Management) データを、Elastic Cloud ( =ESS, Elasticsearch Service) on Azure で収集する方法について、ご紹介していきます。レベル的には100-200くらいです。

##Elastic Stack について
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/ea08a2dd-5a66-452a-b93f-0278c6a495e5.png)

まずは、Elastic Stack ご存じない方のために、この辺りは毎回セッションでご紹介していますが改めて。
Elasticsearch は、超高速な OSS の検索エンジンで、どこにでもデプロイができ、様々なパブリッククラウド上でも稼働します。
データは様々なソースから Beats（GO 言語で書かれている軽量データシッパー）や、 Logstash（データを加工したりエンリッチ可能な ETL ツール）で取得し、Kibana で Elasticsearch 上のデータを可視化、管理、アプリを開発などが行えます。
この 3 層を Elastic Stack と呼ぶのですが、これはローカルで Elastic の Web サイトから、バイナリを落としていただいて実行していただくことでも可能ですし、Elastic Cloud のような AWS/Azure/GCP で稼働する SaaS、Elastic Cloud Enteprise (クラウドおよびオンプレの IaaS)、Elastic Cloud on Kubernetes (クラウドおよびオンプレの Kubernetes)で実行することも可能です。おすすめは、Elastic Cloud ですね。

##Elastic Cloud on Azure デプロイ
おすすめのデプロイメントオプションとしての Elastic Cloud = ESS(Elasticsearch service) の Azure へのデプロイ手段として、一つは、[Elastic のサイト](https://www.elastic.co/jp/)からデプロイしていただく方法があります。無料トライアル（2週間）のボタンから開始してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/b2bf8bc9-45b7-9fd6-7b8d-5097549f0098.png)
そしてもう一つが、Azure (AWS/GCPも同様） Marketplace からデプロイしていただく方法です。
こちらも簡単で、メモリ容量、ディスク容量、ノード数、リージョン、などなど決めてデプロイすると、数分でインスタンスが立ち上がり、使えるようになります（もちろん後から変更できます）。是非お試しください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/83727f2c-ac62-26dd-2801-c3b28afbf408.png)
この辺りは[こちら](https://www.elastic.co/jp/blog/getting-started-with-elastic-cloud-on-microsoft-azure 
)に詳しく書かれていますので、ご参照ください。

##デプロイ終了時の注意点
必ず、この認証情報をとっておいてください。ユーザー ID は Elastic で固定ですが、パスワードはその時発行されます。.csv で保存しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/087e318b-c07c-6e1a-ab6e-78fe25f48963.png)
デプロイが終了して、Elastic Cloud にログインしたところです。僕は GCP 1つ、Azure 1つ、それぞれデプロイしてあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/b3a15510-9e24-17a1-d6e5-20a189c3ceae.png)

そしてこれらの情報も必要となるので、必要に応じてコピペして使ってください。
Elasticsearch のエンドポイントと、APM のエンドポイント、そして Cloud ID ですね。
今回は、APM エンドポイントと、シークレットトークンが必要となります。それぞれのリンクで取得しておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/5447e4b0-ec5a-28ae-fd2f-5c8ad40c81b7.png)


##Elastic Observability
さてここから少し Observability の話をさせてください。システムやアプリの監視と言う意味での、Elastic オブザーバビリティの目標は、単一のオープンスタックでエコシステム全体のエンドツーエンドの可視性を提供し、費用があまりかからない価格モデルで、これらの課題に対処することです。
これにより、何かインシデントが発生した際に MTTR (最小復旧期間） を限りなくゼロを近づけることができるようにすることです。
それは顧客に対して、最も優れた、信頼性の高い、パフォーマンスの高い体験を提供する全てのサービスが対象です。

昨今のソフトウェアの開発モデルとか、デプロイのモデル、デリバリーのモデルは、常に進化しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/913abf7a-c2e5-a1cc-26d9-10393b4aff94.png)

どんどんダイナミックなものになっています。いろいろ複雑になってきていますけれども、これが意味するところとしてはこんな感じですよね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/baaf42e0-6367-e915-2040-00ffc4f07592.png)

2015年のちょっと古いデータですが、これはある調査で、ベイエリアを中心とする様々な企業のうち65%の組織が、自社のシステムを監視するのに、10 種類以上のツールを使っているという報告です。イメージ的にはこんな感じですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/534dbc1e-40bc-2840-d8f2-33e339ddadfa.png)

結局こんな感じで監視とオブザーバビリティの課題に取り組むことになります。これは、おそらく多くの方には馴染みのある光景でしょう。監視ツールはとてもに断片化されています。何かが壊れたとき、何が壊れたのかを把握したり、可能性を排除するために5-10の異なるツールを使用することになります。モニタールームはやかましく、非効率的です。 
・　ログを見るためのツール
・　指標、グラフ、KPIを表示する方法
・　システムの可用性を定量化するツール
・　痕跡を相関させるツール
・　特定の種類のデータ（ネットワーク、クラウドなど）に対応したニッチツール

##Elastic のオブザーバビリティへのアプローチ 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/1efc41aa-d896-0fc3-a967-ab245b4c3993.png)
Elasticでは、データという最も深いレベルでの統一に焦点を当てています。
これらのデータのすべてを単一の強力なデータストアである Elasticsearch に集約しています。
データレベルでの統一は、探索と分析のすべてのレイヤーを通じた力の相乗効果を生み出す強力な単一の基盤を提供してくれます。
またライセンスも単純かつリーズナブルなモデルを採用し、データの容量のみに依存します。

##Application Performance Monitoring (APM)
さて、ここから本題の APM に話題を移しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/5b35eda9-2aa2-9069-c59b-e2fcc9825ae1.png)

ログ、APM、インフラメトリックは監視の3大要素です。3つの領域には重なり合う部分もあり、相互に関連付ける際に役立ちます。ログは、エラーが生じた痕跡を示すが、エラーの理由までは示さないでしょう。他方でメトリックはサーバー上で CPU 使用量にスパイクがあったことを示すかもしれませんが、何が原因だったかは示しません。ただし、うまく組み合わせて活用すれば、はるかに広い範囲の問題を解決できる可能性があります。

ログと APM とで得られる情報を比較してみましょう。
このようなログが取得できたとします。

```
264.242.88.10 - - [22/Jan/2018:16:38:53 -0800] "POST /checkout/addresses/ HTTP/1.1" 500 5253
```
ここで APM が捉えた内容は、最終発生日時、発生頻度、アプリケーションで処理されたか否か、という情報です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/fa75f61f-7151-bd66-1b38-d33bb96b57b4.png)
たとえば NumberParseException の箇所の例外処理の詳細を見ると、エラーが発生した回数の分布がウインドウで視覚的に表示できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/6300836d-47b1-c381-ef2d-6d58d4f1ceb1.png)
ここでは、一定の時間に数回起きているということ、一日中発生していることがわかります。
これをログだけで見ても、ログファイルの1つに対応するスタックの痕跡が見つかるだけで、APM のようにそのコンテクストやメタデータまで見つかる可能性は高くないわけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/19df4f08-f37f-a7df-51de-ff21c6269e1b.png)
そして、赤い部分はこの例外処理を実施したコード行です。そして APM が提供するメタデータが問題の正確な内容となります。
このように、プログラマーでない人間が見ても問題が正確に理解でき、チケットオープンのために必要十分な情報があるわけです。

##Elastic Application Performance Monitoring

今回は、Python + Django アプリが対象ですが、Elastic がサポートする言語は、Node.js、Python、Ruby、.NET、 Java、Go、Real User Monitoring（JavaScript）などで、今後、対応言語のさらなる追加も予定しています。また、Jaeger や OpenTelemetry 等各種のオープンスタンダードもサポートしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/9842ffb1-0bbe-33bd-66ec-591605993438.png)
インストール済みのアプリから Elastic APM へ驚くほど簡単にデータを送れます。
また必要なモジュールが見つからない場合、独自に開発することも、オープンソースコミュニティの成果物を活用することも可能です。

##Elastic APM の概要
Elastic APM は、エージェントをセットアップして、APM エンドポイントと、シークレットトークンを設定するだけで、すぐに Elasticsearch へのデータ送信が開始されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/97ec6fd0-5c15-5c9b-bc1c-602524801e14.png)
Python の場合も同様で、バージョン2.7, 3.5, 3.6, 3.7, 3.8, 3.9 に対応しています。今回僕は3.9をインストールしています。
フレームワークとしては、Django, Flask, Aiohttp server, Tornado, Starlette/FastAPIなどに対応しています。
また、モジュールとしては、Elasticsearch, SQLite, MySQL db, mysql-connector, Cassandra, 等に対応可能です。 

設定としてはこんなイメージです。先ほど、Elastic Cloud on Azure で取得した APM エンドポイントとシークレットトークンが必要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/c35dcca1-bd50-bc52-2ac8-ed757ce6ae67.png)

##Machine Learning との連携
これは応用なのでまた別稿としたいのですが、Elastic には、APM から応答時間ベースの ML ジョブを作成する機能があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/3225c247-b0b2-04d4-f203-a65a909e8c96.png)


##Visual Studio Code によるサンプルアプリの構成と実行
今回は、Form Rendering Examples をインストールします。
[ブログ記事 【Django フォームを手動でレンダリングする方法】](https://simpleisbetterthancomplex.com/article/2017/08/19/how-to-render-django-form-manually.html)
適当なフォルダを切って、VSCode を起動し、下記のような手順で実行してみてください。

```bash
git clone https://github.com/sibtc/form-rendering-examples.git

pip install -r requirements.txt

python manage.py migrate

python manage.py runserver
```

##APM Python Agent のインストール
Agent 側の操作なのでアプリケーション側にて修正します。
今回は Django の処理をモニタリングするため、Python 向けの APM Agent を利用します。
pip コマンドでインストールするだけです。

```bash
pip install elastic-apm
```

##APM Python Agent の構成 (Django) 
settings.py を開いて、INSTALLED_APPS と MIDDLEWARE に所定の値、
そして APM エンドポイントとシークレットトークンを設定します。これだけで完了です。

```python
# Add the agent to the installed apps
INSTALLED_APPS = (
  'elasticapm.contrib.django',
  # ...
)
ELASTIC_APM = {
  # Set required service name. Allowed characters:
  # a-z, A-Z, 0-9, -, _, and space
  ‘SERVICE_NAME’: ‘（一意）', ← 任意の名前(例えば WEBINAR）
  # Use if APM Server requires a token
  ‘SECRET_TOKEN’: ‘fGVbnnhItHK0PjpFOG’,　← APM ポータルから取得
  # Set custom APM Server URL (default: http://localhost:8200)　↓ APM ポータルから取得
  'SERVER_URL': 'https://d4d99add430d497aaa1eba04b5175497.apm.japaneast.azure.elastic-cloud.com:443‘,
}　　
# To send performance metrics, add our tracing middleware:
MIDDLEWARE = (
  'elasticapm.contrib.django.middleware.TracingMiddleware',
  #...
)
```
あとは Kibana ですぐにモニタリング可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33599/68e10e4b-4550-df00-1422-f61d7173529b.png)
例えば、
・　Request Per Minute
HTTP レスポンスステータスコード単位での 1分毎のリクエスト数が表示されます。
リクエスト数が急増したことが原因でレスポンスタイムが悪化したかここで判断できます。
また
・　Transactions duration, Transaction
URL パス単位での平均、95%タイルのレスポンスタイムが表示されます。
特定のパスの処理が遅い時はここを見ればすぐにわかります。

##このセッションの動画について
いかがでしたでしょうか？　ここまでご覧いただいたとおりで、
・　Elastic Cloud on Azure のデプロイも、
・　Python アプリへの APM 実装も、
・　Kibana によるモニタリングも、
すごく簡単ですので、是非やってみてください。

実際のアプリを実行したデモを見たい方、詳細な解説を聞きたい方は、こちら [Elastic APM によるPython アプリケーションの計測と可視化](https://www.elastic.co/jp/webinars/instrument-and-monitor-a-python-application-using-apm) で公開していますので、是非ご覧になってください。いくつか情報を入れて戴ければ Webinar はすぐにみれます。

今月はあと来週16日の [Elastic 7.10 新機能紹介 Webinar](https://www.elastic.co/jp/webinars/introducing-searchable-snapshots-plus-all-new-features-in-elastic-7-10?token=kixy3ro4ek&ultron=introducing-searchable-snapshots-plus-all-new-features-in-Elastic-7-10&blade=followup&hulk=email&mkt_tok=eyJpIjoiWXprd1kySTNZMll3TURoaCIsInQiOiJnZU9rYXF4SllzNElOaEt0am1VcWNMaHF1d3FhUnhRQW5cL1wvbHFDbHNUK1B4dExhK1pYcFdmNldwVnNnbkh1RUtTV1QycmZKakExVDZvOE9ybXJjc25EbDVET0hiTEJDQ203QVc4a3BqSkpOUU9jK1NoaTV0NkczQVBrdEVUcEpIIn0%3D) と、
26日の [.NET ラボ 勉強会 2020年12月](https://dotnetlab.connpass.com/event/197706/)に、登壇します。
年明けも色々イベントでの登壇を予定していますので、是非ご覧いただければありがたいです。
今後ともよろしくお願いします！

鈴木章太郎
Elastic　テクニカルプロダクトマーケティングマネージャー 
内閣官房IT総合戦略室　政府CIO補佐官