#!/usr/bin/env python3 """ Monitoring script for the Puppeteer API server. This script helps track system resources and browser pool status. """ import asyncio import aiohttp import json import time import sys from datetime import datetime async def get_status(api_key, base_url="http://localhost:8000"): """Get system status from the API""" async with aiohttp.ClientSession() as session: headers = {"X-API-Key": api_key} try: async with session.get(f"{base_url}/status", headers=headers) as response: if response.status == 200: return await response.json() else: print(f"Error getting status: {response.status}") return None except Exception as e: print(f"Exception getting status: {e}") return None async def emergency_cleanup(api_key, base_url="http://localhost:8000"): """Trigger emergency cleanup""" async with aiohttp.ClientSession() as session: headers = {"X-API-Key": api_key} try: async with session.post(f"{base_url}/emergency-cleanup", headers=headers) as response: if response.status == 200: result = await response.json() print(f"Emergency cleanup: {result}") return True else: print(f"Error triggering cleanup: {response.status}") return False except Exception as e: print(f"Exception triggering cleanup: {e}") return False def print_status(status_data): """Print formatted status information""" if not status_data: print("No status data available") return print(f"\n{'='*60}") print(f"Status Report - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") print(f"{'='*60}") # System information system = status_data.get('system', {}) print(f"\n📊 SYSTEM STATUS:") print(f" CPU Usage: {system.get('cpu_percent', 'N/A')}%") print(f" Memory: {system.get('memory_mb', 'N/A'):.1f} MB ({system.get('memory_percent', 'N/A'):.1f}%)") print(f" Open Files: {system.get('open_files', 'N/A')}") print(f" Network Connections: {system.get('connections', 'N/A')}") print(f" Threads: {system.get('threads', 'N/A')}") # Browser pool information pool = status_data.get('browser_pool', {}) print(f"\n🌐 BROWSER POOL:") print(f" Pool Size: {pool.get('pool_size', 'N/A')}") print(f" Active Browsers: {pool.get('active_browsers', 'N/A')}") print(f" Max Browsers: {pool.get('max_browsers', 'N/A')}") print(f" Browser TTL: {pool.get('browser_ttl_seconds', 'N/A')}s") print(f" Concurrent Operations Limit: {pool.get('concurrent_operations_limit', 'N/A')}") # Browser ages ages = pool.get('browser_ages_seconds', []) if ages: print(f" Browser Ages: {[f'{age:.0f}s' for age in ages]}") # Warnings warnings = [] if system.get('cpu_percent', 0) > 80: warnings.append("⚠️ High CPU usage") if system.get('memory_percent', 0) > 80: warnings.append("⚠️ High memory usage") if system.get('open_files', 0) > 1000: warnings.append("⚠️ Many open files") if pool.get('active_browsers', 0) >= pool.get('max_browsers', 0): warnings.append("⚠️ Browser pool at capacity") if warnings: print(f"\n🚨 WARNINGS:") for warning in warnings: print(f" {warning}") else: print(f"\n✅ All systems normal") async def monitor_loop(api_key, interval=30, base_url="http://localhost:8000"): """Continuous monitoring loop""" print(f"Starting monitoring with {interval}s intervals...") print(f"Press Ctrl+C to stop") try: while True: status = await get_status(api_key, base_url) print_status(status) # Wait for next check await asyncio.sleep(interval) except KeyboardInterrupt: print("\nMonitoring stopped by user") async def main(): """Main function""" if len(sys.argv) < 2: print("Usage: python monitor.py [interval_seconds] [base_url]") print("Example: python monitor.py my-api-key 30 http://localhost:8000") sys.exit(1) api_key = sys.argv[1] interval = int(sys.argv[2]) if len(sys.argv) > 2 else 30 base_url = sys.argv[3] if len(sys.argv) > 3 else "http://localhost:8000" if len(sys.argv) > 4 and sys.argv[4] == "cleanup": # Emergency cleanup mode print("Triggering emergency cleanup...") success = await emergency_cleanup(api_key, base_url) if success: print("Emergency cleanup completed successfully") else: print("Emergency cleanup failed") return # Start monitoring await monitor_loop(api_key, interval, base_url) if __name__ == "__main__": asyncio.run(main())