AWS Lambda Powertools for .NET を使ってみた

はじめに

こんにちは。小川です。

今回は、Lambdaのログやメトリクスを簡単に出力することが出来る
AWS Lambda Powertoolsを使ってみました。


下記の公式ドキュメントの通り、
AWS Lambda Powertools for .NETの一般提供が開始されました。

aws.amazon.com


.NETの学習も兼ねて、下記ブログを参考に作成しました。

aws.amazon.com


目次

1..NETのプロジェクトを作成
2.Logging
3.Tracing
4.Metrics
5.つまづいた箇所

.NETのプロジェクトを作成

まずはプロジェクトの作成から進めます。
入力された英語を大文字で返す、
簡単なLambda作成します。

前提

AWS CLIの設定
・CloudFormation用のS3バケット

docs.aws.amazon.com

SAMテンプレート

.NETのテンプレートからも作成可能ですが、
今回は、SAMのテンプレートからプロジェクトを作成します。

$ sam init

設定内容は以下の通りです。

・テンプレートソースは、1 - AWS Quick Start Templates
・テンプレートは、1 - Hello World Example
・ランタイムは、dotnet6
X-rayトレーシングはONを選択

コーディング

下記のようなコードを作成しました。

Functions.cs

using System.Collections.Generic;
using System.Linq; using System.Threading.Tasks;
using System.Net.Http;
using System.Text.Json;
using Amazon.Lambda.Core;
using Amazon.Lambda.APIGatewayEvents;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly:LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace HelloWorld
{
  public class Function
  {
    public string FunctionHandler(object input, ILambdaContext context)
    {
      var input_string = input.ToString();
      var upper_string = UpperCaseString(input_string); 

      LambdaLogger.Log(input_string);
      LambdaLogger.Log(upper_string);
      return upper_string;
    }

    private static string UpperCaseString(string input)
    {
      return input.ToUpper();
    }
  }
}


template.ymlに関数名を入力します。

Resources:
HelloWorldFunction:
  Type: AWS::Serverless::Function
  Properties:
    FunctionName: [関数名]

ビルド

これでコードは完成です。
dotnetをビルドします。

$ dotnet build

デプロイ

CloudFormationからデプロイします。
バケット名には、テンプレート保存用のS3バケット名を入力します。
任意のスタック名を入力して、下記コマンドを実行します。

$ aws cloudformation package --template-file template.yaml --s3-bucket [バケット名] --output-template-file packaged-template.yaml
$ dotnet lambda deploy-serverless --s3-bucket [バケット名] --stack-name [スタック名]

実行

下記パラメータでテストを実行します。

{
  "statusCode": 200,
  "body": "Hello world"
}

CloudWatchログを確認します。

大文字が返ってきてますね。
CLIからでも実行が可能です。

$ dotnet lambda invoke-function [関数名] --payload "Hello world"
Amazon Lambda Tools for .NET Core applications (5.6.3)
Project Home: https://github.com/aws/aws-extensions-for-dotnet-cli, https://github.com/aws/aws-lambda-dotnet

Payload: "HELLO WORLD"

(以下、省略)

Logging

Powertoolをプロジェクトに追加します。

$ dotnet add package AWS.Lambda.Powertools.Logging

SAMテンプレートに環境変数を追加します。

template.yaml

Globals:
  Function:
    Environment:
      Variables:
        POWERTOOLS_SERVICE_NAME: powertools-dotnet-logging-sample
        POWERTOOLS_LOG_LEVEL: Debug
        POWERTOOLS_LOGGER_CASE: SnakeCase


Lambda関数にLoggingを追加します。

Function.cs

namespace HelloWorld
{
  public class Function
  {

    [Logging(LogEvent = true)]
    public string FunctionHandler(object input, ILambdaContext context)
    {
      var input_string = input.ToString();
      var upper_string = UpperCaseString(input_string);
      
      Logger.LogInformation(input_string);
      Logger.LogInformation(upper_string);
      return upper_string;
    }

    private static string UpperCaseString(string input)
    {
      return input.ToUpper();
    }
  }
}

デプロイ、実行するとCloudWatchログの出力が変更されます。

CloudWatchログ

ログのインサイト


Tracing

Powertoolをプロジェクトに追加します。

$ dotnet add package AWS.Lambda.Powertools.Tracing


SAMテンプレートに環境変数を追加します。

template.yaml

Globals: 
  Function:
    Environment:
      Variables:
        POWERTOOLS_SERVICE_NAME: powertools-dotnet-tracing-sample
        POWERTOOLS_TRACER_CAPTURE_RESPONSE: true 
        POWERTOOLS_TRACER_CAPTURE_ERROR: true


Lambda関数にTracingを追加します。

Function.cs

namespace HelloWorld
{
  public class Function
  {

    [Tracing]
    public string FunctionHandler(object input, ILambdaContext context)
    {
      var input_string = input.ToString();
      var upper_string = UpperCaseString(input_string); 

      LambdaLogger.Log(input_string);
      LambdaLogger.Log(upper_string);
      return upper_string;
    }

    [Tracing(SegmentName = "UpperCaseString Method")]
    private static string UpperCaseString(object input)
    {
      return input.ToString().ToUpper();
    }
  }
}


デプロイ、実行するとX-rayの出力が変更されます。

X-ray


Metrics

Powertoolをプロジェクトに追加します。

$ dotnet add package AWS.Lambda.Powertools.Metrics


SAMテンプレートに環境変数を追加します。

template.yaml

Globals:
  Function:
    Environment:
      Variables:
        POWERTOOLS_SERVICE_NAME: powertools-dotnet-tracing-sample
        POWERTOOLS_METRICS_NAMESPACE: AWSLambdaPowertools


Lambda関数にMetricsを追加します。

Function.cs

namespace HelloWorld
  {
    public class Function
    {

    public string FunctionHandler(object input, ILambdaContext context)
    {
      var input_string = input.ToString();
      var upper_string = UpperCaseString(input_string); 

      LambdaLogger.Log(input_string);
      LambdaLogger.Log(upper_string); return upper_string;
    }

    [Metrics(CaptureColdStart = true)]
    private static string UpperCaseString(object input)
    {
      Metrics.PushSingleMetric("UpperCaseString_Invocations", 1, MetricUnit.Count);
      return input.ToString().ToUpper();
    }
  }
}


デプロイ、実行するとCloudWatchメトリクスの出力が追加されます。

CloudWatchメトリクス


おわりに

今回は、AWS Lambda Powertoolsを初めて使ってみました。
簡単にログが残せるので便利ですね。

.NETも初めて使ってみましたが、
慣れれば使いやすいのかなと思いました。
(コンソール画面からLambdaを修正できないのは不便に感じますが。。)

他言語のAWS Lambda Powertoolsもあるようなので
うまく活用していきたいと思います。

ブログ著者