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

1"""Prometheus telemetry. Each app gets its own registry, so tests never share counters.""" 

2 

3from __future__ import annotations 

4 

5from prometheus_client import CollectorRegistry, Counter, Histogram 

6 

7 

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 )