Add role-based filtering and imporve code
This commit is contained in:
83
gateway/app/middleware/request_id.py
Normal file
83
gateway/app/middleware/request_id.py
Normal file
@@ -0,0 +1,83 @@
|
||||
"""
|
||||
Request ID Middleware for distributed tracing
|
||||
Generates and propagates unique request IDs across all services
|
||||
"""
|
||||
|
||||
import uuid
|
||||
import structlog
|
||||
from fastapi import Request
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
from starlette.responses import Response
|
||||
|
||||
logger = structlog.get_logger()
|
||||
|
||||
|
||||
class RequestIDMiddleware(BaseHTTPMiddleware):
|
||||
"""
|
||||
Middleware to generate and propagate request IDs for distributed tracing.
|
||||
|
||||
Request IDs are:
|
||||
- Generated if not provided by client
|
||||
- Logged with every request
|
||||
- Propagated to all downstream services
|
||||
- Returned in response headers
|
||||
"""
|
||||
|
||||
def __init__(self, app):
|
||||
super().__init__(app)
|
||||
|
||||
async def dispatch(self, request: Request, call_next) -> Response:
|
||||
"""Process request with request ID tracking"""
|
||||
|
||||
# Extract or generate request ID
|
||||
request_id = request.headers.get("X-Request-ID")
|
||||
if not request_id:
|
||||
request_id = str(uuid.uuid4())
|
||||
|
||||
# Store in request state for access by routes
|
||||
request.state.request_id = request_id
|
||||
|
||||
# Bind request ID to structured logger context
|
||||
logger_ctx = logger.bind(request_id=request_id)
|
||||
|
||||
# Inject request ID header for downstream services
|
||||
# This is done by modifying the headers that will be forwarded
|
||||
request.headers.__dict__["_list"].append((
|
||||
b"x-request-id", request_id.encode()
|
||||
))
|
||||
|
||||
# Log request start
|
||||
logger_ctx.info(
|
||||
"Request started",
|
||||
method=request.method,
|
||||
path=request.url.path,
|
||||
client_ip=request.client.host if request.client else None
|
||||
)
|
||||
|
||||
try:
|
||||
# Process request
|
||||
response = await call_next(request)
|
||||
|
||||
# Add request ID to response headers
|
||||
response.headers["X-Request-ID"] = request_id
|
||||
|
||||
# Log request completion
|
||||
logger_ctx.info(
|
||||
"Request completed",
|
||||
method=request.method,
|
||||
path=request.url.path,
|
||||
status_code=response.status_code
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
except Exception as e:
|
||||
# Log request failure
|
||||
logger_ctx.error(
|
||||
"Request failed",
|
||||
method=request.method,
|
||||
path=request.url.path,
|
||||
error=str(e),
|
||||
error_type=type(e).__name__
|
||||
)
|
||||
raise
|
||||
Reference in New Issue
Block a user