diff --git a/axon/services/metrics.py b/axon/services/metrics.py new file mode 100644 index 0000000..0123ef8 --- /dev/null +++ b/axon/services/metrics.py @@ -0,0 +1,36 @@ +import asyncio +from collections import defaultdict + + +class MetricsRegistry: + def __init__(self) -> None: + self._lock = asyncio.Lock() + self.requests_total = 0 + self.errors_total = 0 + self.latency_total_ms = 0.0 + self.requests_by_path: dict[str, int] = defaultdict(int) + + async def record(self, path: str, status_code: int, latency_ms: float) -> None: + async with self._lock: + self.requests_total += 1 + self.requests_by_path[path] += 1 + self.latency_total_ms += latency_ms + if status_code >= 500: + self.errors_total += 1 + + async def snapshot(self) -> dict: + async with self._lock: + average = ( + self.latency_total_ms / self.requests_total + if self.requests_total + else 0.0 + ) + return { + "requests_total": self.requests_total, + "requests_by_path": dict(self.requests_by_path), + "errors_total": self.errors_total, + "average_latency_ms": round(average, 3), + } + + +metrics = MetricsRegistry()