Files
mold_cost_online_tool/app/health.py
T
Gan, Jimmy 6c0d5a4e63 Initial commit: Clean Mold Cost Calculator application
- 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
2025-06-24 02:30:09 +08:00

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
}