本連載では、AWS Lambdaを使ったサーバレス処理でのエラーハンドリング方法を解説しています。 前回は以下の赤字の矢印のスコープにおいて、同期的なLambdaの呼び出しでシステムエラーが発生するケースを想定して、CloudWatch Logsに出力されたログをイベント契機として実行される、 Spring Cloud Functionを使ったLambdaファンクションを実装を解説しました。今回は実際にCloudWatch Logsに出力されたログをサブスクリプションして、Mattermostへメッセージ通知する環境を構築します。
LambdaファンクションのCloudFormationテンプレート の手順で構築したLambdaテンプレートに、前回実装したLambdaファンクションを追加して、スタックを作成し直します。
AWSTemplateFormatVersion: '2010-09-09'
#omit
Resources:
LambdaForSyncExecuteSystemErrorFuntion:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket:
Fn::ImportValue: debugroom-mynavi-sample-lambda-errorhandling-deploy-s3-bucket
S3Key: spring-cloud-3-1-lambda-function-0.0.1-SNAPSHOT-aws.jar
Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest
FunctionName: mynavi-sample-aws-lambda-errorhandling-sync-system-error
Environment:
Variables:
SPRING_CLOUD_FUNCTION_DEFINITION: syncExecuteSystemErrorFunction
MemorySize: 1024
Runtime: java11
Timeout: 120
Role: !GetAtt LambdaRole.Arn
#omit
LambdaForNotifySystemErrorFuntion:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket:
Fn::ImportValue: debugroom-mynavi-sample-lambda-errorhandling-deploy-s3-bucket
S3Key: spring-cloud-3-1-lambda-function-0.0.1-SNAPSHOT-aws.jar
Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest
FunctionName: mynavi-sample-aws-lambda-errorhandling-notify-system-error
Environment:
Variables:
SPRING_CLOUD_FUNCTION_DEFINITION: notifySystemErrorFunction
MemorySize: 1024
Runtime: java11
Timeout: 120
Role: !GetAtt LambdaRole.Arn
#omit
Outputs:
#omit
LambdaForSyncExecuteSystemErrorFuntion:
Description: Sync execute Lambda function for occuring system error function.
Value: !Ref LambdaForSyncExecuteSystemErrorFuntion
Export:
Name: mynavi-sample-lambda-errorhandling-sync-execute-system-error-function-name
LambdaForSyncExecuteSystemErrorFuntionArn:
Description: Sync execute Lambda function for occuring system error function.
Value: !GetAtt LambdaForSyncExecuteSystemErrorFuntion.Arn
Export:
Name: mynavi-sample-lambda-errorhandling-sync-execute-system-error-function-arn
#omit
LambdaForNotifySystemErrorFuntion:
Description: Lambda function for notifying system error function.
Value: !Ref LambdaForNotifySystemErrorFuntion
Export:
Name: mynavi-sample-lambda-errorhandling-notify-system-error-function-name
LambdaForNotifiySystemErrorFuntionArn:
Description: Lambda function for notifying system error function.
Value: !GetAtt LambdaForNotifySystemErrorFuntion.Arn
Export:
Name: mynavi-sample-lambda-errorhandling-notify-system-error-function-arn
同様に、API Gatewayのテンプレートも、システムエラーが発生するファンクション向けにメソッドやリソースを定義して構築し直します。
#omit
ApiGatewaySystemExceptionResource:
Type: "AWS::ApiGateway::Resource"
Properties:
RestApiId:
Ref: ApiGatewayRestApi
ParentId:
Fn::GetAtt:
- ApiGatewayRestApi
- RootResourceId
PathPart: "system-exception-sample-resource"
#omit
ApiGatewaySystemExceptionMethod:
Type: "AWS::ApiGateway::Method"
DependsOn: ApiGatewayModel
Properties:
RestApiId:
Ref: ApiGatewayRestApi
ResourceId:
Ref: ApiGatewaySystemExceptionResource
HttpMethod: "GET"
AuthorizationType: "NONE"
Integration:
Type: "AWS_PROXY"
Uri:
Fn::Join:
- ""
- - "arn:aws:apigateway"
- ":"
- Ref: AWS::Region
- ":"
- "lambda:path/2015-03-31/functions/"
- Fn::ImportValue: mynavi-sample-lambda-errorhandling-sync-execute-system-error-function-arn
- "/invocations"
IntegrationHttpMethod: "POST"
PassthroughBehavior: WHEN_NO_MATCH
MethodResponses:
- StatusCode: 200
ResponseModels:
application/json: SampleSchema
- StatusCode: 400
ResponseModels:
application/json: Error
SystemErrorLambdaPermission:
Type: "AWS::Lambda::Permission"
Properties:
FunctionName:
Fn::ImportValue: mynavi-sample-lambda-errorhandling-sync-execute-system-error-function-name
Action: "lambda:InvokeFunction"
Principal: "apigateway.amazonaws.com"
続いて、CloudWatchにサブスクリプションフィルタおよびロググループ、実行権限に関するテンプレートを実装します。
AWSTemplateFormatVersion: '2010-09-09'
#omit
Resources:
CloudWatchLogsSyncExecuteSystemErrorSubscription: #(1)
Type: AWS::Logs::SubscriptionFilter
Properties:
LogGroupName: !Ref LogsGroupSyncExecuteSystemError
FilterPattern: "Exception" #(2)
DestinationArn:
Fn::ImportValue: mynavi-sample-lambda-errorhandling-notify-system-error-function-arn #(3)
LogsGroupSyncExecuteSystemError:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName:
Fn::Join:
- ""
- - "/aws/lambda/"
- Fn::ImportValue: mynavi-sample-lambda-errorhandling-sync-execute-system-error-function-name #(4)
NotifyErrorLambdaPermission: #(5)
Type: AWS::Lambda::Permission
Properties:
FunctionName:
Fn::ImportValue: mynavi-sample-lambda-errorhandling-notify-system-error-function-name
Action: lambda:InvokeFunction
Principal: !Join [ ".", [ "logs", !Ref "AWS::Region", "amazonaws.com" ] ]
SourceAccount: !Ref AWS::AccountId
項番 | 説明 |
CloudWatch Logsで特定のログをサブスクリプションする設定を行います。各プロパティの詳細は Type: AWS::Logs::SubscriptionFilter を参照してください。 | |
ログでピックアップ対象とする文字列パターンを指定します。前節の実際の実装ではSystemExceptionをスローしていますが、実際は様々な想定外のExceptionクラスがスローされることになるので、「Exception」をパターン文字列として設定します。 | |
実行するLambdaファンクションのARNをクロススタックリファレンスで参照します。 | |
監視対象とするロググループを指定します。前節で作成したシステム例外を発生するLambdaファンクションのログが出力されるロググループを指定しています。 | |
ロググループにLambdaの実行権限を付与します。 |
これらのテンプレートを実行し、環境を構築します。また、本連載では説明は省略しますが、 Mattermost環境の構築 や、Webhook の設定を行い、 URLをSystemsManager ParameterStoreに設定しておきます。なお、SystemsManager ParameterStoreの設定に関しては、AWSで実践! 基盤構築・デプロイ自動化で解説した 「第29回」 などを適宜参考にしてください。
必要な環境構築・設定後、API GatewayのCloudFormationテンプレート で実行した要領と同様、API Gatewayからシステムエラーが発生するファンクションを実行すると以下の通り、API Gatewayからインターナルサーバエラーが返却されます。
CloudWatch Logsには発生したエラーのスタックトレースが記録されます。
CloudWatch Logsのサブスクリプションが別途Lambdaファンクションを呼び出し、Mattermost側へエラー内容を通知します。システム管理者や運用担当者はエラーの内容を確認して、AWSの外で優先度を設定し対応することができます。
今回は、API GatewayとLambdaを使用した同期呼び出しで、システムエラーが発生した際に、CloudWatchに出力されたエラーログを契機として、システム管理者へ通知を行うLambdaファンクション実装を含めて解説しました。 次回は、S3などのマネージドサービスから非同期に実行されるLambdaファンクション内で発生したエラーのハンドリングについて解説を進めていきます。
川畑 光平(KAWABATA Kohei) - NTTデータ エグゼクティブ ITスペシャリスト ソフトウェアアーキテクト・デジタルテクノロジーストラテジスト(クラウド)
金融機関システム業務アプリケーション開発・システム基盤担当、ソフトウェア開発自動化関連の研究開発を経て、デジタル技術関連の研究開発・推進に従事。
Red Hat Certified Engineer、Pivotal Certified Spring Professional、AWS Certified Solutions Architect Professional等の資格を持ち、アプリケーション基盤・クラウドなど様々な開発プロジェクト支援にも携わる。
AWS Top Engineers & Ambassadors 選出。
本連載記事の内容に対するご意見・ご質問は Facebook まで。