Skip to content

Commit

Permalink
fix/feat: register metrics only once andd add hit-miss
Browse files Browse the repository at this point in the history
  • Loading branch information
Krukov committed Mar 4, 2024
1 parent f5179d2 commit 86dc8d9
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 15 deletions.
40 changes: 26 additions & 14 deletions cashews/contrib/prometheus.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,41 @@
from typing import Optional

from prometheus_client import Histogram
from prometheus_client import Histogram, Counter

from cashews import cache
from cashews._typing import Middleware
from cashews.backends.interface import Backend
from cashews.commands import Command

_DEFAULT_METRIC = Histogram(
"cashews_operations_latency_seconds",
"Latency of different operations with a cache",
labelnames=["operation", "backend_class", "tag"],
)
_HIT_MISS = Counter(
"cashews_get_operation",
"Count of hits or missed GET operations",
labelnames=["result", "backend_class", "tag"],
)

def create_metrics_middleware(latency_metric: Optional[Histogram] = None, with_tag: bool = False) -> Middleware:
_DEFAULT_METRIC = Histogram(
"cashews_operations_latency_seconds",
"Latency of different operations with a cache",
labelnames=["operation", "backend_class"] if not with_tag else ["operation", "backend_class", "tag"],
)
_latency_metric = latency_metric or _DEFAULT_METRIC

def create_metrics_middleware(with_tag: bool = False) -> Middleware:

async def metrics_middleware(call, cmd: Command, backend: Backend, *args, **kwargs):
with _latency_metric.time() as metric:
metric.labels(operation=cmd.value, backend_class=backend.__class__.__name__)
with _DEFAULT_METRIC.time() as metric:
tag = ""

if with_tag and "key" in kwargs:
tags = cache.get_key_tags(kwargs["key"])
tag = next((t for t in tags), None)
if tag:
metric.labels(tag=tag)
return await call(*args, **kwargs)
tag = next((t for t in tags), "")
metric.labels(operation=cmd.value, backend_class=backend.__class__.__name__, tag=tag)
result = await call(*args, **kwargs)
if cmd is Command.GET:
if result is not kwargs["default"]:
op_result = "hit"
else:
op_result = "miss"
_HIT_MISS.labels(result=op_result, backend_class=backend.__class__.__name__, tag=tag).inc()
return result

return metrics_middleware
2 changes: 1 addition & 1 deletion cashews/wrapper/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def _check_setup(self) -> None:
def _add_backend(self, backend: Backend, middlewares=(), prefix: str = default_prefix) -> None:
self._backends[prefix] = (
backend,
tuple(self._default_middlewares) + middlewares,
middlewares + tuple(self._default_middlewares),
)

async def init(self, *args, **kwargs) -> None:
Expand Down

0 comments on commit 86dc8d9

Please sign in to comment.