You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
35 lines
1.2 KiB
Python
35 lines
1.2 KiB
Python
# 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)
|