6c0d5a4e63
- Flask-based mold cost calculation application - PostgreSQL database with SQLAlchemy ORM - Docker/Podman containerization - Comprehensive documentation in docs/ - Clean, organized codebase without obsolete files - Production-ready deployment configuration - Enhanced pytest configuration with coverage reporting - Master/Development branch structure
126 lines
3.7 KiB
Python
126 lines
3.7 KiB
Python
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
|
|
} |