Vollständige Pipeline zur Analyse kommunaler Vorlagen aus ALLRIS: - OParl-Import: 20.149 Vorlagen - PDF-Extraktion: 10.045 Volltexte (adaptives Throttling) - KI-Zusammenfassungen: 10.026 via Qwen Plus (parallelisiert) - Beratungsfolge-Scraper: Beschlusstexte + Wortprotokolle - Abstimmungs-Analyse mit Koalitionsmatrix - Georeferenzierung (Nominatim) Stack: FastAPI + SvelteKit + SQLite Deployment: Docker + Traefik auf VServer Daten (DB, Logs) nicht im Repo — siehe Restic-Backup. Repo-Setup: scripts/setup.sh für Neuaufbau aus OParl-API.
88 lines
2.4 KiB
Python
88 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Pusht Mac Mini System-Metriken zum VServer für Netdata.
|
|
Läuft als Hintergrund-Daemon.
|
|
"""
|
|
|
|
import subprocess
|
|
import time
|
|
import httpx
|
|
|
|
METRICS_URL = "http://152.53.119.77:8127"
|
|
INTERVAL = 10 # Sekunden
|
|
|
|
def get_cpu_percent():
|
|
"""CPU-Auslastung via top."""
|
|
result = subprocess.run(
|
|
["top", "-l", "1", "-n", "0"],
|
|
capture_output=True, text=True
|
|
)
|
|
for line in result.stdout.split("\n"):
|
|
if "CPU usage" in line:
|
|
# "CPU usage: 2.53% user, 10.52% sys, 84.21% idle"
|
|
import re
|
|
numbers = re.findall(r'([\d.]+)%', line)
|
|
if len(numbers) >= 2:
|
|
return float(numbers[0]) + float(numbers[1]) # user + sys
|
|
return 0
|
|
|
|
def get_memory_percent():
|
|
"""Memory-Auslastung via vm_stat."""
|
|
result = subprocess.run(["vm_stat"], capture_output=True, text=True)
|
|
stats = {}
|
|
for line in result.stdout.split("\n"):
|
|
if ":" in line:
|
|
key, val = line.split(":")
|
|
val = val.strip().rstrip(".")
|
|
try:
|
|
stats[key.strip()] = int(val)
|
|
except:
|
|
pass
|
|
|
|
page_size = 16384 # Apple Silicon
|
|
pages_free = stats.get("Pages free", 0)
|
|
pages_active = stats.get("Pages active", 0)
|
|
pages_inactive = stats.get("Pages inactive", 0)
|
|
pages_wired = stats.get("Pages wired down", 0)
|
|
|
|
total_pages = pages_free + pages_active + pages_inactive + pages_wired
|
|
used_pages = pages_active + pages_wired
|
|
|
|
if total_pages > 0:
|
|
return (used_pages / total_pages) * 100
|
|
return 0
|
|
|
|
def get_load_avg():
|
|
"""Load average."""
|
|
result = subprocess.run(["/usr/sbin/sysctl", "-n", "vm.loadavg"], capture_output=True, text=True)
|
|
# "{ 1.23 2.34 3.45 }"
|
|
parts = result.stdout.strip().strip("{}").split()
|
|
if parts:
|
|
return float(parts[0])
|
|
return 0
|
|
|
|
def push_metrics():
|
|
"""Sammelt und pusht Metriken."""
|
|
metrics = {
|
|
"macmini.cpu_percent": get_cpu_percent(),
|
|
"macmini.memory_percent": get_memory_percent(),
|
|
"macmini.load_1min": get_load_avg(),
|
|
}
|
|
|
|
try:
|
|
httpx.post(METRICS_URL, json=metrics, timeout=5)
|
|
print(f"Pushed: {metrics}")
|
|
except Exception as e:
|
|
print(f"Push failed: {e}")
|
|
|
|
def main():
|
|
print(f"Mac Mini metrics pusher → {METRICS_URL}")
|
|
print(f"Interval: {INTERVAL}s")
|
|
|
|
while True:
|
|
push_metrics()
|
|
time.sleep(INTERVAL)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|