chore(observability): externalize stack from root compose files
Manage now connects to existing Grafana/Prometheus/Alertmanager instances and never deploys its own stack. - docker-compose.yml / docker-compose.dev.yml: removed prometheus, loki, alloy, grafana, alertmanager, node-exporter services, the monitoring network, and observability named volumes; they now ship only backend + frontend. Dev frontend now joins the web network so the Vite dev proxy can reach the backend. - backend: alertmanager_url default is now empty; /api/monitoring/alerts and /alertmanager-status return graceful "not configured" responses when ALERTMANAGER_URL is unset. Added not-configured tests. - docker-compose.observability.yml: kept as the optional standalone example; header clarifies Manage does not deploy it. - Removed orphaned combined monitoring/prometheus/prometheus.yml (standalone stack uses prometheus.standalone.yml). - Docs (README, REQUIREMENTS decision log, monitoring-logging-design, observability-runbooks, context.md, MIGRATION_PLAN, frontend/README, CHANGELOG) updated to the connect-to-existing model. VITE_GRAFANA_URL / VITE_PROMETHEUS_URL remain as optional frontend deep-link overrides. .env.example still needs a manual update (safety policy blocks assistant edits): set ALERTMANAGER_URL empty/optional and move standalone-only vars out of the root file.
This commit is contained in:
@@ -55,7 +55,7 @@ class Settings(BaseSettings):
|
||||
# Observability
|
||||
prometheus_enabled: bool = True
|
||||
prometheus_file_sd_dir: str = "/app/backend/.cache/prometheus-file-sd"
|
||||
alertmanager_url: str = "http://alertmanager:9093"
|
||||
alertmanager_url: str = ""
|
||||
alertmanager_webhook_url: str = "" # Optional receiver for alertmanager webhook notifications
|
||||
|
||||
# Remote paths
|
||||
|
||||
@@ -88,11 +88,13 @@ def get_alertmanager_alerts() -> dict[str, Any]:
|
||||
"""Return a summary of active Alertmanager alerts for the UI.
|
||||
|
||||
Proxies the Alertmanager `/api/v1/alerts` endpoint and reshapes the payload
|
||||
into a stable, UI-friendly format. If Alertmanager is unreachable, the
|
||||
endpoint returns an empty summary and logs the failure so the UI can still
|
||||
render a health card instead of an error page.
|
||||
into a stable, UI-friendly format. If Alertmanager is unreachable (or not
|
||||
configured via ``ALERTMANAGER_URL``), the endpoint returns an empty summary
|
||||
so the UI can still render a health card instead of an error page.
|
||||
"""
|
||||
session, base_url = _alertmanager_client()
|
||||
if not base_url:
|
||||
return {"total": 0, "by_severity": {}, "alerts": [], "error": "alertmanager_not_configured"}
|
||||
try:
|
||||
response = session.get(f"{base_url}/api/v1/alerts", timeout=5)
|
||||
response.raise_for_status()
|
||||
@@ -115,9 +117,12 @@ def get_alertmanager_status() -> dict[str, Any]:
|
||||
|
||||
Uses the Alertmanager `/api/v2/status` endpoint and exposes only the high-
|
||||
level fields the UI needs: uptime, version, and whether the cluster is
|
||||
healthy.
|
||||
healthy. Returns ``up=False`` when Alertmanager is unreachable or not
|
||||
configured via ``ALERTMANAGER_URL``.
|
||||
"""
|
||||
session, base_url = _alertmanager_client()
|
||||
if not base_url:
|
||||
return {"up": False, "version": "", "uptime": ""}
|
||||
try:
|
||||
response = session.get(f"{base_url}/api/v2/status", timeout=5)
|
||||
response.raise_for_status()
|
||||
|
||||
Reference in New Issue
Block a user