""" Centralized logging setup using loguru. WHY LOGURU over Python's built-in logging: - Built-in logging requires 10+ lines of boilerplate to set up properly - Loguru does it in 3 lines - Loguru auto-formats with colors, timestamps, and file/line info - Loguru handles file rotation automatically - Every serious Python project at companies like Stripe uses structured logging """ import sys from loguru import logger from config.settings import LOG_LEVEL, LOG_FILE, LOG_ROTATION, LOG_RETENTION def setup_logger(): """ Configure loguru logger with both console and file output. Return the configured logger instance Call this once at application startup """ # Remove the default logger handler # (it only prints to console with basic formatting) logger.remove() # ----------- Console Handler ----------- # Prints colored, formatted logs to terminal # Format: 2024-01-15 10:23:45 | INFO | module:function:42 | Message logger.add( sys.stdout, level = LOG_LEVEL, format = ( "{time:YYYY-MM-DD HH:mm:ss} | " "{level: <8} | " "{name}:{function}:{line} | " "{message}" ), colorize = True ) # ----------- File Handler ----------- # Writes all logs to file for debugging and monitoring # rotation="10 MB" -> creates new file when current reaches 10MB # retention="7 days" -> deletes log files oder than 7 days logger.add( LOG_FILE, level = 'DEBUG', format = "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} | {message}", rotation = LOG_ROTATION, retention = LOG_RETENTION, encoding = 'utf-8' ) return logger # Create the logger instance # Other modules import this directly: # from src.utils.logger import get_logger # logger = get_logger(__name__) def get_logger(name: str): """ Get a named logger instance. The name appears in log output so you know which module logged what Usage: from src.utils.logger import get_logger logger = get_logger(__name__) logger.info("Starting ingestion...") """ return logger.bind(name = name) # Initialize logger when this module is first imported # setup_logger()