Implement database connection pooling with context manager pattern
- 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.
This commit is contained in:
142
py_app/app/logging_config.py
Normal file
142
py_app/app/logging_config.py
Normal file
@@ -0,0 +1,142 @@
|
||||
"""
|
||||
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}')
|
||||
Reference in New Issue
Block a user