AWS Lambda에서 Ruby 코드 계측(Instrumenting)

AWS Lambda에서 Ruby 코드 계측(Instrumenting)

Lambda는 AWS X-Ray와 통합되어 Lambda 애플리케이션을 추적, 디버그, 최적화할 수 있게 해줘요. X-Ray를 사용하면 프런트엔드 API부터 백엔드의 저장소와 데이터베이스까지 애플리케이션의 리소스를 가로지르는 요청을 추적할 수 있죠. 빌드 구성에 X-Ray SDK 라이브러리를 추가하기만 하면 함수가 AWS 서비스에 호출하는 모든 호출의 오류와 지연 시간을 기록할 수 있어요.

활성 추적을 구성한 뒤에는 애플리케이션을 통과하는 특정 요청을 관찰할 수 있어요. X-Ray 서비스 그래프는 애플리케이션과 모든 구성 요소에 대한 정보를 보여줘요. 다음 예제는 함수 두 개가 있는 애플리케이션을 보여줍니다. 기본 함수는 이벤트를 처리하고 가끔 오류를 반환해요. 맨 위의 두 번째 함수는 첫 번째 함수의 로그 그룹에 나타난 오류를 처리하며, AWS SDK를 사용해 X-Ray, Amazon Simple Storage Service(Amazon S3), Amazon CloudWatch Logs를 호출합니다.

두 개의 개별 애플리케이션과 각각의 X-Ray 서비스 맵을 보여주는 다이어그램

콘솔에서 Lambda 함수의 활성 추적(active tracing)을 켜려면 다음 단계를 따르세요.

활성 추적 켜기

  1. Lambda 콘솔의 함수 페이지를 엽니다.
  2. 함수를 선택합니다.
  3. Configuration(구성)을 선택한 다음 Monitoring and operations tools(모니터링 및 운영 도구)를 선택합니다.
  4. Additional monitoring tools(추가 모니터링 도구)에서 Edit(편집)을 선택합니다.
  5. CloudWatch Application Signals and AWS X-Ray 아래에서 Lambda service traces에 대해 Enable(활성화)을 선택합니다.
  6. Save(저장)를 선택합니다.

요금
AWS Free Tier의 일부로 매월 일정 한도까지 X-Ray 추적을 무료로 사용할 수 있어요. 그 임계값을 넘으면 X-Ray는 추적 저장과 검색에 요금을 부과해요. 자세한 내용은 AWS X-Ray 요금을 참고하세요.

함수는 추적 데이터를 X-Ray에 업로드할 권한이 필요해요. Lambda 콘솔에서 추적을 활성화하면 Lambda가 함수의 실행 역할에 필요한 권한을 추가해요. 그렇지 않으면 실행 역할에 AWSXRayDaemonWriteAccess 정책을 추가하세요.

X-Ray는 애플리케이션에 대한 모든 요청을 추적하진 않아요. X-Ray는 추적이 효율적이면서도 모든 요청의 대표적인 샘플을 제공하도록 샘플링 알고리즘을 적용해요. 샘플링 비율은 초당 1개 요청과 추가 요청의 5%예요. 함수의 X-Ray 샘플링 비율은 구성할 수 없습니다.

출처: AWS Lambda 개발자 안내서

본문

X-Ray에서 trace(추적)는 하나 이상의 service(서비스)가 처리하는 요청에 대한 정보를 기록해요. Lambda는 추적마다 2개의 세그먼트를 기록해서 서비스 그래프에 두 개의 노드를 만들어요. 다음 이미지는 이 두 노드를 강조합니다:

단일 함수가 있는 X-Ray 서비스 맵.

왼쪽의 첫 번째 노드는 호출 요청을 받는 Lambda 서비스를 나타내요. 두 번째 노드는 여러분의 특정 Lambda 함수를 나타냅니다. 다음 예제는 이 두 세그먼트가 있는 추적을 보여줘요. 둘 다 my-function이라는 이름이지만, 하나는 origin이 AWS::Lambda이고 다른 하나는 origin이 AWS::Lambda::Function이에요. AWS::Lambda 세그먼트에 오류가 표시되면 Lambda 서비스에 문제가 있는 것이고, AWS::Lambda::Function 세그먼트에 오류가 표시되면 여러분의 함수에 문제가 있는 거예요.

특정 Lambda 호출의 각 하위 세그먼트별 지연 시간을 보여주는 X-Ray 추적.

이 예제는 AWS::Lambda::Function 세그먼트를 펼쳐서 세 개의 하위 세그먼트를 보여줍니다.

참고
AWS는 현재 Lambda 서비스에 변경 사항을 구현하고 있어요. 이 변경으로 인해 AWS 계정의 서로 다른 Lambda 함수가 내보내는 시스템 로그 메시지와 추적 세그먼트의 구조 및 내용에 약간의 차이가 있을 수 있습니다.
여기 표시된 예제 추적은 이전 스타일의 함수 세그먼트를 보여줘요. 이전/새 스타일 세그먼트의 차이는 다음 단락에 설명되어 있죠.
이 변경은 향후 몇 주에 걸쳐 구현되며, 중국 및 GovCloud 리전을 제외한 모든 AWS 리전의 모든 함수가 새 형식의 로그 메시지와 추적 세그먼트로 전환될 예정입니다.

이전 스타일 함수 세그먼트에는 다음 하위 세그먼트가 포함돼요:

  • Initialization(초기화) – 함수를 로드하고 초기화 코드를 실행하는 데 걸린 시간을 나타내요. 이 하위 세그먼트는 함수 인스턴스 각각이 처리하는 첫 번째 이벤트에만 나타나요.
  • Invocation(호출) – 핸들러 코드를 실행하는 데 걸린 시간을 나타내요.
  • Overhead(오버헤드) – Lambda 런타임이 다음 이벤트를 처리할 준비를 하는 데 쓰는 시간을 나타내요.

새 스타일 함수 세그먼트에는 Invocation 하위 세그먼트가 없어요. 대신 고객 하위 세그먼트가 함수 세그먼트에 직접 연결되죠. 이전/새 스타일 함수 세그먼트의 구조에 대해 더 알아보려면 X-Ray 추적 이해를 참고하세요.

핸들러 코드를 계측해 메타데이터를 기록하고 다운스트림 호출을 추적할 수 있어요. 핸들러가 다른 리소스와 서비스에 하는 호출에 대한 상세 정보를 기록하려면 Ruby용 X-Ray SDK를 사용하세요. SDK를 얻으려면 aws-xray-sdk 패키지를 애플리케이션의 의존성에 추가하세요.

예제 blank-ruby/function/Gemfile

# Gemfile
source 'https://rubygems.org'

gem 'aws-xray-sdk', '0.11.4'
gem 'aws-sdk-lambda', '1.39.0'
gem 'test-unit', '3.3.5'

AWS SDK 클라이언트를 계측하려면 초기화 코드에서 클라이언트를 만든 뒤 aws-xray-sdk/lambda 모듈을 require 하세요.

예제 blank-ruby/function/lambda_function.rb – AWS SDK 클라이언트 추적

# lambda_function.rb
require 'logger'
require 'json'
require 'aws-sdk-lambda'
$client = Aws::Lambda::Client.new()
$client.get_account_settings()

require 'aws-xray-sdk/lambda'

def lambda_handler(event:, context:)
  logger = Logger.new($stdout)
  ...

X-Ray에서 trace(추적)는 하나 이상의 service(서비스)가 처리하는 요청에 대한 정보를 기록해요. Lambda는 추적마다 2개의 세그먼트를 기록해서 서비스 그래프에 두 개의 노드를 만들어요. 다음 이미지는 이 두 노드를 강조합니다:

단일 함수가 있는 X-Ray 서비스 맵.

왼쪽의 첫 번째 노드는 호출 요청을 받는 Lambda 서비스를 나타내요. 두 번째 노드는 여러분의 특정 Lambda 함수를 나타냅니다. 다음 예제는 이 두 세그먼트가 있는 추적을 보여줘요. 둘 다 my-function이라는 이름이지만, 하나는 origin이 AWS::Lambda이고 다른 하나는 origin이 AWS::Lambda::Function이에요. AWS::Lambda 세그먼트에 오류가 표시되면 Lambda 서비스에 문제가 있는 것이고, AWS::Lambda::Function 세그먼트에 오류가 표시되면 여러분의 함수에 문제가 있는 거예요.

특정 Lambda 호출의 각 하위 세그먼트별 지연 시간을 보여주는 X-Ray 추적.

이 예제는 AWS::Lambda::Function 세그먼트를 펼쳐서 세 개의 하위 세그먼트를 보여줍니다.

참고
AWS는 현재 Lambda 서비스에 변경 사항을 구현하고 있어요. 이 변경으로 인해 AWS 계정의 서로 다른 Lambda 함수가 내보내는 시스템 로그 메시지와 추적 세그먼트의 구조 및 내용에 약간의 차이가 있을 수 있습니다.
여기 표시된 예제 추적은 이전 스타일의 함수 세그먼트를 보여줘요. 이전/새 스타일 세그먼트의 차이는 다음 단락에 설명되어 있죠.
이 변경은 향후 몇 주에 걸쳐 구현되며, 중국 및 GovCloud 리전을 제외한 모든 AWS 리전의 모든 함수가 새 형식의 로그 메시지와 추적 세그먼트로 전환될 예정입니다.

이전 스타일 함수 세그먼트에는 다음 하위 세그먼트가 포함돼요:

  • Initialization(초기화) – 함수를 로드하고 초기화 코드를 실행하는 데 걸린 시간을 나타내요. 이 하위 세그먼트는 함수 인스턴스 각각이 처리하는 첫 번째 이벤트에만 나타나요.
  • Invocation(호출) – 핸들러 코드를 실행하는 데 걸린 시간을 나타내요.
  • Overhead(오버헤드) – Lambda 런타임이 다음 이벤트를 처리할 준비를 하는 데 쓰는 시간을 나타내요.

새 스타일 함수 세그먼트에는 Invocation 하위 세그먼트가 없어요. 대신 고객 하위 세그먼트가 함수 세그먼트에 직접 연결되죠. 이전/새 스타일 함수 세그먼트의 구조에 대해 더 알아보려면 X-Ray 추적 이해를 참고하세요.

HTTP 클라이언트를 계측하고, SQL 쿼리를 기록하고, 주석(annotation)과 메타데이터로 커스텀 하위 세그먼트를 만들 수도 있어요. 자세한 내용은 AWS X-Ray 개발자 안내서의 Ruby용 X-Ray SDK를 참고하세요.

Topics(주제)

Lambda API로 활성 추적 활성화

AWS CLI 또는 AWS SDK로 추적 구성을 관리하려면 다음 API 작업을 사용하세요:

다음 예제 AWS CLI 명령은 my-function이라는 함수의 활성 추적을 활성화해요.

aws lambda update-function-configuration --function-name my-function \
--tracing-config Mode=Active

추적 모드는 함수 버전을 게시할 때 버전별 구성(version-specific configuration)의 일부가 돼요. 게시된 버전에서는 추적 모드를 변경할 수 없습니다.

CloudFormation으로 활성 추적 활성화

CloudFormation 템플릿에서 AWS::Lambda::Function 리소스의 추적을 활성화하려면 TracingConfig 속성을 사용하세요.

예제 function-inline.yml – 추적 구성

Resources:
  function:
    Type: [AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)
    Properties:
      TracingConfig:
        Mode: Active
      ...

AWS Serverless Application Model(AWS SAM) AWS::Serverless::Function 리소스에는 Tracing 속성을 사용하세요.

예제 template.yml – 추적 구성

Resources:
  function:
    Type: [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
    Properties:
      Tracing: Active
      ...

레이어(layer)에 런타임 의존성 저장

X-Ray SDK로 함수 코드의 AWS SDK 클라이언트를 계측하면 배포 패키지가 꽤 커질 수 있어요. 함수 코드를 업데이트할 때마다 런타임 의존성을 다시 업로드하지 않으려면 X-Ray SDK를 Lambda 레이어에 패키징하세요.

다음 예제는 Ruby용 X-Ray SDK를 저장하는 AWS::Serverless::LayerVersion 리소스를 보여줘요.

예제 template.yml – 의존성 레이어

Resources:
  function:
    Type: [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
    Properties:
      CodeUri: function/.
      Tracing: Active
      Layers:
        - !Ref libs
      ...
  libs:
    Type: [AWS::Serverless::LayerVersion](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-layerversion.html)
    Properties:
      LayerName: blank-ruby-lib
      Description: Dependencies for the blank-ruby sample app.
      ContentUri: lib/.
      CompatibleRuntimes:
        - ruby2.5

이 구성에서는 런타임 의존성을 변경할 때만 라이브러리 레이어를 업데이트하면 돼요. 함수 배포 패키지에 코드만 담기므로 업로드 시간을 줄이는 데 도움이 됩니다.

의존성용 레이어를 만들려면 배포 전에 레이어 아카이브를 생성하는 빌드 변경이 필요해요. 작동하는 예제는 blank-ruby 샘플 애플리케이션을 참고하세요.

더 알아보기 (Learn more)

  • 콘솔·API·CloudFormation으로 활성 추적을 켜고, X-Ray SDK로 AWS SDK 클라이언트를 계측하며, 런타임 의존성을 레이어에 모아두는 Ruby 트레이싱 흐름을 다뤄 보세요.