0
Help us understand the problem. What are the problem?

posted at

updated at

Organization

CloudWatch Syntheticsを使用してAPI監視を実現する

はじめに

本記事はAWS環境でCloudWatch Syntheticsを使用して、API監視を行うための方法について記載しています。

クラウド環境におけるシステム監視を行うためには、クラウドを提供するサービスプロバイダーによってビルトインされたモニタリングシステムや、Datadogなどサードパーティ製ツールを使用するなどの手段があります。

AWSではモニタリングシステムとしてCloudWatchが無料で利用できます。
Syntheticsの監視についてもサードパーティ製ツールを使用せずに、コストを下げてAWSでインテグレーションしたモニタリングシステムを構築できます。

一見便利そうなSyntheticsですが、仕様が分かりにくかったり、痒い所に手が届かない部分もあります。
本記事ではSyntheticsを使ってたナレッジについてまとめました。

CloudWatch Synthetics

日本ではAPIなどエンドポイントに対する監視のことを外形監視といった表現が多いですが、AWSはDatadogと同じSyntheticsと呼び、CloudWatchのSynthetics Canariesとして提供されています。

canary.drawio.png

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を作成することができません。

スクリーンショット 2022-07-11 19.36.34.png

サードパーティライブラリを使用したい場合は、ローカルに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化したファイル名については任意のファイル名でも大丈夫です。

スクリーンショット 2022-07-11 19.54.35.png

S3にアップロード

S3に任意のバケットを作成して、zip化したファイルをアップロードします。
S3のバケットの作成方法などについては特に要件はないため、割愛します。

Canaryの作成

CloudWatchの画面からSynthetics Canariesを選択し、「Canaryを作成」を押します。

スクリーンショット 2022-07-11 19.29.45.png

用意されているテンプレートを利用する場合は「設計図を使用する」を選択しますが、独自に用意したスクリプトを使用するためには、「S3からインポート」を選択します。

スクリーンショット 2022-07-11 19.30.06.png

Canary ビルダーの「名前」に、Canaryの名前を入力します。
名前は、21 文字までの小文字、数字、ハイフン、またはアンダースコアで構成され、スペースを含めることはできません。

スクリーンショット 2022-07-12 19.50.53.png

ソースの場所の「ランタイムバージョン」はNode.jsまたは、Pythonどちらかのランタイムバージョンを選択します。
以下の例ではsyn-python-selenium-1.3を選択しています。Pythonのバージョンは3.8になります。

スクリーンショット 2022-07-14 19.57.47.png

また、「S3 の場所」にCanary のスクリプトが保存されている S3 の場所 (.zip 形式) を入力します。
「S3 の場所」はS3 URIのことを指し、「Browse S3」から選択することもできます。

スクリーンショット 2022-07-19 19.34.22.png

環境変数を利用することで、Canaryを再作成することなく、コードの変更が可能なります。
例えば、URLや監視で使用するしきい値の設定などに活用できます。

スクリーンショット 2022-07-25 20.08.53.png

環境変数はスクリプトから以下のようにして読み取ることができます。
以下は環境変数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と入力します。

スクリーンショット 2022-07-14 19.58.13.png

スケジュールは実行スケジュールを編集します。
設定した周期で監視する場合は「継続的に実行」を選択します。

スクリーンショット 2022-07-14 19.58.44.png

「データ保持」はAWS CLIのget-canary-runsコマンドで取得できるデータのことを指します。
モニタリングで表示するためのデータはメトリクスから取得しているため、関連性がありません。
なお、メトリクスの保持期間はCloudWatchのメトリクス仕様を踏まえて、455日(15か月)間保持されます。

スクリーンショット 2022-07-14 19.59.17.png

AWS CLIが使用可能な環境にて以下のコマンドを実行することで、上記、データ保持で指定している期間のデータが取得できます。

$ aws synthetics get-canary-runs --name <canary名>

アクセス許可は「新しいロールを作成」または、既存のロールを選択します。

スクリーンショット 2022-07-14 19.59.40.png

CloudWatch アラーム - オプションはアラームで監視するためのメトリクスを指定します。
Canaryの実行が失敗したときに、アラームを鳴らしたい場合、メトリクス名は「失敗」を選択します。

スクリーンショット 2022-07-14 20.00.20.png

この Canary の通知を設定するは、アラームの通知先として使用するトピックを選択します。

スクリーンショット 2022-07-14 20.00.39.png

本記事執筆時点で上記、「CloudWatch アラーム - オプション」についてAWSの不具合が発生しています。アラームは作成されますが、アクションの設定が反映されないため、手動で設定する必要があります。AWSサポートに問い合わせて報告済みですが、まだ修正されていないようです。

最後に「Canay を作成」を押します。

スクリーンショット 2022-07-19 19.35.55.png

Canayの作成処理が始まるのため、この画面のまま待ちます。

スクリーンショット 2022-07-19 19.39.02.png

Canaryの動作確認

Canaryの起動

Canayが正常に作成された場合、Canayが起動されます。状態を見ると「起動中」に変化したのが確認できます。

スクリーンショット 2022-07-19 19.40.19.png

Canay起動後、状態は「実行中」に変わります。

スクリーンショット 2022-07-19 19.40.52.png

作成したCanayの名前を押して、「Availability」より、ログが確認できます。
起動が失敗した場合は問題に表示されるので、出力されるログから調査します。

処理が正常に動いた場合、最新の実行は成功と表示されます。

スクリーンショット 2022-07-19 19.41.30.png

「Configuration」では各設定値が確認できます。
上記、Canaryの作成で記載した通りに、本記事執筆時点で問題が発生しています。
アラームは作成されますが、アクションの設定が反映されないという不具合が発生しています。

スクリーンショット 2022-07-19 19.42.59.png

そのため、アラームのアクションの設定画面から「通知の追加」を押して、通知先を再度設定する必要があります。

スクリーンショット 2022-07-19 19.43.33.png

Canaryの停止

Calaryの処理を停止したい場合は、アクションから「中止」を選択します。

スクリーンショット 2022-07-19 19.44.18.png

Canayが停止した場合、状態は「停止」に変化します。
停止している状態では課金されません。

スクリーンショット 2022-07-19 19.47.24.png

Canaryの削除

Calaryを削除したい場合は、Calaryを停止した状態でアクションから「削除」を選択します。

スクリーンショット 2022-07-19 19.48.05.png

以下、生成されたアラーム、IAMロール及びポリシーが不要な場合は全て選択して、「削除」を押します。

スクリーンショット 2022-07-19 19.48.42.png

Deleteを入力して、「確認」を押します。

スクリーンショット 2022-07-19 19.49.16.png

なお、S3に格納されるCanaryの実行ログは削除されないため、不要な場合は手動で削除します。

モニタリング

「Monitoring」を押すと、Canaryのメトリクスについて確認できます。

スクリーンショット 2022-07-28 21.18.51.png

期間(Durationメトリクス)はCanary及びその実行基盤となるLambda関数が起動するまでの時間は含まれてないため、スクリプト処理実行のみに要した合計時間が表示されています。単位はMillisecond(ミリ秒)です。

おわりに

総括としてサードパーティ製ツールを使用せずに、コストを抑えて監視を実現する場合、CloudWatch Syntheticsは最適なサービスだと思います。

弱みとしてはランタイムのバージョンアップなど、保守作業が発生します。
その他、処理の判定条件を変更したい時に環境変数で対応できない場合は、Canaryの再作成が必要になるため、Datadogなどと比較すると設定変更時の煩わしさがあると思います。

参考

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
0
Help us understand the problem. What are the problem?