Files
AISHub/src/ais_hub/core/stats.py
T
2026-05-04 08:13:38 +03:00

45 lines
1.3 KiB
Python

"""Global counters & simple rate samples."""
from __future__ import annotations
import time
from collections import defaultdict
from dataclasses import dataclass, field
from threading import Lock
from typing import Any
@dataclass
class Stats:
"""Thread/async-safe counter container.
Counters are plain integers keyed by name. Gauges hold instantaneous
numeric values. Queue depth samples are reported via ``set_gauge``.
"""
counters: dict[str, int] = field(default_factory=lambda: defaultdict(int))
gauges: dict[str, float] = field(default_factory=dict)
started_at: float = field(default_factory=time.time)
_lock: Lock = field(default_factory=Lock, repr=False)
def incr(self, name: str, n: int = 1) -> None:
with self._lock:
self.counters[name] += n
def set_gauge(self, name: str, value: float) -> None:
with self._lock:
self.gauges[name] = value
def snapshot(self) -> dict[str, Any]:
with self._lock:
now = time.time()
return {
"uptime_sec": round(now - self.started_at, 3),
"started_at": self.started_at,
"counters": dict(self.counters),
"gauges": dict(self.gauges),
}
__all__ = ["Stats"]