api / app /monitoring /metrics.py
Omarelrayes's picture
Create monitoring/metrics.py
6f3f565 verified
Raw
History Blame Contribute Delete
2.17 kB
# 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),
}