File size: 1,411 Bytes
6de2f28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
"""
SmartCertify ML β€” Request/Response Logging Middleware
"""

import time
import logging
from fastapi import Request, Response
from starlette.middleware.base import BaseHTTPMiddleware

logger = logging.getLogger("smartcertify.api")


class RequestLoggingMiddleware(BaseHTTPMiddleware):
    """Middleware to log all API requests and responses."""

    async def dispatch(self, request: Request, call_next):
        start_time = time.time()

        # Log request
        logger.info(
            f"β†’ {request.method} {request.url.path} "
            f"[{request.client.host if request.client else 'unknown'}]"
        )

        # Process request
        try:
            response = await call_next(request)
        except Exception as e:
            duration_ms = (time.time() - start_time) * 1000
            logger.error(
                f"βœ— {request.method} {request.url.path} β€” "
                f"ERROR: {str(e)} [{duration_ms:.1f}ms]"
            )
            raise

        duration_ms = (time.time() - start_time) * 1000

        # Log response
        log_fn = logger.warning if response.status_code >= 400 else logger.info
        log_fn(
            f"← {request.method} {request.url.path} β€” "
            f"{response.status_code} [{duration_ms:.1f}ms]"
        )

        # Add timing header
        response.headers["X-Process-Time-Ms"] = f"{duration_ms:.1f}"
        return response