[AWS SAM] Amazon CloudWatch Lambda Insightsを使って、Lambdaのパフォーマンスを見る

AWS SAMでAmazon CloudWatch Lambda Insightsの設定をしてみました。
2021.06.15

2020年末にGAになったAmazon CloudWatch Lambda Insightsがあります。 この機能を使えば、Lambda関数のパフォーマンスが簡単に確認できます。

  • メモリ使用率がギリギリになっているLambdaはあるか?
  • 実行時間が極端に長いLambdaはあるか?
  • 実行回数が極端に増えているLambdaはあるか?
  • など

そこで、AWS SAMでAmazon CloudWatch Lambda Insightsを使ってみました。

おすすめの方

  • AWS SAMでAmazon CloudWatch Lambda Insightsを使いたい方

サーバーレスアプリを作成する

SAM Init

sam init \
    --runtime python3.8 \
    --name Lambda-insights-Sample \
    --app-template hello-world \
    --package-type Zip

SAMテンプレート

GlobalでLambda Layersを設定し、Policiesを設定するだけです。 今回はそのまま利用しましたが、参照するLambda LayersのARNはSSMパラメータストアに格納し、SAMテンプレートから参照する方法だと管理が楽になると思います。

template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Lambda-insights-Sample

Globals:
  Function:
    Layers:
      # https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Lambda-Insights-extension-versions.html
      - !Sub "arn:aws:lambda:${AWS::Region}:580247275435:layer:LambdaInsightsExtension:14"

Resources:
  HelloWorld1Function:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Timeout: 10
      Policies:
        - CloudWatchLambdaInsightsExecutionRolePolicy
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello1
            Method: get

  HelloWorld1FunctionLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub /aws/lambda/${HelloWorld1Function}

  HelloWorld2Function:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Timeout: 10
      Policies:
        - CloudWatchLambdaInsightsExecutionRolePolicy
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello2
            Method: get

  HelloWorld2FunctionLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub /aws/lambda/${HelloWorld2Function}

Outputs:
  HelloWorldApi1:
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello1/"
  HelloWorldApi2:
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello2/"

Lambdaコード

app.py

import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'body': json.dumps({
            'message': 'hello world',
        }),
    }

デプロイ

sam build

sam package \
    --output-template-file packaged.yaml \
    --s3-bucket cm-fujii.genki-deploy

sam deploy \
    --template-file packaged.yaml \
    --stack-name Lambda-insights-Sample-Stack \
    --s3-bucket cm-fujii.genki-deploy \
    --capabilities CAPABILITY_NAMED_IAM \
    --no-fail-on-empty-changeset

APIエンドポイントを取得

aws cloudformation describe-stacks \
    --stack-name Lambda-insights-Sample-Stack \
    --query 'Stacks[].Outputs'

Amazon CloudWatch Lambda Insightsの様子を確認する

何度か適当にAPIアクセスする

curl https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello1/
curl https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello2/

Amazon CloudWatch Lambda Insightsにデータが表示される

しばらく待つと、情報が表示されました。

Amazon CloudWatch Lambda insightsにデータが表示された様子

Function summaryが表示されるのも地味に嬉しいですね。

Amazon CloudWatch Lambda insightsでLambdaのサマリーが表示されている

LambdaInsightsのメトリクスも追加される

CloudWatch メトリクスにも情報が追加されます。1つのLambda関数につき、8つのメトリクスが追加されます。(ここ料金ポイントです)

Amazon CloudWatchメトリクスにLambda Insightsが追加されている

公式サイトによると、init_durationも収集しているので、いわゆるコールドスタートの時間確認もできます。

Amazon CloudWatch メトリクスでLambdaのコールドスタート時間が分かる

ログを確認すると、240msと一致しています。

Lambdaログの様子

さいごに

Lambdaのメモリ使用率が見れるとは、便利になりました。モニタリングしたい情報があれば、いろいろと活用できそうです。

参考