57 lines
1.8 KiB
Python
Raw Normal View History

2026-07-23 01:15:04 +02:00
# retoor <retoor@molodetz.nl>
from __future__ import annotations
import asyncio
import time
from fastapi import APIRouter
from devplacepy_services.base.config import service_url
from devplacepy_services.base.http import internal_request
from devplacepy_services.base.schemas import HealthOut, HealthStatsOut
from devplacepy_services.base.service import BaseMicroservice
from devplacepy_services.base.stats import COUNTERS
async def _dep_status(name: str) -> str:
url = f"{service_url(name)}/health"
try:
response = await internal_request("GET", url, timeout=2.0)
if response.status_code == 200:
payload = response.json()
if payload.get("status") == "ok":
return "ok"
return "degraded"
return "down"
except Exception:
return "down"
def health_router(service: BaseMicroservice) -> APIRouter:
router = APIRouter()
@router.get("/health", response_model=HealthOut)
async def health() -> HealthOut:
deps: dict[str, str] = {}
if service.depends_on:
results = await asyncio.gather(
*[_dep_status(dep) for dep in service.depends_on]
)
for dep_name, status in zip(service.depends_on, results, strict=True):
deps[dep_name] = status
overall = "ok"
if deps and any(status != "ok" for status in deps.values()):
overall = "degraded"
uptime_s = int(time.monotonic() - service.started_at)
stats = COUNTERS.snapshot()
return HealthOut(
service=service.name,
status=overall,
uptime_s=uptime_s,
version=service.version,
deps=deps,
stats=HealthStatsOut(requests=stats["requests"], errors=stats["errors"]),
)
return router