🕌
Lambdaがタイムアウトしたときの例外処理をCW logsにトリガーさせる
やりたいこと
プログラムにエラーが出たとき、例外処理をしてから終了させたいときがあります。一方で、Lambdaがタイムアウトで終了する場合は、例外処理をすることなく終わってしまいます。これをどうにかしたいと思い、やってみました。
やったこと
CloudWatch Logsのサブスクリプションフィルターで別のLambdaを呼んで例外処理をさせればよさそうです。下の絵のように、Lambda1がタイムアウトしたときのログを見つけたら、Lambda2をコールします。
やりかた
サブスクリプションフィルターについてはこのAWSブログが丁寧なので、ほとんどこれを使いました。構成は以下のようになります。
- Lambda1 タイムアウトエラーを出す
- CloudWatch log フィルターしてLambda2をトリガー
- Lambda2 CWからトリガーを受けて、Amazon SNSで通知する
作成する
- Lambda1を作る
Pythonで作ります。Timeout設定をデフォルト(3秒)にして、5秒スリープさせてタイムアウトさせます。
import time
def lambda_handler(event, context):
time.sleep(5)
テスト実行すると、Task timed out after 3.00 seconds
というメッセージがCWに残ります。これを見つけてトリガーすることになります。
- Step1,2,3はブログのまま
- Step1: SNSトピックを作る
- Step2: IAM Roleを作る(Lambda2がSNSを呼ぶため)
- Step3: Lambda2 を作る
- Step4 フィルターを作る
Lambda2のFunctionOverviewのページで +Add Trigger
ボタンからCloudWatchLogsを選択
- Log group: Lambda1のロググループ
- Filter name: 自由
- Filter pattern: "Task timed out after"
- これがLambdaタイムアウト時に出てくるログを見つけるためのフィルターとしてはたらく(他の書き方でも良い)
- ※ダブルクォートで囲む(パターンの説明aws-doc)
実行する
Lambda1を実行してタイムアウトエラーを出すと、SNSで設定したエラーメッセージが来ます。画像の囲んだ部分がフィルターにひっかかったMessageです。(Lambda1がsample-loggerという名前になっている)
まとめ
- Lambdaがタイムアウトしたときの後処理をCloudWatchLogsから呼び出した別のLambdaでできるようにしました。
- 他のやり方もありそうですが、とりあえず。公式ブログに感謝。
Discussion