remodulation du projet et des classes

This commit is contained in:
cedrick2711
2026-07-28 23:33:31 -04:00
parent 90ac3eb804
commit 3feae80767
94 changed files with 2644 additions and 4366 deletions
+154
View File
@@ -0,0 +1,154 @@
"""Structured logging configuration for the Team Tryouts application.
This module configures rotating file handlers for application logs,
with separate files for errors, authentication events, and general logs.
Sensitive data (passwords, tokens) is automatically filtered out.
Usage:
from logging_config import configure_logging
configure_logging(app)
"""
import logging
import os
from logging.handlers import RotatingFileHandler
import re
class SensitiveDataFilter(logging.Filter):
"""Logging filter that redacts sensitive information from log messages.
Filters out: passwords, API keys, session tokens, and other secrets
that might accidentally be logged.
"""
# Patterns to redact
SENSITIVE_PATTERNS = [
(re.compile(r'(?:password|passwd|secret|token|api[_-]?key)\s*[:=]\s*[^\s,;)]+', re.IGNORECASE), '[REDACTED]'),
(re.compile(r'(?:password|passwd|secret|token|api[_-]?key)\s*[:=]\s*"[^"]*"', re.IGNORECASE), lambda m: m.group(0).split('=')[0] + '="[REDACTED]"'),
(re.compile(r'Authorization[:\s]+[^\s]+', re.IGNORECASE), 'Authorization: [REDACTED]'),
(re.compile(r'Bearer\s+[^\s]+', re.IGNORECASE), 'Bearer [REDACTED]'),
]
def filter(self, record):
"""Apply redaction to the log record's message.
Args:
record: The log record to filter.
Returns:
bool: Always True (never drops records, only redacts).
"""
if hasattr(record, 'msg') and isinstance(record.msg, str):
msg = record.msg
for pattern, replacement in self.SENSITIVE_PATTERNS:
if callable(replacement):
msg = pattern.sub(replacement, msg)
else:
msg = pattern.sub(replacement, msg)
record.msg = msg
return True
def configure_logging(app):
"""Configure structured logging for the Flask application.
Sets up three rotating file handlers:
- errors.log: ERROR and CRITICAL level messages
- auth.log: Authentication-related events (INFO and above)
- app.log: All application logs (DEBUG and above, configurable)
Also configures console output for development.
Args:
app: The Flask application instance to configure logging for.
"""
log_dir = os.path.join(os.getcwd(), 'logs')
os.makedirs(log_dir, exist_ok=True)
# Remove default Flask handlers to avoid duplicate logging
app.logger.handlers.clear()
# Set base log level from environment (default: INFO)
log_level_name = os.getenv('LOG_LEVEL', 'INFO').upper()
log_level = getattr(logging, log_level_name, logging.INFO)
app.logger.setLevel(log_level)
# Create the sensitive data filter
sensitive_filter = SensitiveDataFilter()
# Formatter with timestamp, level, module, and message
formatter = logging.Formatter(
'[%(asctime)s] %(levelname)s [%(name)s:%(lineno)d] %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
# -------------------------------------------------------------------------
# 1. Error Log Handler
# -------------------------------------------------------------------------
error_handler = RotatingFileHandler(
os.path.join(log_dir, 'errors.log'),
maxBytes=10 * 1024 * 1024, # 10 MB
backupCount=10
)
error_handler.setLevel(logging.ERROR)
error_handler.setFormatter(formatter)
error_handler.addFilter(sensitive_filter)
app.logger.addHandler(error_handler)
# -------------------------------------------------------------------------
# 2. Authentication Log Handler
# -------------------------------------------------------------------------
auth_handler = RotatingFileHandler(
os.path.join(log_dir, 'auth.log'),
maxBytes=10 * 1024 * 1024, # 10 MB
backupCount=5
)
auth_handler.setLevel(logging.INFO)
auth_handler.setFormatter(formatter)
auth_handler.addFilter(sensitive_filter)
# Create a named logger specifically for auth events
auth_logger = logging.getLogger('team_tryouts.auth')
auth_logger.setLevel(logging.INFO)
auth_logger.addHandler(auth_handler)
auth_logger.propagate = False # Don't double-log to root
# -------------------------------------------------------------------------
# 3. Application Log Handler (general)
# -------------------------------------------------------------------------
app_handler = RotatingFileHandler(
os.path.join(log_dir, 'app.log'),
maxBytes=10 * 1024 * 1024, # 10 MB
backupCount=10
)
app_handler.setLevel(log_level)
app_handler.setFormatter(formatter)
app_handler.addFilter(sensitive_filter)
app.logger.addHandler(app_handler)
# -------------------------------------------------------------------------
# 4. Console Handler (for development)
# -------------------------------------------------------------------------
if os.getenv('FLASK_DEBUG', 'false').lower() == 'true':
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
console_handler.setFormatter(formatter)
console_handler.addFilter(sensitive_filter)
app.logger.addHandler(console_handler)
# Log startup information
app.logger.info('Logging configured - Level: %s, Log directory: %s', log_level_name, log_dir)
app.logger.info('Application startup')
return app.logger
# Module-level auth logger factory
def get_auth_logger():
"""Get the authentication event logger.
Returns:
logging.Logger: Logger for authentication events.
"""
return logging.getLogger('team_tryouts.auth')