Update src/services/metrics_service.py
Browse files
src/services/metrics_service.py
CHANGED
|
@@ -33,6 +33,8 @@ _DEFAULT_STATE: Dict[str, Any] = {
|
|
| 33 |
"last_updated": 0.0,
|
| 34 |
}
|
| 35 |
|
|
|
|
|
|
|
| 36 |
|
| 37 |
class MetricsService:
|
| 38 |
def __init__(self, path: Path):
|
|
@@ -45,12 +47,47 @@ class MetricsService:
|
|
| 45 |
self._buckets: Dict[str, Dict[str, int]] = {}
|
| 46 |
self._dirty = False
|
| 47 |
|
|
|
|
|
|
|
|
|
|
| 48 |
# Seed disk file if it doesn't exist
|
| 49 |
if not self.path.exists():
|
| 50 |
self._write_to_disk(dict(_DEFAULT_STATE))
|
| 51 |
|
| 52 |
# ββ Public API (sync, no I/O) ββββββββββββββββββββββββββββββββββββββββββββββ
|
| 53 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
def incr(self, key: str, amount: int = 1) -> None:
|
| 55 |
"""Increment a top-level counter in memory."""
|
| 56 |
self._counters[key] = self._counters.get(key, 0) + amount
|
|
|
|
| 33 |
"last_updated": 0.0,
|
| 34 |
}
|
| 35 |
|
| 36 |
+
_MAX_QUERY_LOG = 200 # keep last 200 queries in memory
|
| 37 |
+
|
| 38 |
|
| 39 |
class MetricsService:
|
| 40 |
def __init__(self, path: Path):
|
|
|
|
| 47 |
self._buckets: Dict[str, Dict[str, int]] = {}
|
| 48 |
self._dirty = False
|
| 49 |
|
| 50 |
+
# In-memory query log (last N queries, never flushed to disk)
|
| 51 |
+
self._query_log: list = []
|
| 52 |
+
|
| 53 |
# Seed disk file if it doesn't exist
|
| 54 |
if not self.path.exists():
|
| 55 |
self._write_to_disk(dict(_DEFAULT_STATE))
|
| 56 |
|
| 57 |
# ββ Public API (sync, no I/O) ββββββββββββββββββββββββββββββββββββββββββββββ
|
| 58 |
|
| 59 |
+
def log_query(
|
| 60 |
+
self,
|
| 61 |
+
question: str,
|
| 62 |
+
intent: str = "",
|
| 63 |
+
tool: str = "",
|
| 64 |
+
model: str = "",
|
| 65 |
+
response_time: float = 0.0,
|
| 66 |
+
result_count: int = 0,
|
| 67 |
+
error: str = "",
|
| 68 |
+
) -> None:
|
| 69 |
+
"""Append a query record to the in-memory log (capped at _MAX_QUERY_LOG)."""
|
| 70 |
+
import datetime
|
| 71 |
+
record = {
|
| 72 |
+
"timestamp": datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"),
|
| 73 |
+
"question": (question or "")[:120],
|
| 74 |
+
"intent": intent or "",
|
| 75 |
+
"tool": tool or "",
|
| 76 |
+
"model": model or "",
|
| 77 |
+
"response_time": round(response_time, 2),
|
| 78 |
+
"result_count": result_count,
|
| 79 |
+
"error": (error or "")[:80],
|
| 80 |
+
}
|
| 81 |
+
self._query_log.append(record)
|
| 82 |
+
if len(self._query_log) > _MAX_QUERY_LOG:
|
| 83 |
+
self._query_log = self._query_log[-_MAX_QUERY_LOG:]
|
| 84 |
+
|
| 85 |
+
def recent_queries(self, limit: int = 50) -> list:
|
| 86 |
+
"""Return the most recent `limit` query records, newest first."""
|
| 87 |
+
return list(reversed(self._query_log[-limit:]))
|
| 88 |
+
|
| 89 |
+
# ββ Public API (sync, no I/O) ββββββββββββββββββββββββββββββββββββββββββββββ
|
| 90 |
+
|
| 91 |
def incr(self, key: str, amount: int = 1) -> None:
|
| 92 |
"""Increment a top-level counter in memory."""
|
| 93 |
self._counters[key] = self._counters.get(key, 0) + amount
|