spark: system health check script with disk/memory report

This commit is contained in:
spark committed 2026-10-24 05:10:47 +00:00
1 parent 183ddba7d2
commit 257470a083
2 files changed
+114 -30

No files matched your search

+93 -30
View File
@@ -1,34 +1,97 @@
#!/usr/bin/env python3
"""Quick multi-URL health checker with JSON output."""
import sys, json, urllib.request, urllib.error, concurrent.futures
"""System health check script - verifies system state and writes report."""
import os
import sys
import platform
import shutil
from datetime import datetime
def check_url(url, timeout=5):
"""Check single URL, return status dict."""
try:
req = urllib.request.Request(url, method='HEAD')
with urllib.request.urlopen(req, timeout=timeout) as resp:
return {"url": url, "status": resp.status, "ok": 200 <= resp.status < 400}
except urllib.error.HTTPError as e:
return {"url": url, "status": e.code, "ok": False, "error": str(e)}
except Exception as e:
return {"url": url, "status": None, "ok": False, "error": str(e)}
def get_disk_usage(path="/"):
"""Get disk usage for a path."""
total, used, free = shutil.disk_usage(path)
return {
'total_gb': round(total / (1024**3), 2),
'used_gb': round(used / (1024**3), 2),
'free_gb': round(free / (1024**3), 2),
'percent_used': round((used / total) * 100, 1)
}
def health_check(urls, parallel=True):
"""Check multiple URLs, return JSON results."""
results = []
if parallel and len(urls) > 1:
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as ex:
results = list(ex.map(check_url, urls))
else:
results = [check_url(u) for u in urls]
return {"checked": len(urls), "passed": sum(1 for r in results if r["ok"]), "results": results}
def get_memory_usage():
"""Get memory usage from /proc/meminfo."""
meminfo = {}
with open('/proc/meminfo', 'r') as f:
for line in f:
parts = line.split()
key = parts[0].rstrip(':')
value = int(parts[1])
meminfo[key] = value
total = meminfo.get('MemTotal', 0)
available = meminfo.get('MemAvailable', meminfo.get('MemFree', 0))
used = total - available
return {
'total_mb': round(total / 1024, 1),
'available_mb': round(available / 1024, 1),
'used_mb': round(used / 1024, 1),
'percent_used': round((used / total) * 100, 1) if total > 0 else 0
}
if __name__ == "__main__":
urls = sys.argv[1:] if len(sys.argv) > 1 else [
"https://httpbin.org/status/200",
"https://httpbin.org/status/404",
"https://httpbin.org/delay/1"
]
result = health_check(urls)
print(json.dumps(result, indent=2))
sys.exit(0 if result["passed"] > 0 else 1)
def get_cpu_count():
"""Get CPU count."""
return os.cpu_count() or 1
def main():
"""Main entry point - write health report."""
report = {
'timestamp': datetime.utcnow().isoformat() + 'Z',
'hostname': platform.node(),
'os': platform.system(),
'os_version': platform.version(),
'python': platform.python_version(),
'cpu_count': get_cpu_count(),
'disk_usage': get_disk_usage('/'),
'memory_usage': get_memory_usage(),
'working_dir': os.getcwd(),
'user': os.environ.get('USER', 'unknown'),
'home': os.environ.get('HOME', '/root')
}
# Write readable report
output_path = '/root/.hermes/wizard-outputs/spark/health_report.txt'
with open(output_path, 'w') as f:
f.write("=== SYSTEM HEALTH REPORT ===\n")
f.write(f"Generated: {report['timestamp']}\n")
f.write(f"Hostname: {report['hostname']}\n")
f.write(f"OS: {report['os']} {report['os_version']}\n")
f.write(f"Python: {report['python']}\n")
f.write(f"CPU Cores: {report['cpu_count']}\n")
f.write(f"\nDisk Usage (/):\n")
f.write(f" Total: {report['disk_usage']['total_gb']} GB\n")
f.write(f" Used: {report['disk_usage']['used_gb']} GB ({report['disk_usage']['percent_used']}%)\n")
f.write(f" Free: {report['disk_usage']['free_gb']} GB\n")
f.write(f"\nMemory Usage:\n")
f.write(f" Total: {report['memory_usage']['total_mb']} MB\n")
f.write(f" Used: {report['memory_usage']['used_mb']} MB ({report['memory_usage']['percent_used']}%)\n")
f.write(f" Available: {report['memory_usage']['available_mb']} MB\n")
f.write(f"\nEnvironment:\n")
f.write(f" Working Dir: {report['working_dir']}\n")
f.write(f" User: {report['user']}\n")
f.write(f" Home: {report['home']}\n")
print(f"Health report written to: {output_path}")
# Validation: verify we can read what we wrote
with open(output_path, 'r') as f:
content = f.read()
# Check key sections exist
assert '=== SYSTEM HEALTH REPORT ===' in content, "Report header missing"
assert 'Disk Usage' in content, "Disk section missing"
assert 'Memory Usage' in content, "Memory section missing"
assert f"CPU Cores: {report['cpu_count']}" in content, "CPU info missing"
return 0
if __name__ == '__main__':
sys.exit(main())
+21
View File
@@ -0,0 +1,21 @@
=== SYSTEM HEALTH REPORT ===
Generated: 2026-10-24T05:09:39.986039Z
Hostname: WorkBench
OS: Linux #71-Ubuntu SMP PREEMPT_DYNAMIC Tue Jul 22 16:52:38 UTC 2025
Python: 3.14.7
CPU Cores: 4
Disk Usage (/):
Total: 153.94 GB
Used: 123.33 GB (80.1%)
Free: 30.59 GB
Memory Usage:
Total: 7941.3 MB
Used: 4577.1 MB (57.6%)
Available: 3364.2 MB
Environment:
Working Dir: /root
User: root
Home: /root