""" Ops/health metrics exported as Prometheus metrics (4B Ops). These are low-frequency filesystem-based metrics (safe on scrape). """ from __future__ import annotations from datetime import datetime from pathlib import Path from app.config import get_settings settings = get_settings() try: from prometheus_client import Gauge except Exception: # pragma: no cover Gauge = None # type: ignore if Gauge is not None: db_backups_enabled = Gauge("pounce_db_backups_enabled", "DB backups enabled (1/0)") db_backup_latest_unixtime = Gauge("pounce_db_backup_latest_unixtime", "Unix time of latest backup file (0 if none)") db_backup_latest_age_seconds = Gauge("pounce_db_backup_latest_age_seconds", "Age of latest backup file (seconds)") else: # pragma: no cover db_backups_enabled = None # type: ignore db_backup_latest_unixtime = None # type: ignore db_backup_latest_age_seconds = None # type: ignore def _backup_root() -> Path: root = Path(settings.backup_dir) if not root.is_absolute(): root = (Path.cwd() / root).resolve() return root async def update_prometheus_ops_metrics() -> None: if Gauge is None: return db_backups_enabled.set(1 if settings.enable_db_backups else 0) root = _backup_root() if not root.exists() or not root.is_dir(): db_backup_latest_unixtime.set(0) db_backup_latest_age_seconds.set(0) return files = [p for p in root.glob("*") if p.is_file()] if not files: db_backup_latest_unixtime.set(0) db_backup_latest_age_seconds.set(0) return latest = max(files, key=lambda p: p.stat().st_mtime) mtime = float(latest.stat().st_mtime) now = datetime.utcnow().timestamp() age = max(0.0, now - mtime) db_backup_latest_unixtime.set(mtime) db_backup_latest_age_seconds.set(age)