import logging from loguru import logger from typing import Dict, Any import sys import traceback from datetime import datetime, timezone class InterceptHandler(logging.Handler): """Intercept standard logging and route to loguru""" def emit(self, record): try: level = logger.level(record.levelname).name except ValueError: level = record.levelno frame, depth = logging.currentframe(), 2 while frame.f_code.co_filename == logging.__file__: frame = frame.f_back depth += 1 logger.opt(depth=depth, exception=record.exc_info).log( level, record.getMessage() ) def setup_logging_interceptor(): """Setup logging to intercept standard library logging""" logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True) # Silence some noisy loggers logging.getLogger("discord").setLevel(logging.WARNING) logging.getLogger("discord.http").setLevel(logging.WARNING) logging.getLogger("asyncio").setLevel(logging.WARNING) def log_character_action(character_name: str, action: str, details: Dict[str, Any] = None): """Log character-specific actions""" logger.info(f"Character {character_name}: {action}", extra={"details": details or {}}) def log_conversation_event(conversation_id: int, event: str, participants: list = None, details: Dict[str, Any] = None): """Log conversation events""" logger.info( f"Conversation {conversation_id}: {event}", extra={ "participants": participants or [], "details": details or {} } ) def log_llm_interaction(character_name: str, prompt_length: int, response_length: int, model: str, duration: float): """Log LLM API interactions""" logger.info( f"LLM interaction for {character_name}", extra={ "prompt_length": prompt_length, "response_length": response_length, "model": model, "duration": duration } ) def log_error_with_context(error: Exception, context: Dict[str, Any] = None): """Log errors with additional context""" logger.error( f"Error: {str(error)}", extra={ "error_type": type(error).__name__, "traceback": traceback.format_exc(), "context": context or {} } ) def log_database_operation(operation: str, table: str, duration: float, success: bool = True): """Log database operations""" level = "info" if success else "error" logger.log( level, f"Database {operation} on {table}", extra={ "duration": duration, "success": success } ) def log_autonomous_decision(character_name: str, decision: str, reasoning: str, context: Dict[str, Any] = None): """Log autonomous character decisions""" logger.info( f"Character {character_name} decision: {decision}", extra={ "reasoning": reasoning, "context": context or {} } ) def log_memory_operation(character_name: str, operation: str, memory_type: str, importance: float = None): """Log memory operations""" logger.info( f"Memory {operation} for {character_name}", extra={ "memory_type": memory_type, "importance": importance } ) def log_relationship_change(character_a: str, character_b: str, old_relationship: str, new_relationship: str, reason: str): """Log relationship changes between characters""" logger.info( f"Relationship change: {character_a} <-> {character_b}", extra={ "old_relationship": old_relationship, "new_relationship": new_relationship, "reason": reason } ) def create_performance_logger(): """Create a performance-focused logger""" performance_logger = logger.bind(category="performance") return performance_logger def log_system_health(component: str, status: str, metrics: Dict[str, Any] = None): """Log system health metrics""" logger.info( f"System health - {component}: {status}", extra={ "metrics": metrics or {}, "timestamp": datetime.now(timezone.utc).isoformat() } )