트레이싱: 개념, 원리 및 데이터 수집

저자: IT Sectr 게시일: 2026-05-29 읽는 시간: 8 분

트레이싱은 분산 시스템을 통한 요청의 흐름을 관찰하는 방법으로, 각 처리 단계가 타임스탬프가 있는 별도의 이벤트로 기록됩니다. OpenTelemetry, 2025에 따르면, trace는 모든 마이크로서비스와 외부 호출을 통과하는 요청의 전체 경로를 진입점부터 최종 응답까지 결합합니다. 이를 통해 개발자는 복잡한 모바일 백엔드 아키텍처에서 병목 현상, 지연 및 장애를 식별할 수 있습니다.

핵심 사항

  • 트레이싱 — 각 단계의 시간 측정과 함께 분산 시스템의 모든 구성 요소를 통한 요청 경로 기록.
  • Span — 시작 및 종료 시간과 함께 단일 작업을 나타내는 트레이싱의 기본 단위.
  • 분산 추적 — 컨텍스트 전파를 통해 여러 서비스의 span을 단일 trace 체인으로 연결하는 메커니즘.
  • OpenTelemetry — 모든 주요 언어와 플랫폼에서 트레이싱을 지원하는 텔레메트리 수집 표준.
  • 샘플링 — 데이터 볼륨과 스토리지 비용을 제어할 수 있는 트레이싱 대상 요청 선택 전략.

모니터링에서 트레이싱이란

트레이싱은 각 수신 요청을 시스템의 모든 서비스와 구성 요소를 통해 추적하는 분산 관찰 방법입니다. 집계 값을 표시하는 메트릭(평균 응답 시간, 오류 수)과 달리, 트레이싱은 단일 특정 요청의 전체 컨텍스트를 보존합니다.

각 처리 단계(데이터베이스 호출, 다른 마이크로서비스에 대한 HTTP 요청, 백그라운드 작업 실행)는 타임스탬프, 상태 및 속성이 있는 별도의 단위로 기록됩니다. Google Dapper(2010년 원본 논문)에 따르면, 트레이싱을 통해 분산 시스템의 지연을 단일 호출 수준까지 정확히 파악할 수 있습니다.

트레이싱은 백엔드가 수십 개의 마이크로서비스로 구성된 모바일 애플리케이션에서 특히 중요합니다. 계정 로그인과 같은 사용자 작업은 API 게이트웨이, 인증 서비스, 데이터베이스 및 푸시 서비스를 거칠 수 있습니다. 트레이싱이 없으면 어떤 구성 요소가 응답을 느리게 하는지 확인하는 것이 거의 불가능합니다.

Span 및 trace: 기본 데이터 구조

트레이싱의 기본 단위는 span입니다. 각 span은 하나의 논리적 작업(HTTP 요청, SQL 쿼리, gRPC 호출, JSON 직렬화)을 나타냅니다. span에는 고유 식별자, 부모 식별자, 작업 이름, 시작 시간, 기간, 상태 및 속성 집합이 포함됩니다.

Trace 내 Span 계층 구조

동일한 루트 요청과 관련된 모든 span은 trace로 그룹화됩니다. 루트 span은 진입점(모바일 클라이언트에서 API로의 HTTP 요청)을 나타냅니다. 자식 span은 트리를 형성하며, 각 span은 parent_span_id 필드를 통해 부모를 참조합니다.

trace의 기간은 모든 span의 고유 시간 세그먼트 기간의 합계와 같습니다. 두 개의 자식 span이 병렬로 실행되는 경우 시간이 합산되지 않습니다. 이는 병렬 마이크로서비스 호출로 인한 지연을 올바르게 분석하는 데 중요합니다.

Span 속성 및 이벤트

각 span에는 속성(메타 정보가 있는 키-값 쌍: 요청 URL, 사용자 ID, API 버전, 호스트 이름)이 포함될 수 있습니다. 속성은 trace 필터링 및 그룹화에 사용됩니다. 속성 외에도 span은 이벤트("캐시 미스" 또는 "연결 재시도"와 같은 텍스트 설명이 있는 타임스탬프)를 지원합니다.

분산 추적 작동 방식

분산 추적은 다른 프로세스와 다른 시스템에서 생성된 span을 연결하는 문제를 해결합니다. 메커니즘은 컨텍스트 전파를 기반으로 합니다. 서비스 A가 서비스 B를 호출할 때 현재 trace ID와 부모 span ID가 포함된 헤더가 나가는 요청에 추가됩니다.

표준 컨텍스트 전파 프로토콜은 W3C Trace Context(traceparent 및 tracestate 헤더)와 Zipkin B3(X-B3-TraceId, X-B3-SpanId 헤더)입니다. W3C Trace Context는 2021년 W3C 컨소시엄에 의해 표준으로 채택되었으며 모든 주요 텔레메트리 제공업체에서 지원됩니다.

요청을 수신하면 서비스 B는 헤더에서 trace_id를 추출하고 해당 trace_id로 자식 span을 만듭니다. 따라서 요청이 완료된 후 다른 서비스의 모든 span이 수집기 측에서 하나의 trace로 결합됩니다. 이를 위해서는 각 서비스가 동일한 트레이싱 라이브러리로 계측되어야 합니다.

마이크로서비스의 컨텍스트 전파

모바일 개발에서 컨텍스트 전파는 백엔드뿐만 아니라 클라이언트-서버 상호 작용도 포함합니다. 모바일 애플리케이션은 각 API 요청의 헤더에 trace_id를 전송하여 클라이언트 작업을 서버 측 처리와 연결할 수 있습니다. iOS 및 Android용 OpenTelemetry SDK는 HTTP 클라이언트를 통한 trace 컨텍스트의 자동 생성 및 전파를 지원합니다.

kotlin
import io.opentelemetry.api.trace.Span
import io.opentelemetry.api.trace.Tracer
import io.opentelemetry.context.Context

class TracingInterceptor : Interceptor {
    private val tracer: Tracer = OpenTelemetry.getTracer("mobile-app")

    override fun intercept(chain: Interceptor.Chain): Response {
        val span = tracer.spanBuilder("HTTP POST /api/login")
            .setParent(Context.current())
            .startSpan()

        return chain.proceed(chain.request())
            .also { span.end() }
    }
}

제시된 Kotlin 인터셉터는 서버에 대한 각 HTTP 요청에 대해 span을 만듭니다. 부모 컨텍스트는 Context.current()를 통해 호출 코드에서 전파되어 클라이언트 측 트레이싱을 서버 측 트레이싱에 연결할 수 있습니다.

OpenTelemetry를 통한 트레이싱 구현

OpenTelemetry는 Trace 데이터 수집의 사실상 표준입니다. span 생성을 위한 통합 API, 널리 사용되는 라이브러리의 자동 계측, 그리고 다양한 백엔드(Jaeger, Zipkin, Grafana Tempo, Datadog, New Relic)로 데이터를 내보내기 위한 유연한 메커니즘을 제공합니다.

자동 계측

OpenTelemetry는 널리 사용되는 프레임워크(Spring Boot, Ktor, Flask, Express, gRPC)에 대한 자동 span 생성을 지원합니다. 개발자는 프로젝트에 종속성을 추가하기만 하면 라이브러리가 자동으로 수신 및 발신 요청을 가로챕니다. Java의 자동 계측은 소스 코드를 변경하지 않고 바이트코드를 실시간으로 수정하는 javaagent를 사용합니다.

모바일 플랫폼의 경우 OpenTelemetry는 Swift SDK와 Kotlin SDK를 제공합니다. 이들은 네트워크 요청(URLSession, OkHttp), 데이터베이스 작업(CoreData, Room) 및 백그라운드 작업에 대한 span을 자동으로 생성합니다. 개발자는 비즈니스 로직에 대한 사용자 정의 span을 추가할 수 있습니다.

데이터 내보내기

수집된 span은 OTLP(OpenTelemetry Protocol)를 통해 수집기로 전송됩니다. 수집기는 데이터를 버퍼링, 필터링 및 하나 이상의 스토리지 시스템으로 전달할 수 있습니다. OpenTelemetry 문서에 따르면 gRPC 내보내기를 사용할 때 span 생성부터 대시보드 표시까지의 일반적인 지연 시간은 2~5초입니다.

swift
import OpenTelemetryApi
import OpenTelemetrySdk
import URLSessionInstrumentation

let instrumentation = URLSessionInstrumentation()
instrumentation.enable()

let tracer = OpenTelemetry.instance.tracerFactory
    .get("mobile-monitoring")

let span = tracer.spanBuilder("fetch-user-profile")
    .setAttribute(key: "user.id", value: userId)
    .startSpan()
span.end()

Swift 코드는 네트워킹 레이어의 자동 계측을 활성화하고 사용자 프로필 검색 작업에 대한 사용자 정의 span을 만듭니다. user.id 속성을 사용하면 나중에 특정 사용자별로 trace를 필터링할 수 있습니다.

Trace 샘플링 전략

고부하 시스템에서는 모든 요청을 추적하는 것이 불가능합니다. 스토리지와 네트워크에 허용할 수 없는 부하가 발생합니다. 샘플링은 trace의 일부만 저장하여 이 문제를 해결합니다. 전략 선택은 데이터 완전성과 인프라 비용에 직접적인 영향을 미칩니다.

헤드 기반 샘플링

trace 저장 결정은 생성 시점(루트 span)에 이루어집니다. 가장 간단하고 일반적인 접근 방식: 요청의 고정 비율(예: 5%)을 저장하고 나머지는 폐기합니다. 단점은 드문 오류가 캡처된다는 보장이 없다는 것입니다. OpenTelemetry의 Probability sampler는 0.0에서 1.0까지의 확률 설정을 지원합니다.

테일 기반 샘플링

결정은 trace의 모든 span이 완료될 때까지 연기됩니다. 분석기는 trace에 오류, 시간 초과 또는 흥미로운 속성이 포함되어 있는지 평가한 후에만 저장합니다. 이 접근 방식은 수집기에서 모든 span을 버퍼링해야 하므로 메모리 소비가 증가합니다. Grafana Labs에 따르면, 드물지만 중요한 오류가 있는 시스템에서 테일 기반 샘플링은 "유용한 데이터당 비용" 측면에서 40~60% 더 효율적입니다.

전략장점단점
고정 확률단순함, 예측 가능한 부하드문 이벤트 누락
속도 제한보장된 데이터 볼륨불균일한 커버리지
테일 기반모든 오류 캡처높은 메모리 소비
적응형비용과 커버리지의 균형복잡한 구성

트레이싱과 로깅의 차이

로깅은 심각도 수준(정보, 경고, 오류)과 함께 개별 이벤트를 기록하지만 단일 요청의 컨텍스트로 연결하지 않습니다. 반면 트레이싱은 종단 간 요청에 속하는 작업의 구조화된 트리를 만듭니다. 실제로 이 두 접근 방식은 상호 배타적이지 않으며 서로를 보완합니다.

로그는 특정 오류의 세부 분석에 효과적입니다. 개발자는 정확한 메시지, 스택 추적 및 변수 값을 볼 수 있습니다. 트레이싱은 "요청이 5초가 걸리는 이유"에 대한 답을 제공하며, 어떤 마이크로서비스나 호출이 가장 많은 시간을 소비했는지 보여줍니다. Honeycomb(2024)에 따르면, 트레이싱과 로깅을 함께 사용하는 팀은 인시던트의 근본 원인을 2.3배 더 빠르게 찾습니다.

현대적인 접근 방식인 관측 가능성은 트레이싱, 메트릭 및 로그를 단일 시스템으로 결합합니다. OpenTelemetry는 이 세 신호 간의 상관 관계를 지원합니다. 각 span은 관련 로그에 대한 링크를 포함할 수 있으며, 메트릭은 특정 trace로 드릴다운하기 위해 trace_id로 태그될 수 있습니다.

자주 묻는 질문

트레이싱과 모니터링의 차이는 무엇인가요?

모니터링은 시스템의 집계 메트릭(평균 응답 시간, 분당 오류 수, CPU 부하)을 표시합니다. 트레이싱은 모든 구성 요소를 통한 단일 특정 요청의 경로를 보여줍니다. 모니터링은 "무슨 일이 일어나고 있는가"에 답하고, 트레이싱은 "왜 일어나고 있는가"에 답합니다.

요청의 몇 퍼센트를 추적해야 하나요?

프로덕션 시스템의 경우 헤드 기반 샘플링으로 1~5%의 요청이면 충분합니다. 시스템에서 오류가 거의 발생하지 않는 경우 모든 오류 trace 캡처에 중점을 둔 테일 기반 샘플링이 권장됩니다. 스테이징 환경에서는 제한 없이 100% 요청을 추적해도 됩니다.

어떤 도구가 분산 추적을 지원하나요?

주요 도구로는 Jaeger(Uber의 솔루션, 오픈 소스), Grafana Tempo(확장 가능한 trace 스토리지), Datadog APM, New Relic Distributed Tracing, AWS X-RayHoneycomb이 있습니다. 모두 데이터 수집을 위해 OpenTelemetry 표준을 지원합니다.

백엔드 없이 모바일 애플리케이션을 추적할 수 있나요?

네, 로컬 트레이싱은 단일 프로세스 내에서 작동합니다. iOS 및 Android용 OpenTelemetry SDK는 데이터베이스 읽기, 이미지 처리, 네트워크 요청과 같은 로컬 작업에 대한 span을 만듭니다. 이러한 trace는 분산되지 않지만 클라이언트 측 성능 진단에 유용합니다.

트레이싱은 애플리케이션 성능에 어떤 영향을 미치나요?

최신 트레이싱 라이브러리는 헤드 기반 샘플링으로 1% 미만의 오버헤드를 추가합니다. OpenTelemetry는 메인 스레드를 차단하지 않는 비동기 데이터 내보내기를 사용합니다. 모바일 기기의 경우 span 생성 빈도를 제한하고 적응형 샘플링 전략을 사용하는 것이 좋습니다.

요약

  • 트레이싱은 개별 작업 수준까지 분산 시스템의 모든 구성 요소를 통한 각 요청의 경로를 기록하는 관찰 방법입니다.
  • Span은 작업 이름, 기간, 상태 및 속성을 포함하는 트레이싱의 기본 단위입니다.
  • 분산 추적은 trace_id의 컨텍스트 전파를 통해 여러 서비스의 span을 연결하는 메커니즘입니다.
  • OpenTelemetry는 자동 계측 및 여러 백엔드를 지원하는 trace 데이터 수집 표준입니다.
  • 샘플링을 통해 저장된 trace의 양을 제어할 수 있습니다. 단순성에는 헤드 기반, 드문 오류 캡처에는 테일 기반이 적합합니다.
  • 트레이싱은 로깅 및 메트릭과 결합하여 시스템 관측 가능성의 완전한 그림을 제공합니다.
  • 분산 추적 구현은 인증, 결제, 데이터 로딩과 같은 중요한 시나리오부터 시작하여 점차 모든 서비스로 확장하는 것이 좋습니다.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기