Files
p5g-marvis/app/services/prometheus.py
2026-04-24 12:33:52 -04:00

47 lines
1.6 KiB
Python

"""Prometheus client — queries the HPE P5G Prometheus instance."""
import httpx
from app.config import PROMETHEUS_URL, PROMETHEUS_PREFIX, TARGET_TYPE_MAP, ALL_NFS
_BASE = PROMETHEUS_URL.rstrip("/") + PROMETHEUS_PREFIX
async def query(promql: str) -> list:
"""Run an instant PromQL query, return the result list."""
async with httpx.AsyncClient(timeout=5) as client:
r = await client.get(f"{_BASE}/api/v1/query", params={"query": promql})
r.raise_for_status()
return r.json()["data"]["result"]
async def get_nf_status_map() -> dict[str, dict]:
"""Return Prometheus-backed NF status keyed by display name."""
try:
results = await query("up")
except Exception:
return {n: {"name": n, "state": "unknown", "instance": ""} for n in ALL_NFS}
seen: dict[str, dict] = {}
for r in results:
metric = r["metric"]
target = metric.get("target_type", metric.get("job", "")).lower()
name = TARGET_TYPE_MAP.get(target)
if not name:
continue
state = "up" if r["value"][1] == "1" else "down"
# Keep worst state if multiple instances
if name not in seen or seen[name]["state"] != "down":
seen[name] = {"name": name, "state": state, "instance": metric.get("instance", "")}
# Fill in NFs with no Prometheus data
for n in ALL_NFS:
if n not in seen:
seen[n] = {"name": n, "state": "unknown", "instance": ""}
return seen
async def get_nf_status() -> list:
"""Return a list of {name, state, instance} for every known NF."""
return list((await get_nf_status_map()).values())