File size: 2,169 Bytes
6f3f565
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# app/monitoring/metrics.py
import time
from typing import Dict, Any
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.responses import Response


# =========================
# Simple Metrics Storage
# =========================
_metrics: Dict[str, Any] = {
    "total_requests": 0,
    "requests_by_endpoint": {},
    "requests_by_status": {},
    "total_latency_ms": 0.0,
    "start_time": time.time(),
}


# =========================
# Metrics Middleware
# =========================
class MetricsMiddleware(BaseHTTPMiddleware):
    """Middleware to collect request metrics"""
    
    async def dispatch(self, request: Request, call_next):
        start_time = time.time()
        
        # Process request
        response = await call_next(request)
        
        # Calculate latency
        process_time = (time.time() - start_time) * 1000  # ms
        
        # Update metrics
        _metrics["total_requests"] += 1
        _metrics["total_latency_ms"] += process_time
        
        endpoint = request.url.path
        _metrics["requests_by_endpoint"][endpoint] = (
            _metrics["requests_by_endpoint"].get(endpoint, 0) + 1
        )
        
        status = str(response.status_code)
        _metrics["requests_by_status"][status] = (
            _metrics["requests_by_status"].get(status, 0) + 1
        )
        
        return response


# =========================
# Metrics Endpoint
# =========================
def metrics_endpoint(request: Request) -> Dict[str, Any]:
    """
    Return metrics in JSON format.
    Compatible with Prometheus text format if needed.
    """
    uptime = time.time() - _metrics["start_time"]
    avg_latency = (
        _metrics["total_latency_ms"] / _metrics["total_requests"]
        if _metrics["total_requests"] > 0
        else 0.0
    )
    
    return {
        "total_requests": _metrics["total_requests"],
        "requests_by_endpoint": _metrics["requests_by_endpoint"],
        "requests_by_status": _metrics["requests_by_status"],
        "average_latency_ms": round(avg_latency, 2),
        "uptime_seconds": round(uptime, 2),
    }