#!/usr/bin/env python3 """ Performance monitoring script for tracking CPU utilization during processing. Run this in a separate terminal while your main processing script is running. """ import psutil import time import matplotlib.pyplot as plt import numpy as np from datetime import datetime import threading import json import os class PerformanceMonitor: def __init__(self, log_file="performance_log.json"): self.log_file = log_file self.monitoring = False self.data = { 'timestamps': [], 'cpu_percent': [], 'memory_percent': [], 'cpu_count': [], 'load_average': [], 'network_io': [], 'disk_io': [] } def start_monitoring(self): """Start monitoring in a separate thread""" self.monitoring = True self.monitor_thread = threading.Thread(target=self._monitor_loop) self.monitor_thread.daemon = True self.monitor_thread.start() print("šŸš€ Performance monitoring started...") def stop_monitoring(self): """Stop monitoring""" self.monitoring = False if hasattr(self, 'monitor_thread'): self.monitor_thread.join() print("ā¹ļø Performance monitoring stopped.") def _monitor_loop(self): """Main monitoring loop""" while self.monitoring: try: # CPU usage cpu_percent = psutil.cpu_percent(interval=1, percpu=True) cpu_avg = np.mean(cpu_percent) # Memory usage memory = psutil.virtual_memory() # Load average load_avg = psutil.getloadavg() # Network I/O net_io = psutil.net_io_counters() # Disk I/O disk_io = psutil.disk_io_counters() # Store data timestamp = datetime.now().isoformat() self.data['timestamps'].append(timestamp) self.data['cpu_percent'].append(cpu_percent) self.data['memory_percent'].append(memory.percent) self.data['cpu_count'].append(len(cpu_percent)) self.data['load_average'].append(load_avg) self.data['network_io'].append({ 'bytes_sent': net_io.bytes_sent, 'bytes_recv': net_io.bytes_recv }) self.data['disk_io'].append({ 'read_bytes': disk_io.read_bytes, 'write_bytes': disk_io.write_bytes }) # Print current stats print(f"\ršŸ“Š CPU: {cpu_avg:.1f}% | Memory: {memory.percent:.1f}% | Load: {load_avg[0]:.2f}", end='') except Exception as e: print(f"\nāŒ Monitoring error: {e}") def save_data(self): """Save monitoring data to file""" with open(self.log_file, 'w') as f: json.dump(self.data, f, indent=2) print(f"\nšŸ’¾ Performance data saved to {self.log_file}") def plot_performance(self): """Create performance plots""" if not self.data['timestamps']: print("āŒ No data to plot") return # Convert timestamps to relative time start_time = datetime.fromisoformat(self.data['timestamps'][0]) relative_times = [(datetime.fromisoformat(ts) - start_time).total_seconds() for ts in self.data['timestamps']] # Create subplots fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 10)) # CPU usage cpu_data = np.array(self.data['cpu_percent']) ax1.plot(relative_times, np.mean(cpu_data, axis=1), label='Average CPU %') ax1.fill_between(relative_times, np.min(cpu_data, axis=1), np.max(cpu_data, axis=1), alpha=0.3) ax1.set_title('CPU Utilization') ax1.set_ylabel('CPU %') ax1.grid(True) ax1.legend() # Memory usage ax2.plot(relative_times, self.data['memory_percent'], label='Memory %') ax2.set_title('Memory Utilization') ax2.set_ylabel('Memory %') ax2.grid(True) ax2.legend() # Load average load_data = np.array(self.data['load_average']) ax3.plot(relative_times, load_data[:, 0], label='1min') ax3.plot(relative_times, load_data[:, 1], label='5min') ax3.plot(relative_times, load_data[:, 2], label='15min') ax3.set_title('System Load Average') ax3.set_ylabel('Load') ax3.grid(True) ax3.legend() # Network I/O net_data = self.data['network_io'] bytes_sent = [d['bytes_sent'] for d in net_data] bytes_recv = [d['bytes_recv'] for d in net_data] ax4.plot(relative_times, bytes_sent, label='Bytes Sent') ax4.plot(relative_times, bytes_recv, label='Bytes Received') ax4.set_title('Network I/O') ax4.set_ylabel('Bytes') ax4.grid(True) ax4.legend() plt.tight_layout() plt.savefig('performance_plot.png', dpi=300, bbox_inches='tight') print("šŸ“ˆ Performance plot saved as 'performance_plot.png'") def print_summary(self): """Print performance summary""" if not self.data['timestamps']: print("āŒ No data available") return cpu_data = np.array(self.data['cpu_percent']) memory_data = np.array(self.data['memory_percent']) print("\n" + "="*50) print("šŸ“Š PERFORMANCE SUMMARY") print("="*50) print(f"šŸ“ˆ Monitoring duration: {len(self.data['timestamps'])} samples") print(f"šŸ–„ļø CPU cores: {self.data['cpu_count'][0]}") print(f"⚔ Average CPU usage: {np.mean(cpu_data):.1f}%") print(f"šŸ”„ Peak CPU usage: {np.max(cpu_data):.1f}%") print(f"šŸ’¾ Average memory usage: {np.mean(memory_data):.1f}%") print(f"šŸ“Š Peak memory usage: {np.max(memory_data):.1f}%") # Calculate CPU utilization per core core_utilization = np.mean(cpu_data, axis=0) print(f"\nšŸ”§ Per-core CPU utilization:") for i, util in enumerate(core_utilization): print(f" Core {i+1:2d}: {util:5.1f}%") # Calculate efficiency total_cpu_potential = len(core_utilization) * 100 actual_cpu_usage = np.sum(core_utilization) efficiency = (actual_cpu_usage / total_cpu_potential) * 100 print(f"\nšŸŽÆ CPU Efficiency: {efficiency:.1f}%") if efficiency < 50: print("āš ļø Low CPU utilization detected!") print("šŸ’” Consider:") print(" - Increasing batch sizes") print(" - Using more concurrent processes") print(" - Optimizing I/O operations") elif efficiency > 90: print("āœ… Excellent CPU utilization!") else: print("šŸ‘ Good CPU utilization") def main(): """Main function""" print("šŸ” Performance Monitor for 192-core system") print("Press Ctrl+C to stop monitoring and generate report") monitor = PerformanceMonitor() try: monitor.start_monitoring() # Keep running until interrupted while True: time.sleep(1) except KeyboardInterrupt: print("\n\nā¹ļø Stopping monitoring...") monitor.stop_monitoring() # Generate report monitor.save_data() monitor.plot_performance() monitor.print_summary() if __name__ == "__main__": main()