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()
|