- Added DBUtils PooledDB for intelligent connection pooling - Created db_pool.py with lazy-initialized connection pool (max 20 connections) - Added db_connection_context() context manager for safe connection handling - Refactored all 19 database operations to use context manager pattern - Ensures proper connection cleanup and exception handling - Prevents connection exhaustion on POST requests - Added logging configuration for debugging Changes: - py_app/app/db_pool.py: New connection pool manager - py_app/app/logging_config.py: Centralized logging - py_app/app/__init__.py: Updated to use connection pool - py_app/app/routes.py: Refactored all DB operations to use context manager - py_app/app/settings.py: Updated settings handlers - py_app/requirements.txt: Added DBUtils dependency This solves the connection timeout issues experienced with the fgscan page.
143 lines
5.5 KiB
Python
143 lines
5.5 KiB
Python
"""
|
|
Logging Configuration for Trasabilitate Application
|
|
Centralizes all logging setup for the application
|
|
"""
|
|
|
|
import logging
|
|
import logging.handlers
|
|
import os
|
|
import sys
|
|
from datetime import datetime
|
|
|
|
def setup_logging(app=None, log_dir='/srv/quality_app/logs'):
|
|
"""
|
|
Configure comprehensive logging for the application
|
|
|
|
Args:
|
|
app: Flask app instance (optional)
|
|
log_dir: Directory to store log files
|
|
"""
|
|
|
|
# Ensure log directory exists
|
|
os.makedirs(log_dir, exist_ok=True)
|
|
|
|
# Create formatters
|
|
detailed_formatter = logging.Formatter(
|
|
'[%(asctime)s] [%(name)s] [%(levelname)s] %(filename)s:%(lineno)d - %(funcName)s() - %(message)s',
|
|
datefmt='%Y-%m-%d %H:%M:%S'
|
|
)
|
|
|
|
simple_formatter = logging.Formatter(
|
|
'[%(asctime)s] [%(levelname)s] %(message)s',
|
|
datefmt='%Y-%m-%d %H:%M:%S'
|
|
)
|
|
|
|
# Create logger
|
|
root_logger = logging.getLogger()
|
|
root_logger.setLevel(logging.DEBUG)
|
|
|
|
# Remove any existing handlers to avoid duplicates
|
|
for handler in root_logger.handlers[:]:
|
|
root_logger.removeHandler(handler)
|
|
|
|
# ========================================================================
|
|
# File Handler - All logs (DEBUG and above)
|
|
# ========================================================================
|
|
all_log_file = os.path.join(log_dir, f'application_{datetime.now().strftime("%Y%m%d")}.log')
|
|
file_handler_all = logging.handlers.RotatingFileHandler(
|
|
all_log_file,
|
|
maxBytes=10 * 1024 * 1024, # 10 MB
|
|
backupCount=10
|
|
)
|
|
file_handler_all.setLevel(logging.DEBUG)
|
|
file_handler_all.setFormatter(detailed_formatter)
|
|
root_logger.addHandler(file_handler_all)
|
|
|
|
# ========================================================================
|
|
# File Handler - Error logs (ERROR and above)
|
|
# ========================================================================
|
|
error_log_file = os.path.join(log_dir, f'errors_{datetime.now().strftime("%Y%m%d")}.log')
|
|
file_handler_errors = logging.handlers.RotatingFileHandler(
|
|
error_log_file,
|
|
maxBytes=5 * 1024 * 1024, # 5 MB
|
|
backupCount=5
|
|
)
|
|
file_handler_errors.setLevel(logging.ERROR)
|
|
file_handler_errors.setFormatter(detailed_formatter)
|
|
root_logger.addHandler(file_handler_errors)
|
|
|
|
# ========================================================================
|
|
# Console Handler - INFO and above (for Docker logs)
|
|
# ========================================================================
|
|
console_handler = logging.StreamHandler(sys.stdout)
|
|
console_handler.setLevel(logging.INFO)
|
|
console_handler.setFormatter(simple_formatter)
|
|
root_logger.addHandler(console_handler)
|
|
|
|
# ========================================================================
|
|
# Database-specific logger
|
|
# ========================================================================
|
|
db_logger = logging.getLogger('trasabilitate.db')
|
|
db_logger.setLevel(logging.DEBUG)
|
|
|
|
db_log_file = os.path.join(log_dir, f'database_{datetime.now().strftime("%Y%m%d")}.log')
|
|
db_file_handler = logging.handlers.RotatingFileHandler(
|
|
db_log_file,
|
|
maxBytes=10 * 1024 * 1024, # 10 MB
|
|
backupCount=10
|
|
)
|
|
db_file_handler.setLevel(logging.DEBUG)
|
|
db_file_handler.setFormatter(detailed_formatter)
|
|
db_logger.addHandler(db_file_handler)
|
|
|
|
# ========================================================================
|
|
# Routes-specific logger
|
|
# ========================================================================
|
|
routes_logger = logging.getLogger('trasabilitate.routes')
|
|
routes_logger.setLevel(logging.DEBUG)
|
|
|
|
routes_log_file = os.path.join(log_dir, f'routes_{datetime.now().strftime("%Y%m%d")}.log')
|
|
routes_file_handler = logging.handlers.RotatingFileHandler(
|
|
routes_log_file,
|
|
maxBytes=10 * 1024 * 1024, # 10 MB
|
|
backupCount=10
|
|
)
|
|
routes_file_handler.setLevel(logging.DEBUG)
|
|
routes_file_handler.setFormatter(detailed_formatter)
|
|
routes_logger.addHandler(routes_file_handler)
|
|
|
|
# ========================================================================
|
|
# Settings-specific logger
|
|
# ========================================================================
|
|
settings_logger = logging.getLogger('trasabilitate.settings')
|
|
settings_logger.setLevel(logging.DEBUG)
|
|
|
|
settings_log_file = os.path.join(log_dir, f'settings_{datetime.now().strftime("%Y%m%d")}.log')
|
|
settings_file_handler = logging.handlers.RotatingFileHandler(
|
|
settings_log_file,
|
|
maxBytes=5 * 1024 * 1024, # 5 MB
|
|
backupCount=5
|
|
)
|
|
settings_file_handler.setLevel(logging.DEBUG)
|
|
settings_file_handler.setFormatter(detailed_formatter)
|
|
settings_logger.addHandler(settings_file_handler)
|
|
|
|
# Log initialization
|
|
root_logger.info("=" * 80)
|
|
root_logger.info("Trasabilitate Application - Logging Initialized")
|
|
root_logger.info("=" * 80)
|
|
root_logger.info(f"Log directory: {log_dir}")
|
|
root_logger.info(f"Main log file: {all_log_file}")
|
|
root_logger.info(f"Error log file: {error_log_file}")
|
|
root_logger.info(f"Database log file: {db_log_file}")
|
|
root_logger.info(f"Routes log file: {routes_log_file}")
|
|
root_logger.info(f"Settings log file: {settings_log_file}")
|
|
root_logger.info("=" * 80)
|
|
|
|
return root_logger
|
|
|
|
|
|
def get_logger(name):
|
|
"""Get a logger with the given name"""
|
|
return logging.getLogger(f'trasabilitate.{name}')
|