Skip to content
4월 14, 2025chattiboyPaaS, Django

Django에서 OpenTelemetry를 이용해 Jaeger로 Trace 남기기

image 33

이전 포스팅에서 Log생성을 해보았다.
이번에는 Tracing을 해본다.

Trace

Trace는 하나의 작업(요청)이 여러 시스템이나 컴포넌트를 거쳐 처리되는 과정을 기록하고 시각화한 것이다.

  • 시스템 어디서 병목이 생기는지,
  • 어떤 부분에서 오류가 나는지,
  • 요청이 어디서 얼마나 오래 걸렸는지 확인할 수 있다.

일반적인 로그와는 다르다.

  • 로그는 → logging 시스템 (text, line-by-line)
  • 트레이스(Trace)는 → 서비스 호출 흐름을 시각화해서 보여줌 (A가 B를 부르고, B가 C를 부르는 관계)
  • 시스템이 복잡해질수록 (API → DB → 외부서비스) 흐름을 추적하기가 어려워진다.
  • Trace는 요청 흐름을 시간순서대로, 계층적으로 시각화 해준다.

Jaeger와 OpenTelemetry

Jaeger

오픈소스 분산 트레이싱 시스템 (시각화 도구)

OpenTelemetry

코드에 트레이스를 심고 다양한 시스템으로 전송하는 표준 프레임워크

Django에 Trace를 심는 방법

  • Install OpenTelemetry SDK on Django
  • Create SPAN besween Request and Response
  • Then, send the trace to Jaeger.

Install OpenTelemetry SDK on Django

# 1. OpenTelemetry 기본 SDK
# pip install opentelemetry-sdk

# 2. Django용 자동 Instrumentation
pip install opentelemetry-instrumentation-django

# 3. Jaeger로 보내는 OTLP Exporter
pip install opentelemetry-exporter-otlp

{DjangoProject}/wsgi.py 수정

서버 시작 시 트레이스 기능을 사용할수 있도록 구성합니다.

테스트 중인 Django 애플리케이션의 배포환경은 Kubernetes에서 배포되고 있습니다.
따라서, endpoint는 쿠버네티스 service와 namspace를 지정하면됩니다.
endpoint: http://jaeger-collector.istio-system:4317

Django Project에 있는 wsgi.py에 설정합니다.

import os

# ✅ Django 설정을 미리 불러온다
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'butler_ddochi.settings')

from django.conf import settings  # <<<< 이거 추가

# ✅ DEBUG 모드 아닐 때만 OpenTelemetry 초기화
if not settings.DEBUG:
    from opentelemetry import trace
    from opentelemetry.sdk.resources import Resource
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import BatchSpanProcessor
    from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
    from opentelemetry.instrumentation.django import DjangoInstrumentor

    trace.set_tracer_provider(
        TracerProvider(
            resource=Resource.create({
                "service.name": "butler_ddochi",
            })
        )
    )

    otlp_exporter = OTLPSpanExporter(
        endpoint="http://jaeger-collector.istio-system:4317",
        insecure=True,
    )

    trace.get_tracer_provider().add_span_processor(
        BatchSpanProcessor(otlp_exporter)
    )

    DjangoInstrumentor().instrument()

from django.core.wsgi import get_wsgi_application

application = get_wsgi_application()

테스트 조회

아직 테스트가 끝난 것이 아닙니다. 이벤트로그가 없고 기본적인 span만 나타나는 것을 확인합니다.

  • Trace는 span이 모여서 구성됩니다.
  • span은 “어떤 작업(동작, 프로세스)의 시작부터 끝까지를 하나로 묶어 추적하는 단위”를 말합니다.
    • name, start time, end time, attributes, events, optional.. 등 정보가 들어 있습니다.
image 34
image 31

조회를 해보면 이벤트 로그가 없다. 직접 생성해야 한다.

image 32

View 안에서 Custom Span 만들기

예제 샘플

......
......

import logging
from opentelemetry import trace

logger = logging.getLogger(__name__)
tracer = trace.get_tracer(__name__)  # 트레이서 가져오기

......
......

def add_ip_record(request):
    if request.method == "POST":
        network_nm = request.POST.get("network_nm")
        ip_addrs = request.POST.get("ip_addrs")
        svr_nm = request.POST.get("svr_nm")
        contents = request.POST.get("contents")
        remark = request.POST.get("remark")
        author = request.user

        # 2025-04-14 트레이스 span 생성
        with tracer.start_as_current_span("create_ip_record") as span:
            # 데이터 저장
            IPManagementRecord.objects.create(
                network_nm=network_nm,
                ip_addrs=ip_addrs,
                svr_nm=svr_nm,
                contents=contents,
                remark=remark,
                author=author,
            )

            # 2025-04-14 Jaeger용 Event 추가
            span.add_event(
                "Saved IPManagementRecord",
                attributes={
                    "ip_addrs": ip_addrs,
                    "svr_nm": svr_nm,
                    "desc": "jager logs test",
                }
            )

        # 2025-04-14 로그 등록 (콘솔+FluentBit용)
        logger.info(f"Create_Record_IP_ADDRS: {ip_addrs}")

        return redirect("/ip_mgmt")

......
......

span이 추가되었고 event도 발생한다.

image 33

Leave a comment