"""Structlog configuration for consistent logging throughout the application.""" import logging import sys from typing import Optional import structlog def configure_logging(log_level: str = "INFO") -> None: """Configure structlog with console output. Args: log_level: The logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL). """ level = getattr(logging, log_level.upper(), logging.INFO) # Configure standard library logging logging.basicConfig( format="%(message)s", stream=sys.stdout, level=level, ) # Configure structlog structlog.configure( processors=[ structlog.stdlib.filter_by_level, structlog.stdlib.add_logger_name, structlog.stdlib.add_log_level, structlog.stdlib.PositionalArgumentsFormatter(), structlog.processors.TimeStamper(fmt="iso"), structlog.processors.StackInfoRenderer(), structlog.processors.format_exc_info, structlog.processors.UnicodeDecoder(), structlog.dev.ConsoleRenderer(colors=sys.stdout.isatty()), ], wrapper_class=structlog.stdlib.BoundLogger, context_class=dict, logger_factory=structlog.stdlib.LoggerFactory(), cache_logger_on_first_use=True, ) def get_logger(name: Optional[str] = None) -> structlog.stdlib.BoundLogger: """Get a configured logger instance. Args: name: Optional name for the logger. If not provided, uses the calling module. Returns: A configured structlog logger. """ return structlog.get_logger(name)