本連載では、AWS Lambdaを使ったサーバレス処理でのエラーハンドリング方法を解説しています。前回は、下図の赤字の矢印のスコープにおいて、同期的なLambdaの呼び出しでシステムエラーが発生するケースを想定し、CloudWatch Logsに出力されたログをイベント契機として実行される、Spring Cloud Functionを使ったLambdaファンクションを実装について解説しました。
今回は、実際にCloudWatch Logsに出力されたログをサブスクリプションして、Mattermostへメッセージ通知する環境を構築します。
CloudFormationを使用したLambda環境の構築/CloudWatchサブスリプションの設定
第8回で解説した手順で構築した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
上記のコードのポイントは以下の通りです。
項番 | 説明 |
---|---|
1 | CloudWatch Logsで特定のログをサブスクリプションする設定を行います。各プロパティの詳細は「AWS::Logs::SubscriptionFilter」を参照してください |
2 | ログでピックアップ対象とする文字列パターンを指定します。前節の実際の実装ではSystemExceptionをスローしていますが、実際はさまざまな想定外のExceptionクラスがスローされることになるので、「Exception」をパターン文字列として設定します |
3 | 実行するLambdaファンクションのARNをクロススタックリファレンスで参照します |
4 | 監視対象とするロググループを指定します。前節で作成したシステム例外を発生するLambdaファンクションのログが出力されるロググループを指定しています |
5 | ロググループにLambdaの実行権限を付与します |
これらのテンプレートを実行し、環境を構築します。また、本連載では説明は省略しますが、Mattermost環境の構築やWebhookの設定を行い※、URLを「SystemsManager ParameterStore」に設定しておきます。なお、SystemsManager ParameterStoreの設定に関しては、連載「AWSで実践! 基盤構築・デプロイ自動化」の第29回などを適宜参考にしてください。
必要な環境を構築/設定後、第8回と同じ要領でAPI Gatewayからシステムエラーが発生するファンクションを実行すると、以下のようにAPI Gatewayからインターナルサーバエラーが返却されます。
※ Mattermost環境の構築やWebhookの設定については、公式サイトの「Installing Mattermost」や「Mattermost Integration Guide」を参照してください。
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 まで。