이전 포스팅에서 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.. 등 정보가 들어 있습니다.


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

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도 발생한다.
