X-Ray 트레이싱 구현하기

AWS 모니터링 및 문제 해결

John Q. Martin

Principal Consultant

X-Ray SDK 개요

 

핵심 요약:

  • 지원 언어: Python, Node.js, Java, .NET, Go, Ruby
  • 두 가지 방식: 자동 계측과 수동 계측
  • SDK는 UDP 포트 2000에서 데몬과 통신합니다
  • X-Ray API와 직접 통신하지 않습니다

 

자동 vs. 수동:

자동 및 수동 X-Ray SDK 계측 방식 비교

AWS 모니터링 및 문제 해결

Python SDK: Flask 설정

 

from flask import Flask
from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.ext.flask.middleware import XRayMiddleware

app = Flask(__name__)

xray_recorder.configure(
    service='MyFlaskApp',
    sampling=True,
    context_missing='LOG_ERROR',
    daemon_address='127.0.0.1:2000'
)

XRayMiddleware(app, xray_recorder)

 

레코더 설정 네 가지:

  • service - 서비스 맵에 표시되는 이름
  • sampling - 샘플링 활성화/비활성화
  • context_missing - LOG_ERROR로 설정하면 크래시 방지
  • daemon_address - 세그먼트를 보낼 위치

미들웨어를 연결하면 모든 수신 요청이 자동으로 추적됩니다.

AWS 모니터링 및 문제 해결

자동 계측: Python

 

# Instrument all supported libraries
from aws_xray_sdk.core import patch_all
patch_all()
# Or selectively
from aws_xray_sdk.core import patch
patch(['boto3', 'requests', 'psycopg2'])

 

지원 라이브러리:

boto3, requests, 데이터베이스 클라이언트 등 X-Ray 자동 계측이 지원하는 라이브러리

AWS 모니터링 및 문제 해결

수동 계측: Python

 

데코레이터 방식:

@xray_recorder.capture('process_order')
def process_order(order_id):
    order = get_order(order_id)
    return process_payment(order)

 

컨텍스트 매니저 방식:

def process_order(order_id):
    with xray_recorder.capture('fetch_order'):
        order = db.query(Order).filter_by(
            id=order_id).first()
    with xray_recorder.capture('process_payment'):
        return payment_service.charge(order.total)
AWS 모니터링 및 문제 해결

코드 내 어노테이션과 메타데이터

 

어노테이션 추가:

xray_recorder.put_annotation(
    'order_id', order_id)
xray_recorder.put_annotation(
    'user_id', user_id)

 

메타데이터 추가(상세 컨텍스트):

xray_recorder.put_metadata(
    'order_details',
    {'items': order.items,
     'total': order.total})
  • 어노테이션은 인덱스로 사용되지만 메타데이터는 그렇지 않습니다
  • 어노테이션은 타입이 있고, 메타데이터는 모든 JSON을 허용합니다
  • 필터링에는 인덱스를, 디버깅 컨텍스트에는 메타데이터를 사용하세요
AWS 모니터링 및 문제 해결

트레이스에서의 오류 처리

 

def process_order(order_id):
    try:
        order = get_order(order_id)
        payment = process_payment(order)
        return payment
    except PaymentError as e:
        xray_recorder.put_annotation(
            'error_type', 'payment_failed')
        xray_recorder.put_metadata(
            'error_details',
            {'message': str(e), 'order_id': order_id})
        raise

 

  • 추적 대상 함수 내 예외는 자동으로 캡처됩니다
  • 콘솔에서 필터링할 수 있도록 오류 유형 어노테이션을 추가하세요
  • 전체 오류 상세 정보는 메타데이터로 추가하세요
  • 항상 예외를 다시 발생시켜야 애플리케이션의 오류 처리가 정상 동작합니다
AWS 모니터링 및 문제 해결

Node.js SDK: Express 설정

 

const AWSXRay = require('aws-xray-sdk-core');
const xrayExpress = require('aws-xray-sdk-express');
const app = require('express')();

AWSXRay.config([AWSXRay.plugins.EC2Plugin]);

// Open segment for all incoming requests
app.use(xrayExpress.openSegment('MyExpressApp'));

app.get('/api/orders/:id', async (req, res) => {
    const order = await fetchOrder(req.params.id);
    res.json({ order });
});

// Close segment after response
app.use(xrayExpress.closeSegment());

// Automatic instrumentation
const AWS = AWSXRay.captureAWS(require('aws-sdk'));
const https = AWSXRay.captureHTTPs(require('https'));
AWS 모니터링 및 문제 해결

Lambda 구현

 

from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch_all

patch_all()  # instrument AWS SDK calls

def lambda_handler(event, context):
    xray_recorder.put_annotation(
        'user_id', event['user_id'])

    result = process_user(event['user_id'])

    return {
        'statusCode': 200,
        'body': json.dumps(result)
    }

 

핵심 요약:

  • Active Tracing을 활성화하면 Lambda가 기본 트레이스를 자동으로 전송하며, 이때는 SDK가 필요 없습니다
  • 서브세그먼트, 어노테이션 추가 및 하위 호출 계측을 위해서는 X-Ray SDK를 설치하세요
  • 콘솔에서 활성화: Configuration → Monitoring tools
  • 또는 템플릿에서: Tracing: Active
AWS 모니터링 및 문제 해결

ECS와 Fargate: 사이드카 패턴

 

태스크 구조:

ECS Task
|_ Application Container
|   sends to xray-daemon:2000
|_ X-Ray Daemon Container
    forwards to X-Ray service

앱 컨테이너 설정:

xray_recorder.configure(
    service='MyECSApp',
    daemon_address='xray-daemon:2000'
)

 

태스크 정의 구성 요소:

  • 데몬 컨테이너: amazon/aws-xray-daemon 이미지, UDP 포트 2000
  • 앱 컨테이너: 환경 변수 AWS_XRAY_DAEMON_ADDRESS=xray-daemon:2000

사이드카 패턴을 쓰는 이유

  • 데몬이 태스크와 함께 스케일링됩니다
  • 장애가 태스크별로 격리됩니다
AWS 모니터링 및 문제 해결

X-Ray 데몬 설치하기

플랫폼별 설치:

  • Amazon Linux 2
    • sudo yum install -y aws-xray-daemon-3.x.rpm
  • Ubuntu
    • sudo dpkg -i aws-xray-daemon-3.x.deb
  • Windows
    • xray.exe -f cfg.yaml install
  • Docker
    • docker run -p 2000:2000/udp amazon/aws-xray-daemon

설치 후:

sudo systemctl start xray
sudo systemctl enable xray

데몬이 하는 일:

  • UDP 포트 2000에서 대기
  • 세그먼트를 버퍼링하고 일괄 처리
  • HTTPS로 X-Ray API에 전달
  • 재시도 처리, 애플리케이션이 직접 할 필요 없음
AWS 모니터링 및 문제 해결

데몬 설정

 

TotalBufferSizeMB: 24
Concurrency: 8
Region: "us-east-1"
Socket:
  UDPAddress: "127.0.0.1:2000"
  TCPAddress: "127.0.0.1:2000"
Logging:
  LogLevel: "info"
  LogPath: "/var/log/xray/xray-daemon.log"
LocalMode: false

 

  • 버퍼 크기, 트래픽이 많으면 늘리세요
  • 동시성은 X-Ray와의 병렬 연결 수를 설정합니다
  • 컨테이너의 경우 UDP 주소를 0.0.0.0으로 설정하세요
  • 로컬 모드, 자격 증명 없이 로컬 개발 시 true로 설정하세요
AWS 모니터링 및 문제 해결

IAM 권한

 

{
  "Effect": "Allow",
  "Action": [
    "xray:PutTraceSegments",
    "xray:PutTelemetryRecords",
    "xray:GetSamplingRules",
    "xray:GetSamplingTargets",
    "xray:GetSamplingStatisticSummaries"
  ],
  "Resource": "*"
}

 

가장 쉬운 방법

관리형 정책 AWSXRayDaemonWriteAccess 를 사용하세요

다음에 연결:

  • EC2 인스턴스 역할
  • ECS 태스크 역할
  • Lambda 실행 역할

권한이 올바르지 않으면 데몬은 실행되지만 세그먼트 전송에 조용히 실패합니다.

AWS 모니터링 및 문제 해결

데몬 배포 패턴

 

인스턴스별, 사이드카, 공유 서비스 등 세 가지 X-Ray 데몬 배포 패턴

AWS 모니터링 및 문제 해결

레슨 요약

 

  • SDK: patch_all()로 자동 계측, 데코레이터와 컨텍스트 매니저로 수동 계측
  • 어노테이션(인덱싱, 검색 가능) vs. 메타데이터(상세, 비인덱싱)
  • Lambda: 기본 트레이스는 자동 전송되며, 서브세그먼트와 하위 호출을 위해서는 SDK를 설치하세요
  • ECS/Fargate: 사이드카 데몬 컨테이너 패턴
  • 데몬: cfg.yaml로 설정하며 AWSXRayDaemonWriteAccess IAM 정책이 필요합니다
  • 배포: EC2는 인스턴스별, 컨테이너는 사이드카 방식
AWS 모니터링 및 문제 해결

X-Ray 트레이싱 구현하기

AWS 모니터링 및 문제 해결

Preparing Video For Download...