import time import json from datetime import datetime from functools import wraps class PerformanceMonitor: def __init__(self): self.metrics = { "total_requests": 0, "successful_requests": 0, "failed_requests": 0, "average_response_time": 0, "last_request_time": None, "uptime_start": datetime.now().isoformat() } def log_request(self, func): """Decorator to monitor function performance""" @wraps(func) def wrapper(*args, **kwargs): start_time = time.time() self.metrics["total_requests"] += 1 self.metrics["last_request_time"] = datetime.now().isoformat() try: result = func(*args, **kwargs) self.metrics["successful_requests"] += 1 # Calculate response time response_time = time.time() - start_time self._update_average_response_time(response_time) return result except Exception as e: self.metrics["failed_requests"] += 1 raise e return wrapper def _update_average_response_time(self, new_time): """Update running average of response times""" current_avg = self.metrics["average_response_time"] total_successful = self.metrics["successful_requests"] if total_successful == 1: self.metrics["average_response_time"] = new_time else: self.metrics["average_response_time"] = ( (current_avg * (total_successful - 1) + new_time) / total_successful ) def get_metrics(self): """Get current performance metrics""" success_rate = 0 if self.metrics["total_requests"] > 0: success_rate = ( self.metrics["successful_requests"] / self.metrics["total_requests"] ) * 100 return { **self.metrics, "success_rate_percent": round(success_rate, 2), "average_response_time_seconds": round(self.metrics["average_response_time"], 2) } def get_health_status(self): """Get overall health status""" metrics = self.get_metrics() if metrics["success_rate_percent"] >= 95 and metrics["average_response_time_seconds"] < 10: return "🟢 Healthy" elif metrics["success_rate_percent"] >= 80 and metrics["average_response_time_seconds"] < 15: return "🟡 Degraded" else: return "🔴 Unhealthy" # Global monitor instance monitor = PerformanceMonitor() # Usage example for your main app: # @monitor.log_request # def process_test_lifecycle(selected_story_id, custom_story=""): # # Your existing function code # pass