Spaces:
Running
Running
File size: 4,986 Bytes
7763bf4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
"""
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
@classmethod
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") |