Coverage for src/case_router/metrics.py: 100%
10 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-12 18:59 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-12 18:59 +0000
1"""Prometheus telemetry. Each app gets its own registry, so tests never share counters."""
3from __future__ import annotations
5from prometheus_client import CollectorRegistry, Counter, Histogram
8class Metrics:
9 def __init__(self, registry: CollectorRegistry | None = None) -> None:
10 self.registry = registry or CollectorRegistry()
11 self.cases_routed = Counter(
12 "case_router_cases_routed",
13 "Cases routed, by tenant, queue, and the rule that matched",
14 ["tenant", "queue", "rule"],
15 registry=self.registry,
16 )
17 self.cases_closed = Counter(
18 "case_router_cases_closed",
19 "Cases closed, by tenant and queue, split by whether the deadline was met",
20 ["tenant", "queue", "on_time"],
21 registry=self.registry,
22 )
23 self.requests_rejected = Counter(
24 "case_router_requests_rejected",
25 "Requests turned away before reaching a handler, by tenant and reason",
26 ["tenant", "reason"],
27 registry=self.registry,
28 )
29 self.routing_seconds = Histogram(
30 "case_router_routing_seconds",
31 "Time to load a tenant's rules and pick a queue",
32 ["tenant"],
33 buckets=(0.0005, 0.001, 0.0025, 0.005, 0.01, 0.025, 0.05, 0.1),
34 registry=self.registry,
35 )
36 self.request_seconds = Histogram(
37 "case_router_http_request_seconds",
38 "HTTP request latency by method, route template, and status code",
39 ["method", "route", "status"],
40 registry=self.registry,
41 )