This commit is contained in:
Executable
+140
@@ -0,0 +1,140 @@
|
||||
#!/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())
|
||||
Reference in New Issue
Block a user