서버리스 앱을 X-Ray로 추적하기

이 챕터는 Seed 블로그에 게시된 글을 기반으로 합니다 — www.seed.run/blog/how-to-trace-serverless-apps-with-aws-x-ray.


일반적으로 서버리스 앱이 커질수록 관련된 AWS 서비스의 수도 증가합니다. 이로 인해 디버깅이 까다로워질 수 있습니다. AWS X-Ray는 애플리케이션이 만든 요청을 기록하고 시각화하는 서비스입니다. 이 서비스는 서버리스 애플리케이션을 통과하는 요청의 종단 간 뷰를 제공하며, 애플리케이션의 기본 구성 요소 맵을 보여줍니다.

이 챕터에서는 Serverless Framework 애플리케이션의 API 요청과 Lambda 호출을 추적하기 위해 AWS X-Ray를 설정하는 방법을 설명합니다.

API Gateway와 Lambda에 X-Ray 트레이싱 활성화

먼저 애플리케이션에 X-Ray를 활성화해 보겠습니다.

serverless.yml 파일을 열고 provider 섹션 안에 tracing 설정을 추가합니다:

provider:
  ...
  tracing:
    apiGateway: true
    lambda: true

그런 다음 provider 섹션 내부의 iamRoleStatements 아래에 Lambda가 X-Ray에 기록할 수 있도록 필요한 IAM 권한을 추가합니다:

provider:
  ...
  iamRoleStatements:
    - Effect: Allow
      Action:
        ...
        - xray:PutTraceSegments
        - xray:PutTelemetryRecords
      Resource: "*"

다음은 예제로 사용할 Lambda 함수입니다.

const AWS = require("aws-sdk");
const dynamodb = new AWS.DynamoDB.DocumentClient();
const sns = new AWS.SNS();

exports.main = async function (event) {
  await dynamodb
    .get({
      TableName: "notes",
      Key: { noteId: "note1" },
    })
    .promise();

  await sns
    .publish({
      Message: "test",
      TopicArn: "arn:aws:sns:us-east-1:113345762000:test-topic",
    })
    .promise();

  return { statusCode: 200, body: "successful" };
};

이제 serverless deploy를 실행하여 서비스를 배포합니다. serverless.yml 파일을 수정했으므로 전체 애플리케이션을 배포해야 합니다.

기존 서버리스 프로젝트에 AWS X-Ray 트레이싱을 활성화하려면 Serverless CLI 버전이 1.44 이상인지 확인하세요.

배포가 완료되면 API Gateway 엔드포인트를 호출합니다:

$ curl https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/xxx

AWS X-Ray 콘솔로 이동하여 왼쪽 메뉴에서 Traces를 선택합니다.

AWS X-Ray 콘솔에서 Traces 선택

상단의 Trace overview 섹션은 트레이스를 시작한 모든 URL을 보여줍니다. 하단의 Trace list 섹션은 각각의 개별 트레이스를 표시합니다. 기본적으로 지난 5분 동안의 모든 트레이스를 보여주지만, 다른 시간 범위를 선택할 수도 있습니다.

Trace list에서 트레이스를 클릭합니다. 요청 후 트레이스가 표시되기까지 최대 30초가 걸릴 수 있습니다.

AWS X-Ray 콘솔에서 트레이스 선택

여기서 확인할 수 있는 몇 가지 사항은 다음과 같습니다:

  • API 요청은 GET 요청이었으며 HTTP 200 상태로 성공했습니다.
  • 전체 요청은 API Gateway에서 597ms가 걸렸습니다.
  • 597ms 중 594ms는 Lambda 함수에서 소요되었습니다. 즉, API Gateway는 이 요청에 3ms의 오버헤드를 추가했습니다.
  • 594ms 중 387ms는 Lambda 초기화에 소요되었습니다. 이것이 콜드 스타트 시간입니다.
  • 실제 함수 실행에는 107ms가 걸렸습니다.

그러나 여전히 궁금한 점이 있습니다:

  • DynamoDB 쿼리와 SNS 호출 각각에 얼마나 시간이 걸렸는가?
  • API 요청이 실패하면 DynamoDB 단계에서 실패했는지, 아니면 SNS 단계에서 실패했는지 어떻게 알 수 있는가?

이를 위해 Lambda가 호출한 서비스에 대해 X-Ray 트레이싱을 활성화해야 합니다.

AWS Lambda에서 호출한 다른 AWS 서비스에 X-Ray 트레이싱 활성화

AWS X-Ray SDK를 설치합니다. 프로젝트 디렉토리에서 다음 명령어를 실행하세요:

$ npm install -s aws-xray-sdk

Lambda 코드를 업데이트하고 AWS SDK를 X-Ray SDK로 감싸세요. 다음 코드를:

const AWS = require("aws-sdk");

다음과 같이 변경하세요:

const AWSXRay = require("aws-xray-sdk-core");
const AWS = AWSXRay.captureAWS(require("aws-sdk"));

이제 준비가 끝났습니다!

다시 serverless deploy를 실행하여 변경 사항을 배포하세요. 이번에는 serverless deploy -f FUNCTION_NAME을 사용해 단일 함수만 배포할 수 있습니다. 함수 코드만 변경했고 serverless.yml은 수정하지 않았기 때문입니다.

배포가 완료되면 API Gateway 엔드포인트를 다시 호출하세요:

$ curl https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/xxx

AWS X-Ray 콘솔로 돌아가서 새로운 트레이스가 나타날 때까지 기다리세요. 최대 30초 정도 걸릴 수 있습니다. 트레이스가 최근인지 확인하려면 Age를 확인하세요:

AWS X-Ray 콘솔에서 최근 트레이스 선택

새로운 트레이스를 선택하세요.

AWS X-Ray 콘솔에서 업데이트된 트레이스 보기

이번에는:

  • Lambda 콜드 스타트는 461ms가 걸렸고, 요청 처리에는 185ms가 소요되었습니다.
  • 185ms 중 DynamoDB 쿼리는 73ms, SNS publish 호출은 98ms가 걸렸습니다.

또한 Lambda 함수 호출의 다양한 단계를 명확히 확인할 수 있습니다. 샘플 리포지토리는 기본적으로 AWS X-Ray가 활성화되어 있으므로 이 장에서 다룬 개념을 직접 실험해 볼 수 있습니다.