140 lines
4.9 KiB
Python
Executable File
140 lines
4.9 KiB
Python
Executable File
#!/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 <api_key> [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()) |