diegobeyl/backtesting
2
1"""
2Enhanced logging configuration with structured JSON logging and file rotation.
3"""
4import logging
5import sys
6from logging.handlers import RotatingFileHandler
7from pathlib import Path
8from pythonjsonlogger import jsonlogger
9from config import config
10
11# Diccionario para rastrear loggers ya inicializados
12_initialized_loggers = {}
13
14
15def setup_logger(name: str = __name__) -> logging.Logger:
16 """
17 Configure and return a logger with structured logging support.
18
19 Args:
20 name: Logger name (typically __name__ of the calling module)
21
22 Returns:
23 Configured logger instance
24 """
25 # Si ya fue inicializado, devolverlo sin cambios
26 if name in _initialized_loggers:
27 return logging.getLogger(name)
28
29 logger = logging.getLogger(name)
30
31 # Limpiar handlers previos completamente
32 for handler in logger.handlers[:]:
33 handler.close()
34 logger.removeHandler(handler)
35
36 logger.setLevel(getattr(logging, config.LOG_LEVEL))
37 logger.propagate = False
38
39 # Console Handler
40 console_handler = logging.StreamHandler(sys.stdout)
41 console_handler.setLevel(getattr(logging, config.LOG_LEVEL))
42
43 if config.LOG_FORMAT == 'json':
44 # JSON formatter for structured logging
45 json_formatter = jsonlogger.JsonFormatter(
46 '%(asctime)s %(name)s %(levelname)s %(message)s',
47 datefmt='%Y-%m-%d %H:%M:%S'
48 )
49 console_handler.setFormatter(json_formatter)
50 else:
51 # Standard text formatter
52 text_formatter = logging.Formatter(
53 '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
54 datefmt='%Y-%m-%d %H:%M:%S'
55 )
56 console_handler.setFormatter(text_formatter)
57
58 logger.addHandler(console_handler)
59
60 # File Handler with rotation
61 try:
62 file_handler = RotatingFileHandler(
63 config.LOG_FILE,
64 maxBytes=config.LOG_MAX_BYTES,
65 backupCount=config.LOG_BACKUP_COUNT,
66 encoding='utf-8'
67 )
68 file_handler.setLevel(getattr(logging, config.LOG_LEVEL))
69
70 if config.LOG_FORMAT == 'json':
71 file_handler.setFormatter(json_formatter)
72 else:
73 file_handler.setFormatter(text_formatter)
74
75 logger.addHandler(file_handler)
76 except Exception as e:
77 logger.warning(f"Could not create file handler: {e}")
78
79 # Marcar como inicializado
80 _initialized_loggers[name] = True
81
82 return logger
83
84
85# Create default application logger
86app_logger = setup_logger('backtesting_app')
87 