Spaces:
Paused
Paused
File size: 5,796 Bytes
cdf55aa 906d397 cdf55aa 906d397 cdf55aa 906d397 cdf55aa a8fa9c8 7fcecc9 a8fa9c8 cdf55aa 906d397 cdf55aa 906d397 cdf55aa 906d397 cdf55aa 906d397 cdf55aa | 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 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | # logging_config.py - Production-ready logging configuration
import logging
import logging.handlers
import sys
import os
from typing import Optional
def setup_logging(log_level: str = "INFO", log_dir: str = "logs") -> None:
"""
Configures structured logging for the AI Lab with rotation and proper encoding.
Args:
log_level: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
log_dir: Directory for log files
"""
try:
os.makedirs(log_dir, exist_ok=True)
except Exception as e:
print(f"Error creating log directory: {e}")
sys.exit(1)
# Create formatters
detailed_formatter = logging.Formatter(
fmt="%(asctime)s [%(levelname)-8s] [%(name)-20s] %(funcName)-15s:%(lineno)-4d | %(message)s",
datefmt="%Y-%m-%d %H:%M:%S"
)
simple_formatter = logging.Formatter(
fmt="%(asctime)s [%(levelname)s] %(message)s",
datefmt="%H:%M:%S"
)
# Create handlers
handlers = []
# Rotating file handler with UTF-8 encoding
try:
file_handler = logging.handlers.RotatingFileHandler(
filename=os.path.join(log_dir, "ai_lab.log"),
maxBytes=10 * 1024 * 1024, # 10MB per file
backupCount=5, # Keep 5 backup files
encoding='utf-8',
mode='a'
)
file_handler.setFormatter(detailed_formatter)
file_handler.setLevel(getattr(logging, log_level))
handlers.append(file_handler)
except Exception as e:
print(f"Warning: Could not create file handler: {e}")
# Console handler with UTF-8 support
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(simple_formatter)
console_handler.setLevel(logging.INFO) # Console shows INFO and above
# Ensure UTF-8 encoding on Windows
if hasattr(console_handler.stream, 'reconfigure'):
console_handler.stream.reconfigure(encoding='utf-8')
handlers.append(console_handler)
# Configure root logger
root_logger = logging.getLogger()
root_logger.setLevel(getattr(logging, log_level))
# Remove any existing handlers
for handler in root_logger.handlers[:]:
root_logger.removeHandler(handler)
# Add new handlers
for handler in handlers:
root_logger.addHandler(handler)
# Configure third-party library logging levels
noisy_libraries = [
"httpx",
"urllib3",
"sentence_transformers",
"transformers",
"faiss",
"openai",
"httpcore",
"langchain"
]
for lib in noisy_libraries:
logging.getLogger(lib).setLevel(logging.WARNING)
# Log startup message
logging.info("="*60)
logging.info("AI Lab Logging System Initialized")
logging.info(f"Log Level: {log_level}")
logging.info(f"Log Directory: {os.path.abspath(log_dir)}")
logging.info("="*60)
def get_logger(name: str) -> logging.Logger:
"""
Get a logger instance for a specific module.
Args:
name: Name of the module/component
Returns:
Configured logger instance
"""
return logging.getLogger(name)
def log_exception(logger: logging.Logger, e: Exception, context: str = "") -> None:
"""
Helper function to log exceptions with full traceback.
Args:
logger: Logger instance to use
e: Exception to log
context: Additional context about where the exception occurred
"""
import traceback
error_msg = f"Exception in {context}: {str(e)}" if context else str(e)
logger.error(error_msg)
logger.debug(f"Traceback:\n{traceback.format_exc()}")
def setup_performance_logging() -> Optional[logging.Logger]:
"""
Set up a separate performance logger for tracking execution times and metrics.
Returns:
Performance logger instance
"""
perf_logger = logging.getLogger("performance")
perf_logger.setLevel(logging.DEBUG)
# Create performance log file
try:
perf_handler = logging.handlers.RotatingFileHandler(
filename=os.path.join("logs", "performance.log"),
maxBytes=5 * 1024 * 1024, # 5MB
backupCount=3,
encoding='utf-8'
)
perf_formatter = logging.Formatter(
fmt="%(asctime)s.%(msecs)03d | %(message)s",
datefmt="%Y-%m-%d %H:%M:%S"
)
perf_handler.setFormatter(perf_formatter)
perf_logger.addHandler(perf_handler)
return perf_logger
except Exception as e:
print(f"Warning: Could not create performance logger: {e}")
return None
# Context manager for timed operations
class LoggedTimer:
"""Context manager for logging operation execution time."""
def __init__(self, logger: logging.Logger, operation_name: str):
self.logger = logger
self.operation_name = operation_name
self.start_time = None
def __enter__(self):
import time
self.start_time = time.time()
self.logger.debug(f"Starting: {self.operation_name}")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
import time
elapsed = time.time() - self.start_time
if exc_type:
self.logger.error(f"Failed: {self.operation_name} after {elapsed:.2f}s - {exc_val}")
else:
self.logger.debug(f"Completed: {self.operation_name} in {elapsed:.2f}s")
# Initialize logging when module is imported (can be overridden)
if __name__ != "__main__":
# Auto-initialize with defaults when imported
try:
setup_logging()
except Exception as e:
print(f"Warning: Auto-initialization of logging failed: {e}") |