diff --git a/wizard-work/spark/sys_metrics.py b/wizard-work/spark/sys_metrics.py new file mode 100644 index 0000000..fa20790 --- /dev/null +++ b/wizard-work/spark/sys_metrics.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +"""System metrics collector - outputs JSON to stdout.""" + +import json +import os +import shutil + +def get_disk_usage(): + """Get disk usage for root filesystem.""" + usage = shutil.disk_usage('/') + return { + "total": usage.total, + "used": usage.used, + "free": usage.free, + "percent_used": round(usage.used / usage.total * 100, 2) + } + +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) * 1024 + available = meminfo.get('MemAvailable', meminfo.get('MemFree', 0)) * 1024 + used = total - available + + return { + "total": total, + "used": used, + "available": available, + "percent_used": round(used / total * 100, 2) if total > 0 else 0 + } + +def get_load_average(): + """Get system load average.""" + load1, load5, load15 = os.getloadavg() + return { + "1min": load1, + "5min": load5, + "15min": load15 + } + +def get_uptime(): + """Get system uptime in seconds.""" + with open('/proc/uptime', 'r') as f: + uptime_seconds = float(f.readline().split()[0]) + return round(uptime_seconds, 2) + +def main(): + metrics = { + "disk": get_disk_usage(), + "memory": get_memory_usage(), + "load_average": get_load_average(), + "uptime_seconds": get_uptime() + } + print(json.dumps(metrics, indent=2)) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/wizard-work/spark/verify_metrics.py b/wizard-work/spark/verify_metrics.py new file mode 100644 index 0000000..901e7b0 --- /dev/null +++ b/wizard-work/spark/verify_metrics.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +"""Verify sys_metrics.py produces valid JSON output.""" + +import json +import subprocess + +result = subprocess.run( + ['python3', '/root/.hermes/wizard-outputs/spark/sys_metrics.py'], + capture_output=True, + text=True +) + +if result.returncode != 0: + print(f"FAILED: Script exited with code {result.returncode}") + exit(1) + +try: + data = json.loads(result.stdout) +except json.JSONDecodeError as e: + print(f"FAILED: Invalid JSON - {e}") + exit(1) + +required_keys = ['disk', 'memory', 'load_average', 'uptime_seconds'] +for key in required_keys: + if key not in data: + print(f"FAILED: Missing key '{key}'") + exit(1) + +# Verify disk has required fields +disk_fields = ['total', 'used', 'free', 'percent_used'] +for field in disk_fields: + if field not in data['disk']: + print(f"FAILED: Disk missing field '{field}'") + exit(1) + +# Verify memory has required fields +mem_fields = ['total', 'used', 'available', 'percent_used'] +for field in mem_fields: + if field not in data['memory']: + print(f"FAILED: Memory missing field '{field}'") + exit(1) + +# Verify load_average has required fields +load_fields = ['1min', '5min', '15min'] +for field in load_fields: + if field not in data['load_average']: + print(f"FAILED: Load average missing field '{field}'") + exit(1) + +print("VERIFIED: sys_metrics.py produces valid JSON with all required fields") +print(f"Keys: {list(data.keys())}") +print(f"Disk usage: {data['disk']['percent_used']}%") +print(f"Memory usage: {data['memory']['percent_used']}%") +print(f"Load average: {data['load_average']['1min']}") +print(f"Uptime: {data['uptime_seconds']} seconds") \ No newline at end of file