Some checks failed
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Backend Lint (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
Deploy / Build & Push Images (push) Has been cancelled
Deploy / Deploy to Server (push) Has been cancelled
Deploy / Notify (push) Has been cancelled
66 lines
1.8 KiB
Python
66 lines
1.8 KiB
Python
"""
|
|
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)
|
|
|