""" Sistema de logging para o AgentPDF. Fornece logging estruturado e colorido para melhor debugging e monitoramento do sistema. """ import logging import sys from datetime import datetime from typing import Optional class ColoredFormatter(logging.Formatter): """Formatter personalizado com cores para diferentes níveis de log.""" # Códigos de cores ANSI COLORS = { 'DEBUG': '\033[36m', # Ciano 'INFO': '\033[32m', # Verde 'WARNING': '\033[33m', # Amarelo 'ERROR': '\033[31m', # Vermelho 'CRITICAL': '\033[35m', # Magenta 'RESET': '\033[0m' # Reset } def format(self, record): # Adiciona cor baseada no nível color = self.COLORS.get(record.levelname, self.COLORS['RESET']) reset = self.COLORS['RESET'] # Formato personalizado record.levelname = f"{color}{record.levelname}{reset}" return super().format(record) def setup_logger(name: str = "AgentPDF", level: str = "INFO") -> logging.Logger: """ Configura e retorna um logger personalizado. Args: name: Nome do logger level: Nível de logging (DEBUG, INFO, WARNING, ERROR, CRITICAL) Returns: logging.Logger: Logger configurado """ logger = logging.getLogger(name) # Evita duplicação de handlers if logger.handlers: return logger # Configura nível numeric_level = getattr(logging, level.upper(), logging.INFO) logger.setLevel(numeric_level) # Handler para console console_handler = logging.StreamHandler(sys.stdout) console_handler.setLevel(numeric_level) # Formatter com cores formatter = ColoredFormatter( '%(asctime)s | %(levelname)s | %(name)s | %(message)s', datefmt='%H:%M:%S' ) console_handler.setFormatter(formatter) logger.addHandler(console_handler) return logger def log_node_execution(node_name: str, status: str, details: Optional[str] = None): """ Log específico para execução de nós do LangGraph. Args: node_name: Nome do nó status: Status da execução (START, SUCCESS, ERROR) details: Detalhes adicionais """ logger = logging.getLogger("AgentPDF.Nodes") emoji_map = { "START": "🚀", "SUCCESS": "✅", "ERROR": "❌", "PROCESSING": "⚙️" } emoji = emoji_map.get(status, "📝") message = f"{emoji} {node_name} - {status}" if details: message += f" | {details}" if status == "ERROR": logger.error(message) elif status == "START" or status == "PROCESSING": logger.info(message) else: logger.info(message) def log_graph_execution(action: str, details: Optional[str] = None): """ Log específico para execução do grafo principal. Args: action: Ação sendo executada details: Detalhes adicionais """ logger = logging.getLogger("AgentPDF.Graph") message = f"🔄 {action}" if details: message += f" | {details}" logger.info(message) # Logger principal do sistema main_logger = setup_logger("AgentPDF", "INFO")