demander IA de faire tous les modifications pour que le webapp soit pret au déploiement.
Force connection HTTPS, proxy-inversé, WSGI de production, reset cookie de conncection à chaque reconnection, limite sur les mdp, fichiers et One on One par minute, verification d'injection de SQL dans les champs d'entrées. renommage des fichiers lors du téléchargement, fichier de backup quotidien pour la bd et j'ai oublié quelque chose :(
This commit is contained in:
@@ -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')
|
||||
Reference in New Issue
Block a user