klg-asutk-app/backend/app/middleware/request_logger.py
Yuriy fabe4fa72f feat(backend): 6 модулей для main/роутов + ws_notifications
- api/helpers: audit, is_authority, get_org_name, paginate_query, require_roles
- services/ws_manager: connect(ws, user_id, org_id), send_to_user, send_to_org, broadcast, make_notification(event, entity_type, entity_id, **extra)
- services/risk_scheduler: setup_scheduler (заглушка/APScheduler)
- services/email_service: email_service.send (заглушка)
- middleware/request_logger: RequestLoggerMiddleware
- core/rate_limit: RateLimitMiddleware (in-memory, RATE_LIMIT_PER_MINUTE, /health в обход)
- api/routes/ws_notifications: WebSocket /ws/notifications?user_id=&org_id=

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-14 23:21:57 +03:00

22 lines
958 B
Python

"""Request logging middleware."""
import logging, time
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
logger = logging.getLogger("klg.requests")
class RequestLoggerMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
start = time.time()
if request.url.path in ("/api/v1/health", "/api/v1/metrics"):
return await call_next(request)
response = await call_next(request)
ms = (time.time() - start) * 1000
logger.info("%s %s %d %.1fms", request.method, request.url.path, response.status_code, ms)
# Audit log regulator access
if "/regulator" in str(request.url.path):
logger.info("REGULATOR_ACCESS: %s %s from user=%s",
request.method, request.url.path, getattr(request.state, "user_id", "-"))
response.headers["X-Response-Time"] = f"{ms:.1f}ms"
return response