はじめに
本記事ではAWSのLambdaとSNSを使用したメール送信において、エラーハンドリングを実装していきます。
ゴール
下記の2点を確認することをゴールとします。
- Lambda→SNS段階のエラーを検知し、エラーメールを送信できてる事
- SNS→メール配信段階のエラー検知し、エラーメールを送信できてる事
処理フロー
【正常系】
Lambda → SNS → メール配信
【エラー系1: Lambda→SNS段階】
Lambda → エラー発生 → エラーメール送信
【エラー系2: SNS→メール配信段階】
SNS → エラー発生 → CloudWatchメトリクスで検知 → アラーム状態 → エラーメール送信
作るもの
- AWS Lambda:1つ
- Amazon SNS:1つ
- Amazon CloudWatch:1つ
1. SNSトピックの作成
トピック・サブスクリプションの作成
トピックとサブスクリプションの作成手順については、次の記事に記載されてる方法を参照ください。
2. Lambda関数の作成
LambdaからSNSを利用したメール通知に関しても、次の記事に記載されてるソースを参考に実装しています。
lambda_function.py
import json
from notifier import send_notification, send_error_notification
def lambda_handler(event, context):
TOPIC_ARN = 'SNSトピックのARN'
subject = "Lambda からの通知"
message = "テスト通知メッセージ"
try:
response = send_notification(TOPIC_ARN, message, subject)
return {
'statusCode': 200,
'body': json.dumps({
'message': '通知が送信されました',
'messageId': response['MessageId']
})
}
except Exception as e:
error_message = str(e)
send_error_notification(
TOPIC_ARN,
error_message,
"Lambda-SNS通信エラー"
)
return {
'statusCode': 500,
'body': json.dumps({
'error': 'メール送信に失敗しました',
'details': error_message
})
}
notifier.py
notifier.py
import json
import boto3
from datetime import datetime
sns = boto3.client('sns')
def send_notification(topic_arn, message, subject):
response = sns.publish(
TopicArn=topic_arn,
Message=message,
Subject=subject
)
return response
def send_error_notification(topic_arn, error_message, error_type):
error_subject = f"【エラー通知】{error_type}"
error_body = f"""
エラーが発生しました。
発生時刻: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
エラー種別: {error_type}
エラー詳細: {error_message}
"""
try:
sns.publish(
TopicArn=topic_arn,
Message=error_body,
Subject=error_subject
)
except Exception:
pass
Lambdaを動かす際にはIAMのポリシーからSNSの権限付与を行っていてください。
3. CloudWatchアラームの作成
- 「アラーム」→「すべてのアラーム」を選択し、「アラームの作成」をクリック
- メトリクスの選択:
- メトリクス名: NumberOfNotificationsFailed
- トピック名: 監視対象のSNSトピック名を選択
- メトリクスオプションの設定:
- 統計: Sum
- 期間: 5分
- 条件の設定
- しきい値の種類: 静的
- アラーム条件: 以上
- しきい値: 1
- アラームアクションの設定
- アラーム状態トリガー:アラーム状態
- SNSトピックを選択
- 通知の送信先:エラー通知用のSNSトピック
動作の確認
正常系の確認
Lambdaをテスト実行し、正常にメールが通知されることを確認できました。
内容
件名:Lambda からの通知
本文:これはテスト通知メッセージです。
エラー系1: Lambda→SNS通信エラーの確認
意図的にLambdaのソースを誤ったものにし、Lambdaを実行してみます。
誤った例
response = sns.publish(
TopicArn=topic_arnあああ,
Message=message,
Subject=subject
)
Lambda実行後、Lambda側で定義した内容のエラーメールが送信されることを確認できました。
エラーメール
件名:【エラー通知】Lambda-SNS通信エラー
本文:
エラーが発生しました。
発生時刻: 2024-10-31 15:48:41
エラー種別: Lambda-SNS通信エラー
エラー詳細: name 'topic_arnあああ' is not defined
エラー系2:SNS配信エラーの確認
AWS CLIを使用してメトリクスをアラーム状態にし、配信エラーを擬似的に再現します。
# アラーム状態に設定
aws cloudwatch set-alarm-state \
--alarm-name アラーム名 \
--state-value ALARM \
--state-reason "Testing alarm notification"
次のコマンドではアラームをOK状態に戻すことができます。
# OK状態に設定
aws cloudwatch set-alarm-state \
--alarm-name アラーム名 \
--state-value OK \
--state-reason "Test completed"
コマンド実行後、CloudWatchアラームによるエラーメールが送信されることを確認できました。
参考