feat: implement collection runs tracking and error acknowledgment features
This commit is contained in:
1 parent
c39364eda4
commit
34903492f6
14 files changed
+484
-21
No files matched your search
+59
-1
@@ -10,7 +10,7 @@ from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sqlite3
|
||||
from datetime import date
|
||||
from datetime import date, datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
DEFAULT_DB_PATH = "cost_dashboard.db"
|
||||
@@ -656,3 +656,61 @@ def resource_detail(conn: sqlite3.Connection, provider: str, name: str, service_
|
||||
"period_end": period_end,
|
||||
"resources": resources,
|
||||
}
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Exécutions de collecte (page "Collecte")
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def list_collection_runs(conn: sqlite3.Connection, limit: int = 50) -> list[dict]:
|
||||
rows = conn.execute(
|
||||
"""
|
||||
SELECT id, run_type, started_at, finished_at, tenants_ok, tenants_error, acknowledged_at
|
||||
FROM collection_runs
|
||||
ORDER BY started_at DESC
|
||||
LIMIT ?
|
||||
""",
|
||||
(limit,),
|
||||
).fetchall()
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
|
||||
def collection_run_errors(conn: sqlite3.Connection, run_id: int) -> list[dict]:
|
||||
"""Détail des relevés en erreur d'une exécution — relu depuis
|
||||
`collections` sur la fenêtre [started_at, finished_at] du run, plutôt que
|
||||
dupliqué dans collection_runs."""
|
||||
run = conn.execute(
|
||||
"SELECT started_at, finished_at FROM collection_runs WHERE id = ?", (run_id,)
|
||||
).fetchone()
|
||||
if run is None:
|
||||
return []
|
||||
|
||||
rows = conn.execute(
|
||||
"""
|
||||
SELECT provider, tenant_name, granularity, period_start, error_message, collected_at
|
||||
FROM collections
|
||||
WHERE status = 'error' AND collected_at BETWEEN ? AND ?
|
||||
ORDER BY collected_at
|
||||
""",
|
||||
(run["started_at"], run["finished_at"] or run["started_at"]),
|
||||
).fetchall()
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
|
||||
def has_unacknowledged_errors(conn: sqlite3.Connection) -> bool:
|
||||
row = conn.execute(
|
||||
"SELECT 1 FROM collection_runs WHERE tenants_error > 0 AND acknowledged_at IS NULL LIMIT 1"
|
||||
).fetchone()
|
||||
return row is not None
|
||||
|
||||
|
||||
def acknowledge_collection_run(conn: sqlite3.Connection, run_id: int) -> bool:
|
||||
"""Seule écriture de ce module (le reste est lecture seule) : marque une
|
||||
exécution en erreur comme acquittée manuellement depuis le dashboard.
|
||||
Retourne False si l'exécution n'existe pas ou était déjà acquittée."""
|
||||
cur = conn.execute(
|
||||
"UPDATE collection_runs SET acknowledged_at = ? WHERE id = ? AND acknowledged_at IS NULL",
|
||||
(datetime.now(timezone.utc).isoformat(), run_id),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
Reference in new issue
Block a user