#!/usr/bin/env python3 """ LandveX API Monitor — enkel healthcheck och loggning """ import requests import json import time from datetime import datetime BASE_URLS = { "api": "http://localhost:8081", # Docker: landvex-api (mappad 8081→8080) "bounties": "http://localhost:8084", # Ej startad — FastAPI på port 8084 när den körs "claims": "http://localhost:8085", # Ej startad — FastAPI på port 8085 när den körs "demo": "http://localhost:8086", # demo.html — statisk fil, ingen tjänst } # Vilka tjänster som faktiskt förväntas köra just nu EXPECTED_SERVICES = {"api"} def check_health(name, url): """Kolla hälsan på en tjänst.""" try: if name in ["bounties", "claims"]: # POST to create a test resource res = requests.post(url, json={"title": "monitor-test", "description": "test"} if name == "bounties" else {"model_id": "LVX-TEST", "manufacturer_name": "Test", "contact_email": "test@test.com"}, timeout=5) else: res = requests.get(url, timeout=5) if res.status_code in [200, 201]: return {"status": "ok", "response_time_ms": res.elapsed.total_seconds() * 1000} else: return {"status": "error", "code": res.status_code} except Exception as e: return {"status": "down", "error": str(e)} def monitor(): """Kör healthcheck på alla tjänster.""" timestamp = datetime.utcnow().isoformat() + "Z" results = { "timestamp": timestamp, "services": {}, } # Kolla varje tjänst for name, base_url in BASE_URLS.items(): if name == "api": health_url = f"{base_url}/health" # API har /health endpoint elif name == "demo": health_url = base_url else: health_url = f"{base_url}/v0/{name}" # Bounties/claims har ingen health, kolla om de svarar results["services"][name] = check_health(name, health_url) # Kolla mätetal try: res = requests.get(f"{BASE_URLS['api']}/v0/metrics", timeout=5) if res.status_code == 200: results["metrics"] = res.json() except Exception as e: results["metrics_error"] = str(e) # Spara till loggfil with open("/tmp/landvex-monitor.jsonl", "a") as f: f.write(json.dumps(results) + "\n") # Skriv ut sammanfattning print(f"\n[{timestamp}] LandveX Monitor") print("-" * 50) for name, status in results["services"].items(): if status["status"] == "ok": icon = "🟢" elif name not in EXPECTED_SERVICES: icon = "⚪" # Grå för tjänster som inte förväntas köra än else: icon = "🔴" rt = status.get("response_time_ms", 0) note = " (ej förväntad)" if name not in EXPECTED_SERVICES and status["status"] != "ok" else "" print(f"{icon} {name:12} {status['status']:8} {rt:6.1f}ms{note}") if "metrics" in results: m = results["metrics"]["objects"] print(f"\n📊 {m['total']} objekt ({m['klasser']} klasser, {m['modeller']} modeller)") elif "metrics_error" in results: print(f"\n⚠️ Metrics ej tillgängliga: {results['metrics_error']}") return results if __name__ == "__main__": monitor()