Lambdaのtimeoutを検知してSlackに通知する。
検知Lambdaが、検知対象のLambdaCloudwatchのtimeoutをトリガーとして、SNSを配信する。
やること概要
- SNSを作成する
- timeout_checkのLambdaを作る
- テスト用Lambdaを作る
SimpleNoticeService(SNS)
トピックを作成
名前と表示名 lambda_timeout_check
スタンダード方式
(FIFOでも変わらないと思う)
サブスクリプションの作成
プロトコル: EMAIL
宛先: Slackのチャンネルのメール
サブスクリプションを作成すると初回のみ認証メールが届くので、メール内リンク Confirm
を押す。
テスト用Lambda
コード
意図的にタイムアウトするよう処理を書きます。
hoge-timeout-tester
import json
import time
def lambda_handler(event, context):
# TODO implement
print("処理を開始")
time.sleep(1)
print("1秒経過しました。")
time.sleep(9)
print("10秒経過しました。")
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
一般設定>タイムアウト は初期値 3秒
のままでよい。
コードをDeploy後、Testで走らせておく。
チェック用Lambda
コード
hoge-timeout-monitor
import os, json, base64, zlib, datetime, boto3
def lambda_handler(event, context):
# print("### event", event)
# print("### context", context)
data = zlib.decompress(base64.b64decode(event['awslogs']['data']), 16+zlib.MAX_WBITS)
data_json = json.loads(data)
log_target_lambda = json.loads(json.dumps(data_json["logGroup"], ensure_ascii=False))
log_target_lambda = log_target_lambda.split('/')[-1]
print('### log_target_lambda', log_target_lambda)
log_target_logstream = json.loads(json.dumps(data_json["logStream"], ensure_ascii=False))
print('### log_target_logstream', log_target_logstream)
log_entire_json = json.loads(json.dumps(data_json["logEvents"], ensure_ascii=False))
log_entire_len = len(log_entire_json)
print('### log_entire_json', log_entire_json)
print('### log_entire_len', log_entire_len)
for i in range(log_entire_len):
log_json = json.loads(json.dumps(data_json["logEvents"][i], ensure_ascii=False))
log_timestamp = datetime.datetime.fromtimestamp(log_json["timestamp"]/1000, datetime.timezone(datetime.timedelta(hours=9)))
msg = f'【メール内リンクは触らないで!通知解除ボタンです!】\nTimeoutエラーが発生しています。至急確認してください。\n●Lambda:{log_target_lambda}\n ●CloudWatch\n ・Log stream:{log_target_logstream}\n ・timestamp:{log_timestamp}\n\n【メール内リンクは触らないで!通知解除ボタンです!】'
print("### msg", msg)
try:
sns = boto3.client('sns')
publishResponse = sns.publish(
TopicArn = os.environ['SNS_TOPIC_ARN'],
Message = msg,
Subject = "Timeoutエラー: " + log_target_lambda
)
print("publishResponse:",publishResponse)
print("### SNSメッセージ送信完了")
except Exception as e:
print(e)
return
環境変数
SNS_TOPIC_ARN
: SNSトピックのARN
起動時間(タイムアウト)
一般設定>タイムアウト : 1分程度
トリガーの設定
CloudWatch Logs
hoge-timeout-tester(チェック対象としたいLambda関数のCloudWatch)
フィルター名: Task timed out
フィルターパターン: Task timed out
テスト
testerLambdaを実行させ、意図的にタイムアウトを起こす。
Slackに通知が走ればOK。