Spaces:
Runtime error
Runtime error
| """ | |
| Centralized logging module for AGI Multi-Model API. | |
| Provides structured logging with: | |
| - Colored console output | |
| - File logging with rotation | |
| - Configurable log levels | |
| - Timestamp and module name tracking | |
| """ | |
| import logging | |
| import sys | |
| from pathlib import Path | |
| from logging.handlers import RotatingFileHandler | |
| from typing import Optional | |
| class ColoredFormatter(logging.Formatter): | |
| """Custom formatter with color support for console output.""" | |
| # ANSI color codes | |
| COLORS = { | |
| 'DEBUG': '\033[36m', # Cyan | |
| 'INFO': '\033[32m', # Green | |
| 'WARNING': '\033[33m', # Yellow | |
| 'ERROR': '\033[31m', # Red | |
| 'CRITICAL': '\033[35m', # Magenta | |
| } | |
| RESET = '\033[0m' | |
| BOLD = '\033[1m' | |
| def format(self, record): | |
| """Format log record with colors.""" | |
| # Add color to level name | |
| levelname = record.levelname | |
| if levelname in self.COLORS: | |
| record.levelname = f"{self.COLORS[levelname]}{self.BOLD}{levelname}{self.RESET}" | |
| # Format the message | |
| result = super().format(record) | |
| # Reset levelname for other handlers | |
| record.levelname = levelname | |
| return result | |
| class Logger: | |
| """ | |
| Singleton logger class for the entire application. | |
| Usage: | |
| from logger import get_logger | |
| logger = get_logger(__name__) | |
| logger.info("Application started") | |
| """ | |
| _instance: Optional[logging.Logger] = None | |
| _initialized: bool = False | |
| def get_logger( | |
| cls, | |
| name: str = "AGI", | |
| level: int = logging.INFO, | |
| log_file: Optional[str] = "agi.log", | |
| max_bytes: int = 10 * 1024 * 1024, # 10MB | |
| backup_count: int = 5 | |
| ) -> logging.Logger: | |
| """ | |
| Get or create the application logger. | |
| Args: | |
| name: Logger name (typically module name) | |
| level: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL) | |
| log_file: Path to log file (None to disable file logging) | |
| max_bytes: Maximum size of log file before rotation | |
| backup_count: Number of backup files to keep | |
| Returns: | |
| Configured logger instance | |
| """ | |
| # Create or get logger | |
| logger = logging.getLogger(name) | |
| # Only configure handlers once for the root logger | |
| if not cls._initialized and name == "AGI": | |
| logger.setLevel(level) | |
| # Console handler with colors | |
| console_handler = logging.StreamHandler(sys.stdout) | |
| console_handler.setLevel(level) | |
| console_formatter = ColoredFormatter( | |
| fmt='%(asctime)s | %(levelname)s | %(name)s | %(message)s', | |
| datefmt='%Y-%m-%d %H:%M:%S' | |
| ) | |
| console_handler.setFormatter(console_formatter) | |
| logger.addHandler(console_handler) | |
| # File handler with rotation (if enabled) | |
| if log_file: | |
| log_path = Path(log_file) | |
| log_path.parent.mkdir(parents=True, exist_ok=True) | |
| file_handler = RotatingFileHandler( | |
| log_file, | |
| maxBytes=max_bytes, | |
| backupCount=backup_count | |
| ) | |
| file_handler.setLevel(level) | |
| file_formatter = logging.Formatter( | |
| fmt='%(asctime)s | %(levelname)-8s | %(name)s | %(funcName)s:%(lineno)d | %(message)s', | |
| datefmt='%Y-%m-%d %H:%M:%S' | |
| ) | |
| file_handler.setFormatter(file_formatter) | |
| logger.addHandler(file_handler) | |
| # Prevent propagation to avoid duplicate logs | |
| logger.propagate = False | |
| cls._initialized = True | |
| return logger | |
| # Convenience function for easy import | |
| def get_logger(name: str = "AGI", level: int = logging.INFO) -> logging.Logger: | |
| """ | |
| Get a logger instance for the specified module. | |
| Args: | |
| name: Logger name (use __name__ for automatic module naming) | |
| level: Logging level (default: INFO) | |
| Returns: | |
| Configured logger instance | |
| Example: | |
| from logger import get_logger | |
| logger = get_logger(__name__) | |
| logger.info("Starting application") | |
| """ | |
| return Logger.get_logger(name, level) | |
| # Initialize the root logger on module import | |
| _root_logger = Logger.get_logger("AGI", level=logging.INFO) | |
| if __name__ == "__main__": | |
| # Test the logger | |
| logger = get_logger("test_module") | |
| logger.debug("This is a debug message") | |
| logger.info("This is an info message") | |
| logger.warning("This is a warning message") | |
| logger.error("This is an error message") | |
| logger.critical("This is a critical message") | |
| print("\nTesting with different module names:") | |
| api_logger = get_logger("api") | |
| api_logger.info("API logger initialized") | |
| client_logger = get_logger("client") | |
| client_logger.info("Client logger initialized") |