feat(observability): service discovery, health cards, alertmanager widget
Slice 3 of observability-service-registry (frontend). The Observability
page discovers Grafana from the service registry instead of env vars,
adds Grafana + Prometheus health cards, and ships an alertmanager
active_alerts dashboard widget.
- types: added GrafanaStatus + PrometheusStatus; added optional
service_id/error to AlertmanagerStatus.
- api/client.ts + hooks/useObservability.ts: fetchGrafanaStatus,
fetchPrometheusStatus, useGrafanaStatus, usePrometheusStatus.
- widgets/AlertmanagerAlertsWidget.tsx (new): presentational widget
consuming the active_alerts summary shape (total/by_severity/alerts);
exported from widgets/index.ts.
- integrations/registry.ts: alertmanager binding (active_alerts kind,
30s refresh, optional severity_filter); registry.test.ts updated to
6 service types incl alertmanager + a resolve test.
- components/ObservabilityPage.tsx: removed
import.meta.env.VITE_GRAFANA_URL; derive GRAFANA_BASE_URL from the
first enabled grafana service via useServiceInstances("grafana");
added Grafana + Prometheus HealthCards (up/not-configured/unreachable)
with QueryError retry blocks; machine dashboard shows a "No Grafana
service configured" empty-state linking to /services when none is set.
npm run build (tsc -b + vite) clean; 0 lint errors; 72 frontend tests
pass. Reviewed fresh-context (read-only): no blockers.
This commit is contained in:
@@ -56,9 +56,7 @@ def _auth_headers(service: ServiceRecord) -> dict[str, str]:
|
||||
return {"Authorization": f"Bearer {api_key}"} if api_key else {}
|
||||
|
||||
|
||||
def _status_response(
|
||||
service: ServiceRecord | None, *, version: str = "", error: str | None = None
|
||||
) -> dict[str, Any]:
|
||||
def _status_response(service: ServiceRecord | None, *, version: str = "", error: str | None = None) -> dict[str, Any]:
|
||||
return {
|
||||
"up": error is None,
|
||||
"version": version or "",
|
||||
@@ -232,9 +230,7 @@ def get_prometheus_status(
|
||||
try:
|
||||
health = requests.get(f"{base}/-/healthy", headers=headers, timeout=timeout)
|
||||
health.raise_for_status()
|
||||
build_info = requests.get(
|
||||
f"{base}/api/v1/status/buildinfo", headers=headers, timeout=timeout
|
||||
)
|
||||
build_info = requests.get(f"{base}/api/v1/status/buildinfo", headers=headers, timeout=timeout)
|
||||
build_info.raise_for_status()
|
||||
version = build_info.json().get("data", {}).get("version", "")
|
||||
except Exception:
|
||||
|
||||
Reference in New Issue
Block a user