AWS Lambda での TypeScript コードのトレース - AWS Lambda

AWS Lambda での TypeScript コードのトレース

Lambda アプリケーションのトレース、デバッグ、最適化を行うために、Lambda は AWS X-Ray と統合されています。X-Ray を使用すると、Lambda 関数や他の AWS のサービスが含まれるアプリケーション内で、リソースを横断するリクエストをトレースできます。

トレーシングデータを X-Ray に送信するには、以下に表示された 3 つの SDK ライブラリのいずれかを使用できます。

各 SDK は、テレメトリデータを X-Ray サービスに送信する方法を提供します。続いて、X-Ray を使用してアプリケーションのパフォーマンスメトリクスの表示やフィルタリングを行い、インサイトを取得することで、問題点や最適化の機会を特定できます。

重要

X-Ray および Powertools for AWS Lambda SDK は、AWS が提供する、密接に統合された計測ソリューションの一部です。ADOT Lambda レイヤーは、一般的により多くのデータを収集するトレーシング計測の業界標準の一部ですが、すべてのユースケースに適しているわけではありません。これらのソリューションのいずれかを使用して、X-Ray でエンドツーエンドのトレーシングを実装することができます。選択方法の詳細については、「Choosing between the AWS Distro for Open Telemetry and X-Ray SDKs」( Distro for Open Telemetry または X-Ray SDK の選択) を参照してください。

トレース用の Powertools for AWS Lambda (TypeScript) と AWS SAM の使用

AWS SAM を使用した統合 Powertools for AWS Lambda (TypeScript) モジュールを使用して、Hello World TypeScript サンプルアプリケーションをダウンロード、ビルド、およびデプロイする場合は、以下の手順に従ってください。このアプリケーションは基本的な API バックエンドを実装し、Powertools を使用してログ、メトリクス、トレースを生成します。Amazon API Gateway エンドポイントと Lambda 関数で構成されています。API Gateway エンドポイントに GET リクエストを送信すると、Lambda 関数は呼び出し、Embedded Metric Format を使用してログおよびメトリクスを CloudWatch に送信、トレースを AWS X-Ray に送信します。関数は hello world のメッセージを返します。

前提条件

このセクションの手順を完了するには、以下が必要です。

AWS SAM サンプルアプリケーションをデプロイする
  1. Hello World TypeScript テンプレートを使用して、アプリケーションを初期化します。

    sam init --app-template hello-world-powertools-typescript --name sam-app --package-type Zip --runtime nodejs18.x --no-tracing
  2. アプリケーションを構築します。

    cd sam-app && sam build
  3. アプリケーションをデプロイします。

    sam deploy --guided
  4. 画面に表示されるプロンプトに従ってください。インタラクティブな形式で提供されるデフォルトオプションを受け入れるには、Enter を押します。

    注記

    [HelloWorldFunction には権限が定義されていない場合がありますが、問題ありませんか?] には、必ず y を入力してください。

  5. デプロイされたアプリケーションの URL を取得します。

    aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
  6. API エンドポイントを呼び出します。

    curl <URL_FROM_PREVIOUS_STEP>

    成功すると、次のレスポンスが表示されます。

    {"message":"hello world"}
  7. 関数のトレースを取得するには、sam traces を実行します。

    sam traces

    トレース出力は次のようになります。

    XRay Event [revision 1] at (2023-01-31T11:29:40.527000) with id (1-11a2222-111a222222cb33de3b95daf9) and duration (0.483s) - 0.425s - sam-app/Prod [HTTP: 200] - 0.422s - Lambda [HTTP: 200] - 0.406s - sam-app-HelloWorldFunction-Xyzv11a1bcde [HTTP: 200] - 0.172s - sam-app-HelloWorldFunction-Xyzv11a1bcde - 0.179s - Initialization - 0.112s - Invocation - 0.052s - ## app.lambdaHandler - 0.001s - ### MySubSegment - 0.059s - Overhead
  8. これは、インターネット経由でアクセス可能なパブリック API エンドポイントです。テスト後にエンドポイントを削除することを推奨します。

    sam delete

X-Ray は、アプリケーションへのすべてのリクエストをトレースするわけではありません。X-Ray は、サンプリングアルゴリズムを適用することで効率的なトレースを行うと同時に、すべてのリクエストについての代表的なサンプルを示します。サンプルレートは 1 秒あたり 1 回のリクエストで、追加リクエストの 5% です。関数の X-Ray サンプルレートを設定することはできません。

Powertools for AWS Lambda (TypeScript) およびトレース用の AWS CDK の使用

AWS CDK を使用した統合 Powertools for AWS Lambda (TypeScript) モジュールを使用して、Hello World TypeScript サンプルアプリケーションをダウンロード、ビルド、およびデプロイする場合は、以下の手順に従ってください。このアプリケーションは基本的な API バックエンドを実装し、Powertools を使用してログ、メトリクス、トレースを生成します。Amazon API Gateway エンドポイントと Lambda 関数で構成されています。API Gateway エンドポイントに GET リクエストを送信すると、Lambda 関数は呼び出し、Embedded Metric Format を使用してログおよびメトリクスを CloudWatch に送信、トレースを AWS X-Ray に送信します。関数は hello world のメッセージを返します。

前提条件

このセクションの手順を完了するには、以下が必要です。

AWS Cloud Development Kit (AWS CDK) サンプルアプリケーションをデプロイする
  1. 新しいアプリケーション用のプロジェクトディレクトリを作成します。

    mkdir hello-world cd hello-world
  2. アプリケーションを初期化します。

    cdk init app --language typescript
  3. 開発環境の依存関係として @types/aws-lambda パッケージを追加します。

    npm install -D @types/aws-lambda
  4. Powertools Tracer ユーティリティをインストールします。

    npm install @aws-lambda-powertools/tracer
  5. lib ディレクトリを開きます。hello-world-stack.ts という名前のファイルが表示されます。このディレクトリに hello-world.function.tshello-world.ts の 2 つの新しいファイルを作成します。

  6. hello-world.function.ts を開き、次のコードをファイルに追加します。これは Lambda 関数のコードです。

    import { APIGatewayEvent, APIGatewayProxyResult, Context } from 'aws-lambda'; import { Tracer } from '@aws-lambda-powertools/tracer'; const tracer = new Tracer(); export const handler = async (event: APIGatewayEvent, context: Context): Promise<APIGatewayProxyResult> => { // Get facade segment created by Lambda const segment = tracer.getSegment(); // Create subsegment for the function and set it as active const handlerSegment = segment.addNewSubsegment(`## ${process.env._HANDLER}`); tracer.setSegment(handlerSegment); // Annotate the subsegment with the cold start and serviceName tracer.annotateColdStart(); tracer.addServiceNameAnnotation(); // Add annotation for the awsRequestId tracer.putAnnotation('awsRequestId', context.awsRequestId); // Create another subsegment and set it as active const subsegment = handlerSegment.addNewSubsegment('### MySubSegment'); tracer.setSegment(subsegment); let response: APIGatewayProxyResult = { statusCode: 200, body: JSON.stringify({ message: 'hello world', }), }; // Close subsegments (the Lambda one is closed automatically) subsegment.close(); // (### MySubSegment) handlerSegment.close(); // (## index.handler) // Set the facade segment as active again (the one created by Lambda) tracer.setSegment(segment); return response; };
  7. hello-world.ts を開き、次のコードをファイルに追加します。これには、Lambda 関数を作成し、Powertools の環境変数を設定し、ログ保持を 1 週間に設定する NodejsFunction コンストラクトが含まれています。また、REST API を作成する LambdaRestApi コンストラクトも含まれています。

    import { Construct } from 'constructs'; import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'; import { LambdaRestApi } from 'aws-cdk-lib/aws-apigateway'; import { CfnOutput } from 'aws-cdk-lib'; import { Tracing } from 'aws-cdk-lib/aws-lambda'; export class HelloWorld extends Construct { constructor(scope: Construct, id: string) { super(scope, id); const helloFunction = new NodejsFunction(this, 'function', { environment: { POWERTOOLS_SERVICE_NAME: 'helloWorld', }, tracing: Tracing.ACTIVE, }); const api = new LambdaRestApi(this, 'apigw', { handler: helloFunction, }); new CfnOutput(this, 'apiUrl', { exportName: 'apiUrl', value: api.url, }); } }
  8. hello-world-stack.ts を開きます。これは、AWS CDK スタックを定義するコードです。このコードを、次のコードで置き換えます。

    import { Stack, StackProps } from 'aws-cdk-lib'; import { Construct } from 'constructs'; import { HelloWorld } from './hello-world'; export class HelloWorldStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); new HelloWorld(this, 'hello-world'); } }
  9. アプリケーションをデプロイします。

    cd .. cdk deploy
  10. デプロイされたアプリケーションの URL を取得します。

    aws cloudformation describe-stacks --stack-name HelloWorldStack --query 'Stacks[0].Outputs[?ExportName==`apiUrl`].OutputValue' --output text
  11. API エンドポイントを呼び出します。

    curl <URL_FROM_PREVIOUS_STEP>

    成功すると、次のレスポンスが表示されます。

    {"message":"hello world"}
  12. 関数のトレースを取得するには、sam traces を実行します。

    sam traces

    トレース出力は次のようになります。

    XRay Event [revision 1] at (2023-01-31T11:50:06.997000) with id (1-11a2222-111a222222cb33de3b95daf9) and duration (0.449s) - 0.350s - HelloWorldStack-helloworldfunction111A2BCD-Xyzv11a1bcde [HTTP: 200] - 0.157s - HelloWorldStack-helloworldfunction111A2BCD-Xyzv11a1bcde - 0.169s - Initialization - 0.058s - Invocation - 0.055s - ## index.handler - 0.000s - ### MySubSegment - 0.099s - Overhead
  13. これは、インターネット経由でアクセス可能なパブリック API エンドポイントです。テスト後にエンドポイントを削除することを推奨します。

    cdk destroy

X-Ray トレースの解釈

アクティブトレースの設定後は、アプリケーションを通じて特定のリクエストの観測が行えるようになります。X-Ray トレースマップには、アプリケーションとそのすべてのコンポーネントに関する情報が表示されます。次の例はで、サンプルアプリケーションのトレースを示しています。

サンプルアプリケーションの X-Ray サービスマップ