121 lines
4.2 KiB
Python
121 lines
4.2 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Dict, List, Tuple
|
|
|
|
try:
|
|
from prometheus_client import Counter as _PromCounter
|
|
from prometheus_client import generate_latest as _prom_generate_latest
|
|
from prometheus_client import CONTENT_TYPE_LATEST as _PROM_CONTENT_TYPE
|
|
_PROM_OK = True
|
|
except Exception:
|
|
_PROM_OK = False
|
|
|
|
|
|
if _PROM_OK:
|
|
# Total send requests, labeled by routed node_id
|
|
SOFIIA_SEND_REQUESTS_TOTAL = _PromCounter(
|
|
"sofiia_send_requests_total",
|
|
"Total number of send requests processed by sofiia-console",
|
|
["node_id"],
|
|
)
|
|
|
|
# Total idempotency replays (same response served again)
|
|
SOFIIA_IDEMPOTENCY_REPLAYS_TOTAL = _PromCounter(
|
|
"sofiia_idempotency_replays_total",
|
|
"Total number of idempotency replays served from cache",
|
|
)
|
|
|
|
# Total cursor pagination requests
|
|
SOFIIA_CURSOR_REQUESTS_TOTAL = _PromCounter(
|
|
"sofiia_cursor_requests_total",
|
|
"Total number of cursor pagination requests",
|
|
["resource"],
|
|
)
|
|
SOFIIA_RATE_LIMITED_TOTAL = _PromCounter(
|
|
"sofiia_rate_limited_total",
|
|
"Total number of requests rejected by rate limiting",
|
|
["scope"],
|
|
)
|
|
|
|
def render_metrics() -> Tuple[bytes, str]:
|
|
return _prom_generate_latest(), _PROM_CONTENT_TYPE
|
|
|
|
else:
|
|
class _FallbackCounterChild:
|
|
def __init__(self, parent: "_FallbackCounter", key: Tuple[str, ...]):
|
|
self._parent = parent
|
|
self._key = key
|
|
|
|
def inc(self, amount: float = 1.0) -> None:
|
|
self._parent._values[self._key] = self._parent._values.get(self._key, 0.0) + float(amount)
|
|
|
|
class _FallbackCounter:
|
|
def __init__(self, name: str, doc: str, labelnames: List[str] | Tuple[str, ...] | None = None):
|
|
self.name = name
|
|
self.doc = doc
|
|
self.labelnames = tuple(labelnames or [])
|
|
self._values: Dict[Tuple[str, ...], float] = {}
|
|
|
|
def labels(self, **kwargs: str) -> _FallbackCounterChild:
|
|
key = tuple(str(kwargs.get(lbl, "")) for lbl in self.labelnames)
|
|
if key not in self._values:
|
|
self._values[key] = 0.0
|
|
return _FallbackCounterChild(self, key)
|
|
|
|
def inc(self, amount: float = 1.0) -> None:
|
|
key = tuple()
|
|
self._values[key] = self._values.get(key, 0.0) + float(amount)
|
|
|
|
def _render(self) -> List[str]:
|
|
out = [f"# HELP {self.name} {self.doc}", f"# TYPE {self.name} counter"]
|
|
if not self._values:
|
|
if self.labelnames:
|
|
out.append(f"{self.name}{{}} 0.0")
|
|
else:
|
|
out.append(f"{self.name} 0.0")
|
|
return out
|
|
for key, value in self._values.items():
|
|
if self.labelnames:
|
|
labels = ",".join(
|
|
f'{lname}="{lval}"' for lname, lval in zip(self.labelnames, key)
|
|
)
|
|
out.append(f"{self.name}{{{labels}}} {value}")
|
|
else:
|
|
out.append(f"{self.name} {value}")
|
|
return out
|
|
|
|
SOFIIA_SEND_REQUESTS_TOTAL = _FallbackCounter(
|
|
"sofiia_send_requests_total",
|
|
"Total number of send requests processed by sofiia-console",
|
|
["node_id"],
|
|
)
|
|
SOFIIA_IDEMPOTENCY_REPLAYS_TOTAL = _FallbackCounter(
|
|
"sofiia_idempotency_replays_total",
|
|
"Total number of idempotency replays served from cache",
|
|
)
|
|
SOFIIA_CURSOR_REQUESTS_TOTAL = _FallbackCounter(
|
|
"sofiia_cursor_requests_total",
|
|
"Total number of cursor pagination requests",
|
|
["resource"],
|
|
)
|
|
SOFIIA_RATE_LIMITED_TOTAL = _FallbackCounter(
|
|
"sofiia_rate_limited_total",
|
|
"Total number of requests rejected by rate limiting",
|
|
["scope"],
|
|
)
|
|
|
|
_ALL = [
|
|
SOFIIA_SEND_REQUESTS_TOTAL,
|
|
SOFIIA_IDEMPOTENCY_REPLAYS_TOTAL,
|
|
SOFIIA_CURSOR_REQUESTS_TOTAL,
|
|
SOFIIA_RATE_LIMITED_TOTAL,
|
|
]
|
|
|
|
def render_metrics() -> Tuple[bytes, str]:
|
|
lines: List[str] = []
|
|
for c in _ALL:
|
|
lines.extend(c._render())
|
|
text = "\n".join(lines) + "\n"
|
|
return text.encode("utf-8"), "text/plain; version=0.0.4; charset=utf-8"
|
|
|