はじめに
本記事はAWS環境でCloudWatch Syntheticsを使用して、API監視を行うための方法について記載しています。
クラウド環境におけるシステム監視を行うためには、クラウドを提供するサービスプロバイダーによってビルトインされたモニタリングシステムや、Datadogなどサードパーティ製ツールを使用するなどの手段があります。
AWSではモニタリングシステムとしてCloudWatchが無料で利用できます。
Syntheticsの監視についてもサードパーティ製ツールを使用せずに、コストを下げてAWSでインテグレーションしたモニタリングシステムを構築できます。
一見便利そうなSyntheticsですが、仕様が分かりにくかったり、痒い所に手が届かない部分もあります。
本記事ではSyntheticsを使ってたナレッジについてまとめました。
CloudWatch Synthetics
日本ではAPIなどエンドポイントに対する監視のことを外形監視といった表現が多いですが、AWSはDatadogと同じSyntheticsと呼び、CloudWatchのSynthetics Canariesとして提供されています。
CloudWatch SyntheticsではAPIなどエンドポイントに対する死活監視及び障害監視や、取得したメトリクスを利用した性能監視が実現できます。
また、CloudWatch Syntheticsの動作環境は以下の通りです。
- スケジュールに沿って実行可能なスクリプトであるCanaryを作成し、APIなどエンドポイントをモニタリングできます。
- Node.jsまたはPythonで記述されたスクリプトをサポートし、HTTP/TTPSプロトコルの両方で動作します。
- 内部的な仕組みとしてCanaryで作成したスクリプトは、Lambda関数として作成されます。
テンプレートで用意されているCanaryのスクリプトで要件を満たせる場合は、テンプレートでも問題ないと思います。
CloudWatch Syntheticsの仕様を踏まえて、Pythonなどサードパーティライブラリを使用する際は少し工夫が必要です。
例えば、HTTPリクエストに対するResponse timeを条件に判定したい場合は、Requestsモジュールが必要になると思います。
通常、LamdaではLayerファイルを使用してRequestsモジュールなど、サードパーティライブラリが使用できます。
しかし、Canaryで作成したスクリプトを保存すると、関数ではなくレイヤーに保存されます。
そのため、Canaryで作成したスクリプトから別のレイヤーに入っているモジュールを呼び出すことができません。
解決方法としてS3バケットを介してプログラムをインポートすることで、独自に用意したスクリプトからRequestsモジュールなどサードパーティライブラリを使用できます。
その他の振替手段としては、コストと相談した上でAWS X-Rayのサービスを使用して監視することもできます。
Canaryの作成
本記事ではサードパーティライブラリを含めた独自に用意したスクリプトでAPI監視を行う方法について記載しています。
必要な作業は以下になります。
- スクリプトの用意
- S3にアップロード
- Canaryの作成
スクリプトの用意
はじめにローカルにてスクリプトを格納するためのフォルダを用意します。
注意点としては、下記ドキュメントの通りにPythonでCanaryを利用している場合、ファイルをZIP形式でパッケージングする際には、pythonフォルダ内に、メインの Python スクリプトが格納されている必要があります。
例えば、pythonhogeなど、python以外の名前のフォルダ名にした場合、正しくCanaryを作成することができません。
サードパーティライブラリを使用したい場合は、ローカルにpipでインストールします。
例えば、requestsモジュールを使用する場合は以下のコマンドを実行します。
$ mkdir python && cd python && pip3 install -t ./ requests
出力例
WARNING: pip is being invoked by an old script wrapper. This will fail in a future version of pip.
Please see https://github.com/pypa/pip/issues/5599 for advice on fixing the underlying issue.
To avoid this problem you can invoke Python with '-m pip' instead of running pip directly.
Collecting requests
Downloading requests-2.28.1-py3-none-any.whl (62 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 62.8/62.8 KB 1.9 MB/s eta 0:00:00
Collecting certifi>=2017.4.17
Downloading certifi-2022.6.15-py3-none-any.whl (160 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 160.2/160.2 KB 5.3 MB/s eta 0:00:00
Collecting idna<4,>=2.5
Using cached idna-3.3-py3-none-any.whl (61 kB)
Collecting urllib3<1.27,>=1.21.1
Downloading urllib3-1.26.10-py2.py3-none-any.whl (139 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 139.2/139.2 KB 4.9 MB/s eta 0:00:00
Collecting charset-normalizer<3,>=2
Downloading charset_normalizer-2.1.0-py3-none-any.whl (39 kB)
Installing collected packages: urllib3, idna, charset-normalizer, certifi, requests
Successfully installed certifi-2022.6.15 charset-normalizer-2.1.0 idna-3.3 requests-2.28.1 urllib3-1.26.10
WARNING: You are using pip version 22.0.4; however, version 22.1.2 is available.
You should consider upgrading via the '/Library/Developer/CommandLineTools/usr/bin/python3 -m pip install --upgrade pip' command.
上記、コマンド実行後、作成した独自のスクリプトも合わせて格納します。
以下の例ではtest_canaries.py
が独自に用意したスクリプトを指します。
また、スクリプトのファイル名は後で設定する際に必要になるため、控えておきます。
drwxr-xr-x 3 foo staff 96 7 11 19:44 bin
drwxr-xr-x 7 foo staff 224 7 11 19:44 certifi
drwxr-xr-x 8 foo staff 256 7 11 19:44 certifi-2022.6.15.dist-info
drwxr-xr-x 14 foo staff 448 7 11 19:44 charset_normalizer
drwxr-xr-x 9 foo staff 288 7 11 19:44 charset_normalizer-2.1.0.dist-info
drwxr-xr-x 11 foo staff 352 7 11 19:44 idna
drwxr-xr-x 8 foo staff 256 7 11 19:44 idna-3.3.dist-info
drwxr-xr-x 20 foo staff 640 7 11 19:44 requests
drwxr-xr-x 9 foo staff 288 7 11 19:44 requests-2.28.1.dist-info
-rw-r--r-- 1 foo staff 1980 7 11 19:51 test_canaries.py
drwxr-xr-x 16 foo staff 512 7 11 19:44 urllib3
drwxr-xr-x 8 foo staff 256 7 11 19:44 urllib3-1.26.10.dist-info
下準備の最後にファイルをzip化します。Macの場合はファイルを選択して右クリックで圧縮することができます。
上記で説明した通りにパッケージングする際のフォルダ名については制約がありますが、zip化したファイル名については任意のファイル名でも大丈夫です。
S3にアップロード
S3に任意のバケットを作成して、zip化したファイルをアップロードします。
S3のバケットの作成方法などについては特に要件はないため、割愛します。
Canaryの作成
CloudWatchの画面からSynthetics Canariesを選択し、「Canaryを作成」を押します。
用意されているテンプレートを利用する場合は「設計図を使用する」を選択しますが、独自に用意したスクリプトを使用するためには、「S3からインポート」を選択します。
Canary ビルダーの「名前」に、Canaryの名前を入力します。
名前は、21 文字までの小文字、数字、ハイフン、またはアンダースコアで構成され、スペースを含めることはできません。
ソースの場所の「ランタイムバージョン」はNode.jsまたは、Pythonどちらかのランタイムバージョンを選択します。
以下の例ではsyn-python-selenium-1.3
を選択しています。Pythonのバージョンは3.8になります。
また、「S3 の場所」にCanary のスクリプトが保存されている S3 の場所 (.zip 形式) を入力します。
「S3 の場所」はS3 URIのことを指し、「Browse S3」から選択することもできます。
環境変数を利用することで、Canaryを再作成することなく、コードの変更が可能なります。
例えば、URLや監視で使用するしきい値の設定などに活用できます。
環境変数はスクリプトから以下のようにして読み取ることができます。
以下は環境変数THRESHOLD
を読み込んで、レスポンスタイムを基に判定を行なう例です。
レスポンスタイムがしきい値である3秒以下の場合はCanaryが失敗するため、アラームによってシステムの異常を検知することができます。
# sample
import requests
import os
response = requests.get(url, headers=headers)
response_time = response.elapsed.total_seconds()
threshold = os.environ['THRESHOLD']
if response_time > float(threshold):
logger.error("Response Time: %s" % response_time)
raise Exception("Failed Response Time Over: %s" % response_time)
Pythonは動的型付け言語になり環境変数を読み込んだ際はstr型になるため、数字で判定を行う場合はデータ型を考慮する必要があります。
Lambda ハンドラーの「スクリプトエントリポイント」に、実行するメインのプログラムのファイル名を.handler
形式で入力します。
ファイル名がtest_canaries
の場合は、test_canaries.handle
と入力します。
スケジュールは実行スケジュールを編集します。
設定した周期で監視する場合は「継続的に実行」を選択します。
「データ保持」はAWS CLIのget-canary-runs
コマンドで取得できるデータのことを指します。
モニタリングで表示するためのデータはメトリクスから取得しているため、関連性がありません。
なお、メトリクスの保持期間はCloudWatchのメトリクス仕様を踏まえて、455日(15か月)間保持されます。
AWS CLIが使用可能な環境にて以下のコマンドを実行することで、上記、データ保持で指定している期間のデータが取得できます。
$ aws synthetics get-canary-runs --name <canary名>
アクセス許可は「新しいロールを作成」または、既存のロールを選択します。
CloudWatch アラーム - オプションはアラームで監視するためのメトリクスを指定します。
Canaryの実行が失敗したときに、アラームを鳴らしたい場合、メトリクス名は「失敗」を選択します。
この Canary の通知を設定するは、アラームの通知先として使用するトピックを選択します。
本記事執筆時点で上記、「CloudWatch アラーム - オプション」についてAWSの不具合が発生しています。アラームは作成されますが、アクションの設定が反映されないため、手動で設定する必要があります。AWSサポートに問い合わせて報告済みですが、まだ修正されていないようです。
最後に「Canay を作成」を押します。
Canayの作成処理が始まるのため、この画面のまま待ちます。
Canaryの動作確認
Canaryの起動
Canayが正常に作成された場合、Canayが起動されます。状態を見ると「起動中」に変化したのが確認できます。
Canay起動後、状態は「実行中」に変わります。
作成したCanayの名前を押して、「Availability」より、ログが確認できます。
起動が失敗した場合は問題に表示されるので、出力されるログから調査します。
処理が正常に動いた場合、最新の実行は成功と表示されます。
「Configuration」では各設定値が確認できます。
上記、Canaryの作成で記載した通りに、本記事執筆時点で問題が発生しています。
アラームは作成されますが、アクションの設定が反映されないという不具合が発生しています。
そのため、アラームのアクションの設定画面から「通知の追加」を押して、通知先を再度設定する必要があります。
Canaryの停止
Calaryの処理を停止したい場合は、アクションから「中止」を選択します。
Canayが停止した場合、状態は「停止」に変化します。
停止している状態では課金されません。
Canaryの削除
Calaryを削除したい場合は、Calaryを停止した状態でアクションから「削除」を選択します。
以下、生成されたアラーム、IAMロール及びポリシーが不要な場合は全て選択して、「削除」を押します。
Deleteを入力して、「確認」を押します。
なお、S3に格納されるCanaryの実行ログは削除されないため、不要な場合は手動で削除します。
モニタリング
「Monitoring」を押すと、Canaryのメトリクスについて確認できます。
期間(Durationメトリクス)はCanary及びその実行基盤となるLambda関数が起動するまでの時間は含まれてないため、スクリプト処理実行のみに要した合計時間が表示されています。単位はMillisecond(ミリ秒)です。
おわりに
総括としてサードパーティ製ツールを使用せずに、コストを抑えて監視を実現する場合、CloudWatch Syntheticsは最適なサービスだと思います。
弱みとしてはランタイムのバージョンアップなど、保守作業が発生します。
その他、処理の判定条件を変更したい時に環境変数で対応できない場合は、Canaryの再作成が必要になるため、Datadogなどと比較すると設定変更時の煩わしさがあると思います。