Files
HexaWetter/api/app/services/health.py

84 lines
2.5 KiB
Python

from __future__ import annotations
import asyncio
import time
from typing import Any
from app.cache import cache_get, cache_set, redis_available
from app.config import (
BRIGHTSKY_BASE_URL,
CACHE_TTL_HEALTH_SOURCES,
DATABASE_URL,
DWD_RADAR_BASE_URL,
DWD_WMS_URL,
DWD_WARNINGS_URL,
OPEN_METEO_BASE_URL,
)
from app.database import pool_available
from app.http_client import get_client
async def _probe(name: str, url: str, timeout: float = 5.0) -> dict[str, Any]:
started = time.perf_counter()
try:
client = get_client()
response = await client.get(url, timeout=timeout)
elapsed_ms = round((time.perf_counter() - started) * 1000, 1)
ok = response.status_code < 500
return {
"name": name,
"url": url,
"status": "ok" if ok else "degraded",
"http_status": response.status_code,
"latency_ms": elapsed_ms,
}
except Exception as exc:
elapsed_ms = round((time.perf_counter() - started) * 1000, 1)
return {
"name": name,
"url": url,
"status": "error",
"error": str(exc),
"latency_ms": elapsed_ms,
}
async def check_sources() -> list[dict[str, Any]]:
cache_key = "health:sources"
cached = await cache_get(cache_key)
if cached:
return cached
probes = await asyncio.gather(
_probe("open_meteo", f"{OPEN_METEO_BASE_URL}/forecast?latitude=52.5&longitude=13.4&current=temperature_2m"),
_probe("brightsky", f"{BRIGHTSKY_BASE_URL}/current_weather?lat=52.5&lon=13.4"),
_probe("dwd_radar", f"{DWD_RADAR_BASE_URL}/rv/", timeout=4.0),
_probe(
"dwd_wms",
(
f"{DWD_WMS_URL}?service=WMS&version=1.1.1&request=GetMap"
"&layers=dwd:Niederschlagsradar&format=image/png&transparent=true"
"&width=64&height=64&srs=EPSG:4326&bbox=8,50,9,51"
),
timeout=5.0,
),
_probe("dwd_warnings", DWD_WARNINGS_URL, timeout=4.0),
)
results = list(probes)
results.append(
{
"name": "postgres",
"url": DATABASE_URL.split("@")[-1],
"status": "ok" if pool_available() else "disabled",
}
)
results.append(
{
"name": "redis",
"url": "redis",
"status": "ok" if redis_available() else "disabled",
}
)
await cache_set(cache_key, results, CACHE_TTL_HEALTH_SOURCES)
return results