feat: детали проверки в тултипе сегментов uptime
Build and deploy / build-deploy (push) Has been cancelled

Сегмент при наведении показывает тултип: успех/провал, время
проверки, латентность и текст ошибки.

Бэкенд: в таблицу checks добавлена колонка error (миграция через
ALTER TABLE), probe.py и ручной /api/check теперь сохраняют текст
ошибки, /api/models отдаёт детали каждой проверки в history.
This commit is contained in:
2026-10-21 22:24:17 +00:00
parent 3f6b5768d0
commit 1fb770fc52
3 changed files with 122 additions and 19 deletions
+25 -6
View File
@@ -106,6 +106,12 @@ def init_db():
CREATE INDEX IF NOT EXISTS idx_at_norm ON arena_text_leaderboard(norm_name);
CREATE INDEX IF NOT EXISTS idx_ag_norm ON arena_agent_leaderboard(norm_name);
""")
# Миграция: текст ошибки нужен для деталей в тултипах сегментов.
cols = [r[1] for r in db.execute("PRAGMA table_info(checks)").fetchall()]
if "error" not in cols:
db.execute("ALTER TABLE checks ADD COLUMN error TEXT")
db.commit()
db.close()
@@ -354,7 +360,8 @@ def model_stats(db: sqlite3.Connection, model_id: str, hours: int = 24) -> dict:
).fetchone()
rows = db.execute(
"SELECT ok FROM checks WHERE model_id=? AND checked_at > ? ORDER BY checked_at ASC",
"SELECT ok, latency_ms, checked_at, error FROM checks "
"WHERE model_id=? AND checked_at > ? ORDER BY checked_at ASC",
(model_id, cutoff)
).fetchall()
@@ -363,7 +370,16 @@ def model_stats(db: sqlite3.Connection, model_id: str, hours: int = 24) -> dict:
pct = round(100 * success / total) if total else None
# История последних проверок (старые → новые) для сегментной витрины.
history = [bool(r["ok"]) for r in rows][-HISTORY_LIMIT:]
# Каждый элемент — детали проверки: ok, latency, время, текст ошибки.
history = [
{
"ok": bool(r["ok"]),
"latency_ms": r["latency_ms"],
"at": r["checked_at"],
"error": r["error"],
}
for r in rows[-HISTORY_LIMIT:]
]
return {
"last_ok": bool(last["ok"]) if last else None,
@@ -476,6 +492,7 @@ def api_check(model_id: str):
t0 = _t.time()
ok = False
latency = None
error = None
try:
body = json.dumps({
"model": model_id,
@@ -494,15 +511,17 @@ def api_check(model_id: str):
resp = json.loads(r.read())
content = resp["choices"][0]["message"]["content"]
ok = bool(content.strip())
latency = int((_t.time() - t0) * 1000)
except Exception as e:
print(f"[check] {model_id}: {e}")
error = f"{type(e).__name__}: {e}"
print(f"[check] {model_id}: {error}")
latency = int((_t.time() - t0) * 1000)
now = datetime.now(timezone.utc).isoformat()
db = get_db()
db.execute(
"INSERT INTO checks (model_id, checked_at, ok, latency_ms) VALUES (?,?,?,?)",
(model_id, now, int(ok), latency),
"INSERT INTO checks (model_id, checked_at, ok, latency_ms, error) VALUES (?,?,?,?,?)",
(model_id, now, int(ok), latency, error),
)
db.commit()
stats = model_stats(db, model_id)