landvex: Fixar och tester klara för alla komponenter
- Datafabrik: Dockerfile fix, agentorkestrering fungerar - Vision: Identify-modell, FAISS, OCR alla testade - API: Alla 7 integrationstester passerade - Upplösare: Entitetsupplösning verifierad
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
LIFE Runtime Monitor
|
||||
Samlar operativa mätvärden under burn-in
|
||||
"""
|
||||
import sqlite3
|
||||
import json
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
from pathlib import Path
|
||||
|
||||
DB_PATH = "/home/bernt/.openclaw/workspace/rivp-pilot-1/rivp.db"
|
||||
LOG_DIR = Path("/home/bernt/.openclaw/workspace/life-weather/logs")
|
||||
METRICS_FILE = Path("/home/bernt/.openclaw/workspace/life-weather/metrics.json")
|
||||
|
||||
def collect_metrics():
|
||||
"""Samla mätvärden från databasen"""
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
c = conn.cursor()
|
||||
|
||||
metrics = {
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"pipeline": {},
|
||||
"observations": {},
|
||||
"system": {}
|
||||
}
|
||||
|
||||
# Pipeline-mätvärden
|
||||
c.execute("SELECT COUNT(*) FROM weather_observations")
|
||||
total_obs = c.fetchone()[0]
|
||||
|
||||
c.execute("""
|
||||
SELECT COUNT(*) FROM weather_observations
|
||||
WHERE created_at > datetime('now', '-1 hour')
|
||||
""")
|
||||
obs_last_hour = c.fetchone()[0]
|
||||
|
||||
# Dubbletter
|
||||
c.execute("""
|
||||
SELECT road_id, observation_type, timestamp, COUNT(*) as cnt
|
||||
FROM weather_observations
|
||||
GROUP BY road_id, observation_type, timestamp
|
||||
HAVING cnt > 1
|
||||
""")
|
||||
duplicates = len(c.fetchall())
|
||||
|
||||
# Reality Latency
|
||||
c.execute("""
|
||||
SELECT MAX(created_at) FROM weather_observations
|
||||
""")
|
||||
last_obs = c.fetchone()[0]
|
||||
if last_obs:
|
||||
last_time = datetime.fromisoformat(last_obs)
|
||||
latency_minutes = (datetime.now() - last_time).total_seconds() / 60
|
||||
else:
|
||||
latency_minutes = None
|
||||
|
||||
metrics["observations"] = {
|
||||
"total": total_obs,
|
||||
"last_hour": obs_last_hour,
|
||||
"duplicates": duplicates,
|
||||
"reality_latency_minutes": round(latency_minutes, 1) if latency_minutes else None
|
||||
}
|
||||
|
||||
# System-mätvärden (från loggar)
|
||||
log_file = LOG_DIR / "scheduler.log"
|
||||
if log_file.exists():
|
||||
with open(log_file) as f:
|
||||
lines = f.readlines()
|
||||
|
||||
# Räkna fel
|
||||
errors = [l for l in lines if "ERROR" in l]
|
||||
warnings = [l for l in lines if "WARNING" in l]
|
||||
|
||||
metrics["pipeline"] = {
|
||||
"total_runs": len([l for l in lines if "WEATHER JOB STARTAR" in l]),
|
||||
"errors": len(errors),
|
||||
"warnings": len(warnings)
|
||||
}
|
||||
|
||||
conn.close()
|
||||
|
||||
# Spara mätvärden
|
||||
if METRICS_FILE.exists():
|
||||
with open(METRICS_FILE) as f:
|
||||
history = json.load(f)
|
||||
else:
|
||||
history = []
|
||||
|
||||
history.append(metrics)
|
||||
|
||||
# Behåll senaste 168 timmar (7 dagar)
|
||||
cutoff = datetime.now() - timedelta(hours=168)
|
||||
history = [h for h in history if datetime.fromisoformat(h["timestamp"]) > cutoff]
|
||||
|
||||
with open(METRICS_FILE, 'w') as f:
|
||||
json.dump(history, f, indent=2)
|
||||
|
||||
return metrics
|
||||
|
||||
def print_status():
|
||||
"""Skriv ut aktuell status"""
|
||||
metrics = collect_metrics()
|
||||
|
||||
print("=" * 60)
|
||||
print("LIFE RUNTIME STATUS")
|
||||
print("=" * 60)
|
||||
print(f"Tid: {metrics['timestamp']}")
|
||||
print()
|
||||
print("OBSERVATIONER:")
|
||||
print(f" Total: {metrics['observations']['total']}")
|
||||
print(f" Senaste timmen: {metrics['observations']['last_hour']}")
|
||||
print(f" Dubbletter: {metrics['observations']['duplicates']}")
|
||||
print(f" Reality Latency: {metrics['observations']['reality_latency_minutes']} min")
|
||||
print()
|
||||
print("PIPELINE:")
|
||||
print(f" Körningar: {metrics['pipeline'].get('total_runs', 0)}")
|
||||
print(f" Fel: {metrics['pipeline'].get('errors', 0)}")
|
||||
print(f" Varningar: {metrics['pipeline'].get('warnings', 0)}")
|
||||
print()
|
||||
|
||||
# Beräkna success rate
|
||||
total = metrics['pipeline'].get('total_runs', 0)
|
||||
errors = metrics['pipeline'].get('errors', 0)
|
||||
if total > 0:
|
||||
success_rate = ((total - errors) / total) * 100
|
||||
print(f" Success Rate: {success_rate:.1f}%")
|
||||
|
||||
print("=" * 60)
|
||||
|
||||
if __name__ == "__main__":
|
||||
print_status()
|
||||
Reference in New Issue
Block a user