🕌

Lambdaがタイムアウトしたときの例外処理をCW logsにトリガーさせる

2022/10/11に公開

やりたいこと

プログラムにエラーが出たとき、例外処理をしてから終了させたいときがあります。一方で、Lambdaがタイムアウトで終了する場合は、例外処理をすることなく終わってしまいます。これをどうにかしたいと思い、やってみました。

やったこと

CloudWatch Logsのサブスクリプションフィルターで別のLambdaを呼んで例外処理をさせればよさそうです。下の絵のように、Lambda1がタイムアウトしたときのログを見つけたら、Lambda2をコールします。

やりかた

サブスクリプションフィルターについてはこのAWSブログが丁寧なので、ほとんどこれを使いました。構成は以下のようになります。

  • Lambda1 タイムアウトエラーを出す
  • CloudWatch log フィルターしてLambda2をトリガー
  • Lambda2 CWからトリガーを受けて、Amazon SNSで通知する

https://aws.amazon.com/jp/blogs/mt/get-notified-specific-lambda-function-error-patterns-using-cloudwatch/

作成する

  • 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