from __future__ import annotations try: from prometheus_client import Counter, Gauge # type: ignore except Exception: class _Metric: def __init__(self, *_, **__): self._values = {} def labels(self, **kwargs): key = tuple(sorted(kwargs.items())) class H: def __init__(self, parent, k): self._p = parent; self._k = k def inc(self, v: float = 1.0): self._p._values[self._k] = self._p._values.get(self._k, 0.0) + v def set(self, v: float): self._p._values[self._k] = v return H(self, key) class Counter(_Metric): pass class Gauge(_Metric): pass replication_under = Counter("dht_replication_under", "Times replication fell below target", ["content_id"]) replication_over = Counter("dht_replication_over", "Times replication exceeded target", ["content_id"]) leader_changes = Counter("dht_leader_changes_total", "Count of leader changes per content", ["content_id"]) merge_conflicts = Counter("dht_merge_conflicts_total", "Number of DHT merge conflicts", ["key"]) view_count_total = Gauge("dht_view_count_total", "Total content views per window", ["content_id", "window"]) unique_estimate = Gauge("dht_unique_view_estimate", "Estimated unique viewers per window", ["content_id", "window"]) watch_time_seconds = Gauge("dht_watch_time_seconds", "Aggregate watch time per window", ["content_id", "window"]) def record_replication_under(content_id: str, have: int) -> None: replication_under.labels(content_id=content_id).inc() def record_replication_over(content_id: str, have: int) -> None: replication_over.labels(content_id=content_id).inc() def record_leader_change(content_id: str) -> None: leader_changes.labels(content_id=content_id).inc() def record_merge_conflict(key: str) -> None: merge_conflicts.labels(key=key).inc() def update_view_metrics(content_id: str, window_id: str, views: int, unique: float, watch_time: int) -> None: view_count_total.labels(content_id=content_id, window=window_id).set(views) unique_estimate.labels(content_id=content_id, window=window_id).set(unique) watch_time_seconds.labels(content_id=content_id, window=window_id).set(watch_time)