AWS Lambda에서 TypeScript 코드 추적

AWS Lambda에서 TypeScript 코드 추적 (Tracing TypeScript code in AWS Lambda)

Lambda는 AWS X-Ray와 통합되어 Lambda 애플리케이션을 추적, 디버깅, 최적화하는 데 도움을 줍니다. X-Ray를 사용해 요청이 Lambda 함수와 다른 AWS 서비스를 포함한 애플리케이션의 리소스를 통과할 때 그 요청을 추적할 수 있습니다.

X-Ray로 추적 데이터를 보내려면 세 가지 SDK 라이브러리 중 하나를 사용할 수 있습니다:

  • AWS Distro for OpenTelemetry (ADOT) — OpenTelemetry(OTel) SDK의 안전하고 프로덕션 준비가 된 AWS 지원 배포판입니다.
  • AWS X-Ray SDK for Node.js — 추적 데이터를 생성해 X-Ray로 보내는 SDK입니다.
  • Powertools for AWS Lambda (TypeScript) — Serverless 모범 사례를 구현하고 개발자 생산성을 높이는 개발자 툴킷입니다.

각 SDK는 원격 측정 데이터를 X-Ray 서비스로 보내는 방법을 제공합니다. 그런 다음 X-Ray를 사용해 애플리케이션의 성능 메트릭을 보고, 필터링하고, 분석해 문제와 최적화 기회를 식별할 수 있습니다.

중요

X-Ray 및 Powertools for AWS Lambda SDK는 AWS가 제공하는 긴밀하게 통합된 계측 솔루션의 일부입니다. ADOT Lambda 레이어는 일반적으로 더 많은 데이터를 수집하지만 모든 사용 사례에 적합하지 않을 수 있는 업계 표준 추적 계측 솔루션입니다. 두 솔루션 중 하나로 X-Ray에서 종단 간 추적을 구현할 수 있습니다. 둘 중 선택하는 방법에 대해 알아보려면 AWS Distro for Open Telemetry와 X-Ray SDK 중 선택을 참조하세요.

출처: AWS Lambda 개발자 안내서

본문

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 메시지를 반환합니다.

사전 조건:

이 섹션의 단계를 완료하려면 다음이 있어야 합니다:

  • Node.js
  • AWS CLI 버전 2
  • AWS SAM CLI 버전 1.75 이상. 더 오래된 버전의 AWS SAM CLI가 있으면 AWS SAM CLI 업그레이드를 참조하세요.

샘플 AWS SAM 애플리케이션 배포:

  1. Hello World TypeScript 템플릿으로 애플리케이션을 초기화합니다.
sam init --app-template hello-world-powertools-typescript --name sam-app --package-type Zip --runtime nodejs24.x --no-tracing
  1. 앱을 빌드합니다.
cd sam-app && sam build
  1. 앱을 배포합니다.
sam deploy --guided
  1. 화면 프롬프트를 따릅니다. 대화형 환경에서 제공된 기본 옵션을 수락하려면 Enter를 누르세요.

참고

"HelloWorldFunction may not have authorization defined. Is this okay?"에서는 y를 입력해야 합니다.

  1. 배포된 애플리케이션의 URL을 가져옵니다:
aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
  1. API 엔드포인트를 호출합니다:
curl -X GET <URL>

성공하면 다음 응답이 표시됩니다:

{"message":"hello world"}
  1. 함수의 추적을 얻으려면 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

이것은 인터넷을 통해 액세스할 수 있는 공개 API 엔드포인트입니다. 테스트 후 엔드포인트를 삭제할 것을 권장합니다.

sam delete

X-Ray는 애플리케이션에 대한 모든 요청을 추적하지 않습니다. X-Ray는 모든 요청의 대표 샘플을 제공하면서도 추적이 효율적이도록 샘플링 알고리즘을 적용합니다. 샘플링 속도는 초당 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 메시지를 반환합니다.

사전 조건:

이 섹션의 단계를 완료하려면 다음이 있어야 합니다:

  • Node.js
  • AWS CLI 버전 2
  • AWS CDK 버전 2
  • AWS SAM CLI 버전 1.75 이상. 더 오래된 버전의 AWS SAM CLI가 있으면 AWS SAM CLI 업그레이드를 참조하세요.

샘플 AWS Cloud Development Kit (AWS CDK) 애플리케이션 배포:

  1. 새 애플리케이션용 프로젝트 디렉터리를 만듭니다.
mkdir hello-world
cd hello-world
  1. 앱을 초기화합니다.
cdk init app --language typescript
  1. @types/aws-lambda 패키지를 개발 종속성으로 추가합니다.
npm install -D @types/aws-lambda
  1. Powertools Tracer 유틸리티를 설치합니다.
npm install @aws-lambda-powertools/tracer
  1. lib 디렉터리를 엽니다. hello-world-stack.ts라는 파일이 보여야 합니다. 이 디렉터리에 hello-world.function.ts와 hello-world.ts라는 새 파일 두 개를 만듭니다.

  2. 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;
};
  1. 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,
    });
  }
}
  1. 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');
  }
}
  1. 애플리케이션을 배포합니다.
cd ..
cdk deploy
  1. 배포된 애플리케이션의 URL을 가져옵니다:
aws cloudformation describe-stacks --stack-name HelloWorldStack --query 'Stacks[0].Outputs[?ExportName==`apiUrl`].OutputValue' --output text
  1. API 엔드포인트를 호출합니다:
curl -X GET <URL>

성공하면 다음 응답이 표시됩니다:

{"message":"hello world"}
  1. 함수의 추적을 얻으려면 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

이것은 인터넷을 통해 액세스할 수 있는 공개 API 엔드포인트입니다. 테스트 후 엔드포인트를 삭제할 것을 권장합니다.

cdk destroy

X-Ray 추적 해석

활성 추적을 구성한 후 애플리케이션을 통한 특정 요청을 관찰할 수 있습니다. X-Ray 추적 맵은 애플리케이션과 모든 구성 요소에 대한 정보를 제공합니다. 다음 예제는 샘플 애플리케이션의 추적을 보여줍니다:

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

이 추적에서 최상위 세그먼트(sam-app/Prod)는 API Gateway입니다. Lambda 세그먼트(sam-app-HelloWorldFunction-Xyzv11a1bcde)는 Lambda 함수를 나타냅니다. 세그먼트 아래의 하위 세그먼트는 Init, Invocation, Overhead의 실행 환경 수명주기 단계를 보여줍니다. ## app.lambdaHandler는 함수 핸들러를 나타내고 ### MySubSegment는 코드에서 만든 사용자 지정 하위 세그먼트입니다.

더 알아보기 (Learn more)

  • AWS X-Ray를 통한 Lambda 추적
  • AWS Distro for OpenTelemetry
  • Powertools for AWS Lambda (TypeScript)