import os import psutil import time from datetime import datetime from flask import jsonify from sqlalchemy import text from . import db def check_database(): """Check database connection and response time.""" try: start_time = time.time() # Execute a simple query db.session.execute(text('SELECT 1')) response_time = (time.time() - start_time) * 1000 # Convert to milliseconds return { 'status': 'healthy', 'response_time_ms': round(response_time, 2) } except Exception as e: return { 'status': 'unhealthy', 'error': str(e) } def check_disk_space(): """Check available disk space.""" try: disk = psutil.disk_usage('/') return { 'status': 'healthy' if disk.percent < 90 else 'warning', 'total_gb': round(disk.total / (1024**3), 2), 'used_gb': round(disk.used / (1024**3), 2), 'free_gb': round(disk.free / (1024**3), 2), 'percent_used': disk.percent } except Exception as e: return { 'status': 'unhealthy', 'error': str(e) } def check_memory(): """Check memory usage.""" try: memory = psutil.virtual_memory() return { 'status': 'healthy' if memory.percent < 90 else 'warning', 'total_gb': round(memory.total / (1024**3), 2), 'used_gb': round(memory.used / (1024**3), 2), 'free_gb': round(memory.available / (1024**3), 2), 'percent_used': memory.percent } except Exception as e: return { 'status': 'unhealthy', 'error': str(e) } def check_cpu(): """Check CPU usage.""" try: cpu_percent = psutil.cpu_percent(interval=1) return { 'status': 'healthy' if cpu_percent < 90 else 'warning', 'usage_percent': cpu_percent, 'core_count': psutil.cpu_count() } except Exception as e: return { 'status': 'unhealthy', 'error': str(e) } def check_application(): """Check application-specific metrics.""" try: # Check if required directories exist required_dirs = ['instance', 'logs', 'backups'] dir_status = {} for dir_name in required_dirs: dir_status[dir_name] = os.path.exists(dir_name) # Check if log files are writable log_status = {} log_files = ['logs/mold_cost_calculator.log', 'logs/error.log', 'logs/access.log'] for log_file in log_files: log_status[log_file] = os.access(os.path.dirname(log_file), os.W_OK) return { 'status': 'healthy' if all(dir_status.values()) and all(log_status.values()) else 'warning', 'directories': dir_status, 'log_files': log_status, 'startup_time': datetime.utcnow().isoformat() } except Exception as e: return { 'status': 'unhealthy', 'error': str(e) } def get_health_status(): """Get comprehensive health status of the application.""" checks = { 'database': check_database(), 'disk_space': check_disk_space(), 'memory': check_memory(), 'cpu': check_cpu(), 'application': check_application() } # Determine overall status statuses = [check['status'] for check in checks.values()] if 'unhealthy' in statuses: overall_status = 'unhealthy' elif 'warning' in statuses: overall_status = 'warning' else: overall_status = 'healthy' return { 'status': overall_status, 'timestamp': datetime.utcnow().isoformat(), 'checks': checks }