Amazon CloudWatch Syntheticsを試してみた


Amazon CloudWatch SyntheticsがGAになったので試してみました。
https://aws.amazon.com/about-aws/whats-new/2020/04/amazon-cloudwatch-synthetics-generally-available/
https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries.html

どんなもの

WEBやAPIを監視するサービスです。
TOPページやAPI監視以外にもリンク切れワークフロー監視のBlueprintsが用意されています。
UIのスクリーンショットを保存することも可能です。

WEB監視

準備

1. 時々200以外のステータスを返すLambdaを用意する
lambda.py
import random

def lambda_handler(event, context):
    status = random.choices((200,400,500), weights = (7,2,1))[0]

    res = {
        "isBase64Encoded": False,
        "statusCode": status,
        "statusDescription": "status: {}".format(status),
        "headers": {
            "Set-cookie": "cookies",
            "Content-Type": "text/html"
        }
    }

    res['body'] = """<html>
    <head>
    <title>hello world</title>
    </head>
    <body>
    <h1>Hello World</h1>
    </body>
    </html>"""

    return res
2. ALBを作成して、Lambdaをターゲットにする
3. Canaryを作成する

ALBのDNS名(または作成していればRoute53のALBのエイリアス)をURLに指定します。
残りはデフォルトで作成します。

結果

レイテンシや、スクリーンショットが確認できます。

リンク切れ監視

準備

1. 時々リンク切れにする(=リンク先で404ステータスを返す)Lambdaを用意する
lambda_link.py
import random

def lambda_handler(event, context):
    path = event['path']
    if path == '/':
        status = 200
    else:
        status = random.choices((200,404), weights = (7,3))[0]

    res = {
        "isBase64Encoded": False,
        "statusCode": status,
        "statusDescription": "status: {}".format(status),
        "headers": {
            "Set-cookie": "cookies",
            "Content-Type": "text/html"
        }
    }

    top = """<html>
    <head>
    <title>hello world</title>
    </head>
    <body>
    <h1>TOP Page</h1>
    <a href="/linkA">linkA</a>
    <a href="/linkB">linkB</a>
    <a href="/linkC">linkC</a>  
    </body>
    </html>"""

    link = """<html>
    <head>
    <title>hello world</title>
    </head>
    <body>
    <h1>Linked Page</h1>
    </body>
    </html>"""

    if path == '/':
        res['body'] = top
    else:
        res['body'] = link

    return res
2. ALBを作成して、Lambdaをターゲットにする
3. Canaryを作成する

ALBのDNS名(または作成していればRoute53のALBのエイリアス)をURLに指定します。
残りはデフォルトで作成します。

結果

リンク先(LinkB)で404エラーになったのを拾って、失敗のステータスになっていることが確認できます。

雑感

技術的にはLambda+αで目立ったところはないですが、手軽に監視できるところが良いと感じました。