この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、CX事業本部 IoT事業部の若槻です。
このたび、AWS Lambda Powertools for TypeScriptがついにGAされました。
AWS Lambda Powertoolsは、Lambda Functionに対してサーバーレスのベストプラクティスを適用できるユーティリティで、AWS LabsからOSSとして提供されています。
今まではPythonとJavaでのみ提供されており、TypeScriptはbeta release(以下ブログ参照)でしたが、このたびproduct releaseとなりました。
今回は、GAされたこのAWS Lambda Powertools for TypeScriptを早速試してみました。
試してみた
まずはじめに、Lambda FunctionのTypeScriptコードにAWS Lambda Powertoolsを適用する方法は次の3つがあります。
- Middy middleware:Middy middleware engineを使う方法。Lambda Functionsに簡単にAWS Lambda Powertoolsを組み込める。
- Manually:middlewareの追加などを行わない方法。AWS Lambda Powertoolsのきめ細かな制御が可能。
- Method decorator:TypeScript method decoratorsを使用する方法。クラスを使う場合に有用。
今回はMiddyを使用した実装を試してみます。開発環境にmiddyをインストールしておきます。
npm i @middy/core
Lambda FunctionはAWS CDK(TypeScript)で構築します。
lib/aws-app-stack.ts
import { Construct } from 'constructs';
import { aws_lambda_nodejs, Stack, StackProps } from 'aws-cdk-lib';
import { Tracing } from 'aws-cdk-lib/aws-lambda';
export class AwsAppStack extends Stack {
constructor(scope: Construct, id: string, props: StackProps) {
super(scope, id, props);
new aws_lambda_nodejs.NodejsFunction(this, 'logger');
new aws_lambda_nodejs.NodejsFunction(this, 'tracer', {
tracing: Tracing.ACTIVE,
}); //Tracerを使うFunctionはX-Rayの追跡を有効にする
new aws_lambda_nodejs.NodejsFunction(this, 'metrics');
}
}
AWS Lambda Powertools for TypeScriptには、次の3つの機能があります。
- Logger
- Tracer
- Metrics
それぞれの機能を試してみます。
Logger
Loggerを使用すると、Lambdaの実行イベントの構造化ログをCloudWatch Logsに出力することができます。
@aws-lambda-powertools/logger
をインストールします。
npm install @aws-lambda-powertools/logger
Lambdaのコードは次のようになります。Logger
を初期化してHandlerで使用します。オプションでaddPersistentLogAttributes
を使用すると任意のAttributeを出力ログに含めることができるので、Event Dataはこれを使用してLogに含めるようにすると良さそうです。
lib/aws-app-stack.logger.ts
import { Logger, injectLambdaContext } from '@aws-lambda-powertools/logger';
import middy from '@middy/core';
const logger = new Logger({
logLevel: 'INFO',
serviceName: 'shopping-cart-api',
});
const lambdaHandler = async (event: unknown): Promise<void> => {
logger.addPersistentLogAttributes({ event: event });
logger.info('This is an INFO log with some context');
};
export const handler = middy(lambdaHandler).use(injectLambdaContext(logger));
DeployしたLambda Functionを実行すると、次のEvent Logが出力されました。
log
{
"cold_start": true,
"function_arn": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:AwsAppStack-loggerE71C1604-7O0zP2rA8iBZ",
"function_memory_size": 128,
"function_name": "AwsAppStack-loggerE71C1604-7O0zP2rA8iBZ",
"function_request_id": "5c4e6be5-870f-487a-a0e8-bc05d44f1d9c",
"level": "INFO",
"message": "This is an INFO log with some context",
"service": "shopping-cart-api",
"timestamp": "2022-07-23T09:33:23.238Z",
"xray_trace_id": "1-62dbc062-2b65813062b227f4358eb9c1",
"event": {
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
}
Tracer
TracerはAWS X-Ray SDK for Node.jsの軽量ラッパーで、Handler実行時のSegment毎のTraceデータをAWS X-Rayに記録できます。
@aws-lambda-powertools/tracer
をインストールします。
npm install @aws-lambda-powertools/tracer
Lambdaのコードは次のようになります。
import { Tracer, captureLambdaHandler } from '@aws-lambda-powertools/tracer';
import middy from '@middy/core';
const tracer = new Tracer({
serviceName: 'shopping-cart-api',
});
const lambdaHandler = async (): Promise<void> => {
/* ... Something happens ... */
};
export const handler = middy(lambdaHandler).use(captureLambdaHandler(tracer));
Lambdaを実行してX-RayのTraceを見ると、index.handler
のSegmentが記録されていますね。
またTracerでは、Handlerの中にサブセグメントを持たせて詳細なTraceを記録することも可能です。詳細は下記をご参考ください。
Metrics
Metricsを使用すると、Lambda実行をカスタムメトリクスとして発行できます。Amazon CloudWatch Embedded Metric Format (EMF)の形式でCloudWatch Logsに出力されたログが非同期でCloudWatch Metricsに発行されます。
@aws-lambda-powertools/metrics
をインストールします。
npm install @aws-lambda-powertools/metrics
Lambdaのコードは次のようになります。
lib/aws-app-stack.metrics.ts
import {
Metrics,
MetricUnits,
logMetrics,
} from '@aws-lambda-powertools/metrics';
import middy from '@middy/core';
const metrics = new Metrics({
namespace: 'serverlessAirline',
serviceName: 'orders',
});
const lambdaHandler = async (): Promise<void> => {
metrics.addMetric('successfulBooking', MetricUnits.Count, 1);
};
export const handler = middy(lambdaHandler).use(logMetrics(metrics));
Lambdaを実行すると、CloudWatch LogsにMetricsの情報が記録されています。
log
{
"_aws": {
"Timestamp": 1658570601859,
"CloudWatchMetrics": [
{
"Namespace": "serverlessAirline",
"Dimensions": [
[
"service"
]
],
"Metrics": [
{
"Name": "successfulBooking",
"Unit": "Count"
}
]
}
]
},
"service": "orders",
"successfulBooking": 1
}
MetricsのNamespaceを見ると、メトリクスが発行されていることが確認できます。
おわりに
AWS Lambda Powertools for TypeScriptがGAされたので試してみました。
AWS Lambdaのロギングの実装は開発者やプロジェクトによってバラツキがあると思いますが、今後はAWS Lambda Powertoolsに統一されていく流れになるかも知れませんね。
参考
- Simplifying serverless best practices with AWS Lambda Powertools for TypeScript | AWS Compute Blog
- Homepage - AWS Lambda Powertools for TypeScript
以上