"""运行指标收集(线程安全,零依赖)。""" from __future__ import annotations import threading from collections import Counter, deque from typing import Any, Deque, Dict class Stats: def __init__(self, window: int = 1000): self._lock = threading.Lock() self.requests = 0 self.domain_counter: Counter = Counter() self.difficulty_counter: Counter = Counter() self.upgraded = 0 self.cache_hits = 0 self.cache_levels: Counter = Counter() self.errors = 0 self.latencies: Deque[float] = deque(maxlen=window) self.cost_total = 0.0 self.model_usage: Counter = Counter() def record(self, latency_ms: float, domain: str, difficulty: str, upgraded: bool, cache_hit: bool, cache_level: str | None, cost_est: float, model_used: str): with self._lock: self.requests += 1 self.domain_counter[domain] += 1 self.difficulty_counter[difficulty] += 1 if upgraded: self.upgraded += 1 if cache_hit: self.cache_hits += 1 if cache_level: self.cache_levels[cache_level] += 1 self.latencies.append(latency_ms) self.cost_total += cost_est self.model_usage[model_used] += 1 def record_error(self): with self._lock: self.errors += 1 def summary(self) -> Dict[str, Any]: with self._lock: n = self.requests lat = list(self.latencies) avg_lat = sum(lat) / len(lat) if lat else 0.0 p99 = sorted(lat)[int(len(lat) * 0.99) - 1] if len(lat) >= 100 else (max(lat) if lat else 0.0) return { "total_requests": n, "domain_distribution": dict(self.domain_counter), "difficulty_distribution": dict(self.difficulty_counter), "fallback_rate": round(self.upgraded / n, 4) if n else 0.0, "upgraded_requests": self.upgraded, "cache_hit_rate": round(self.cache_hits / n, 4) if n else 0.0, "cache_levels": dict(self.cache_levels), "avg_latency_ms": round(avg_lat, 3), "p99_latency_ms": round(p99, 3), "total_cost_est_usd": round(self.cost_total, 6), "model_usage": dict(self.model_usage), "errors": self.errors, }