こんにちは、みーまです。
業務で「Webサービスの死活監視をしたい」というリクエストを受け、Pythonでコードを書きましたので残しておきます。
「CloudWatch Syntheticsでもいいじゃない」みたいな話はあるんですが、技術として枯れていてシンプルなので。
HTTPステータスコードが期待と異なる場合Slack通知
動作
- 指定したサイトに対してGETリクエストを行う
- HTTPステータスコードを取得し、期待値と異なる場合Slackに通知
- DNSダウンなど、何らかの理由でGETリクエストが失敗した場合も内容を変えてSlackに通知
環境変数
実行のために環境変数を使います。
項目 | 用途(参考値) |
---|---|
environment | 環境認識文字列(production/staging) |
healthcheck_url | チェック対象のURL('https://aws.amazon.com/jp/) |
healthcheck_code | 期待するHTTPステータスコード |
コード
- slack_pathおよびpost_channelは適宜書き替えてください。
- os.getenv()にデフォルト値を渡しているので、最終行を有効化すれば単体テストもできます。
import requests
import json
import os
def lambda_handler(event, context):
environment = os.getenv('environment', 'test')
healthcheck_url = os.getenv(
'healthcheck_url', 'https://aws.amazon.com/jp/')
healthcheck_code = int(os.getenv('healthcheck_code', 418)) # strで格納の為キャスト
slack_path = "/services/***********/***********/**********************"
title = f"{environment.title()}サイトダウン検知"
# access to website
try:
r = requests.get(healthcheck_url)
except requests.exceptions.RequestException as e:
message = "以下のサイトに通信が到達しません。状況を確認してください。\n"
message += f"URL: {healthcheck_url}\n"
message += f"STATUS: FAILED({e})"
print(f"STATUS: FAILED({e})")
post_to_slack(title, message, slack_path)
else:
message = "以下のサイトが期待されるステータスコードを返しません。状況を確認してください。\n"
message += f"URL: {healthcheck_url}\n"
message += f"STATUS: UNMATCH({r.status_code})"
# check status_code
if r.status_code != healthcheck_code:
post_to_slack(title, message, slack_path)
# print log
print(
f"STATUS: UNMATCH({r.status_code})")
else:
# print log
print(f"STATUS: SUCCESS({r.status_code})")
# post to slack
def post_to_slack(title, message, path):
requests.post(
f"""https://hooks.slack.com{path}""",
data=json.dumps({
"channel": "#post_channel",
"attachments": [{
"color": "#FF0000",
"title": f"{title}",
"text": f"{message}",
}],
"icon_emoji": ":aws:",
}),
headers={'Content-Type': 'application/json'}
)
# for local test
# lambda_handler("event", "context")
実際どう使っているのか
- CloudWatch Eventsで5分おきのcronイベントを作り、Lambdaを呼び出しています。
- 今のところサイトがダウンしたことがないので、まだ活躍してません。
- フロントエンドがECS on Fargateなので、当分活躍することもないかなと思ってます。
以上です。