# backend/app/observability/middleware.py — 요청 컨텍스트(request_id) + 접근 로그 + 메트릭 import time import uuid from starlette.middleware.base import BaseHTTPMiddleware from starlette.requests import Request from . import metrics from .logging import get_logger, request_id_ctx class RequestContextMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next): rid = request.headers.get("X-Request-Id") or uuid.uuid4().hex[:12] token = request_id_ctx.set(rid) start = time.monotonic() status = 500 try: response = await call_next(request) status = response.status_code return response finally: dur = time.monotonic() - start metrics.http_request(request.method, request.url.path, status, dur) get_logger("ari.access").info( "request", extra={ "method": request.method, "path": request.url.path, "status": status, "dur_ms": round(dur * 1000, 1), }, ) request_id_ctx.reset(token)