From 5b87285cc59ccea450938332b8ec8f1daa5c3cb5 Mon Sep 17 00:00:00 2001 From: Bast Date: Mon, 2 Nov 2026 11:52:07 -0600 Subject: [PATCH] =?UTF-8?q?debug:=20erforce=20globale=20fehler-diagnose=20?= =?UTF-8?q?f=C3=BCr=20consul-weiche?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- monitor/views.py | 56 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/monitor/views.py b/monitor/views.py index 49a8ffe..19a3a88 100644 --- a/monitor/views.py +++ b/monitor/views.py @@ -1,34 +1,46 @@ import json import base64 import requests -import logging +import traceback from django.http import JsonResponse from django.views.generic import TemplateView, View -logger = logging.getLogger(__name__) - class DashboardView(TemplateView): template_name = "monitor/dashboard.html" class ClusterGraphDataView(View): + """ + Die Diagnose-Schnittstelle: Fängt jeden Fehler global ab + und liefert den echten Python-Fehler als Text zurück! + """ def get(self, request, *args, **kwargs): - repo_name = request.GET.get("repo", "boday_tf") - consul_url = f"http://consul:8500/v1/kv/terraform/states/{repo_name}" - - # ABSOLUTER SICHERHEITSGURT: Fängt jeden Parsing-Fehler ab, damit das Dashboard NIEMALS mit 500 abstürzt + # Wir umschließen die ABSOLUT GESAMTE Funktion mit einem globalen Sicherheitsnetz try: + repo_name = request.GET.get("repo", "boday_tf") + consul_url = f"http://consul:8500/v1/kv/terraform/states/{repo_name}" + response = requests.get(consul_url, timeout=5) if response.status_code == 404: - return JsonResponse({"name": f"Warte auf korrekten Consul-Key '{repo_name}'...", "type": "Root", "children": []}) + return JsonResponse({ + "name": f"Warte auf Consul-Key '{repo_name}'...", + "type": "Root", + "children": [] + }) - consul_json = response.json() - if isinstance(consul_json, list) and len(consul_json) > 0: - raw_value = consul_json[0].get("Value") + consul_data = response.json() + + # WICHTIG: Consul liefert im KV-Store IMMER eine Liste zurück! [ {"LockIndex": 0, "Key": "...", "Value": "..."} ] + if isinstance(consul_data, list) and len(consul_data) > 0: + raw_value = consul_data[0].get("Value") else: - raw_value = consul_json.get("Value") + raw_value = consul_data.get("Value") if hasattr(consul_data, "get") else None if not raw_value: - return JsonResponse({"name": f"Key '{repo_name}' leer.", "type": "Root", "children": []}) + return JsonResponse({ + "name": f"Key '{repo_name}' geladen, aber Value ist leer.", + "type": "Root", + "children": [] + }) # Base64 decodieren state_json = json.loads(base64.b64decode(raw_value).decode('utf-8')) @@ -42,9 +54,16 @@ class ClusterGraphDataView(View): for res in resources: res_type = res.get("type") res_name = res.get("name") + + # Attribut-Struktur sicher auflösen instances = res.get("instances", []) - if not instances or not isinstance(instances, list): continue - attributes = instances[0].get("attributes", {}) + if isinstance(instances, list) and len(instances) > 0: + attributes = instances[0].get("attributes", {}) + else: + attributes = res.get("values", {}) + + if not attributes: + continue metadata = attributes.get("metadata", [{}]) actual_name = metadata[0].get("name", res_name) if isinstance(metadata, list) else metadata.get("name", res_name) @@ -85,10 +104,11 @@ class ClusterGraphDataView(View): return JsonResponse(root_node) except Exception as e: - logger.error(f"Sicherheits-Fallback gegriffen: {str(e)}") - # Liefert im Fehlerfall ein valides leeres Baumdiagramm (HTTP 200 OK statt 500!) + # DIE RETTUNG: Falls IRGENDWAS crasht, fangen wir es ab und senden den Fehler als HTTP 200 Text! + error_msg = f"Fehler: {str(e)} -> Traceback: {traceback.format_exc()}" return JsonResponse({ - "name": f"Boday-IT Monitor // Synchronisiere '{repo_name}'...", + "name": "cloudmon // Diagnose-Modus", "type": "Root", + "error_details": error_msg, "children": [] })