Spaces:
Runtime error
Runtime error
| """ | |
| Sistema de logging para o Docling Document Processor. | |
| Este módulo configura e gerencia o sistema de logging da aplicação, | |
| incluindo rotação de arquivos e formatação consistente. | |
| """ | |
| import logging | |
| import sys | |
| from logging.handlers import RotatingFileHandler | |
| from pathlib import Path | |
| from typing import Optional | |
| import config | |
| # Flag para evitar configuração duplicada | |
| _logging_configured = False | |
| # Cache de loggers | |
| _loggers: dict[str, logging.Logger] = {} | |
| def setup_logger( | |
| name: str = "docling_space", | |
| level: int = logging.INFO, | |
| log_to_file: bool = True, | |
| log_to_console: bool = True | |
| ) -> logging.Logger: | |
| """ | |
| Configura e retorna um logger. | |
| Args: | |
| name: Nome do logger. | |
| level: Nível de logging (default: INFO). | |
| log_to_file: Se deve logar em arquivo. | |
| log_to_console: Se deve logar no console. | |
| Returns: | |
| Logger configurado. | |
| """ | |
| global _logging_configured | |
| # Se já existe no cache, retorna | |
| if name in _loggers: | |
| return _loggers[name] | |
| # Cria o logger | |
| logger = logging.getLogger(name) | |
| logger.setLevel(level) | |
| # Evita handlers duplicados | |
| if logger.handlers: | |
| return logger | |
| # Formatter | |
| formatter = logging.Formatter( | |
| config.LOG_FORMAT, | |
| datefmt=config.LOG_DATE_FORMAT | |
| ) | |
| # Handler de console | |
| if log_to_console: | |
| console_handler = logging.StreamHandler(sys.stdout) | |
| console_handler.setLevel(level) | |
| console_handler.setFormatter(formatter) | |
| logger.addHandler(console_handler) | |
| # Handler de arquivo com rotação | |
| if log_to_file: | |
| try: | |
| # Garante que o diretório existe | |
| config.LOGS_DIR.mkdir(parents=True, exist_ok=True) | |
| log_file = config.LOGS_DIR / config.LOG_FILE | |
| file_handler = RotatingFileHandler( | |
| log_file, | |
| maxBytes=config.LOG_MAX_BYTES, | |
| backupCount=config.LOG_BACKUP_COUNT, | |
| encoding="utf-8" | |
| ) | |
| file_handler.setLevel(level) | |
| file_handler.setFormatter(formatter) | |
| logger.addHandler(file_handler) | |
| except Exception as e: | |
| # Se não conseguir criar o arquivo de log, continua só com console | |
| if log_to_console: | |
| logger.warning(f"Não foi possível criar arquivo de log: {e}") | |
| # Não propaga para o root logger | |
| logger.propagate = False | |
| # Adiciona ao cache | |
| _loggers[name] = logger | |
| _logging_configured = True | |
| return logger | |
| def get_logger(name: Optional[str] = None) -> logging.Logger: | |
| """ | |
| Obtém um logger pelo nome. | |
| Se o logger não existir, cria um novo com as configurações padrão. | |
| Args: | |
| name: Nome do logger. Se None, usa "docling_space". | |
| Returns: | |
| Logger configurado. | |
| """ | |
| if name is None: | |
| name = "docling_space" | |
| # Se for um nome de módulo completo, usa apenas a última parte | |
| if "." in name: | |
| short_name = name.split(".")[-1] | |
| else: | |
| short_name = name | |
| logger_name = f"docling_space.{short_name}" | |
| if logger_name not in _loggers: | |
| return setup_logger(logger_name) | |
| return _loggers[logger_name] | |
| def log_exception( | |
| logger: logging.Logger, | |
| message: str, | |
| exc: Exception, | |
| include_traceback: bool = True | |
| ) -> None: | |
| """ | |
| Loga uma exceção com detalhes. | |
| Args: | |
| logger: Logger a usar. | |
| message: Mensagem descritiva. | |
| exc: Exceção a logar. | |
| include_traceback: Se deve incluir traceback completo. | |
| """ | |
| if include_traceback: | |
| logger.exception(f"{message}: {exc}") | |
| else: | |
| logger.error(f"{message}: {type(exc).__name__}: {exc}") | |
| def log_processing_start( | |
| logger: logging.Logger, | |
| filename: str, | |
| file_size: int | |
| ) -> None: | |
| """ | |
| Loga o início do processamento de um arquivo. | |
| Args: | |
| logger: Logger a usar. | |
| filename: Nome do arquivo. | |
| file_size: Tamanho em bytes. | |
| """ | |
| size_mb = file_size / (1024 * 1024) | |
| logger.info(f"Iniciando processamento: {filename} ({size_mb:.2f} MB)") | |
| def log_processing_complete( | |
| logger: logging.Logger, | |
| filename: str, | |
| duration_seconds: float, | |
| output_format: str | |
| ) -> None: | |
| """ | |
| Loga a conclusão do processamento de um arquivo. | |
| Args: | |
| logger: Logger a usar. | |
| filename: Nome do arquivo. | |
| duration_seconds: Tempo de processamento em segundos. | |
| output_format: Formato de saída usado. | |
| """ | |
| logger.info( | |
| f"Processamento concluído: {filename} " | |
| f"({duration_seconds:.2f}s, formato: {output_format})" | |
| ) | |
| def log_validation_error( | |
| logger: logging.Logger, | |
| filename: str, | |
| error_code: str, | |
| message: str | |
| ) -> None: | |
| """ | |
| Loga um erro de validação. | |
| Args: | |
| logger: Logger a usar. | |
| filename: Nome do arquivo. | |
| error_code: Código do erro. | |
| message: Mensagem de erro. | |
| """ | |
| logger.warning(f"Validação falhou [{error_code}] {filename}: {message}") | |
| class ProcessingLogger: | |
| """ | |
| Context manager para logging de processamento. | |
| Automaticamente loga início e fim do processamento com timing. | |
| """ | |
| def __init__( | |
| self, | |
| logger: logging.Logger, | |
| operation: str, | |
| filename: str | |
| ): | |
| self.logger = logger | |
| self.operation = operation | |
| self.filename = filename | |
| self.start_time: float = 0 | |
| def __enter__(self): | |
| import time | |
| self.start_time = time.time() | |
| self.logger.info(f"[INÍCIO] {self.operation}: {self.filename}") | |
| return self | |
| def __exit__(self, exc_type, exc_val, exc_tb): | |
| import time | |
| duration = time.time() - self.start_time | |
| if exc_type is None: | |
| self.logger.info( | |
| f"[FIM] {self.operation}: {self.filename} ({duration:.2f}s)" | |
| ) | |
| else: | |
| self.logger.error( | |
| f"[ERRO] {self.operation}: {self.filename} " | |
| f"({duration:.2f}s) - {exc_type.__name__}: {exc_val}" | |
| ) | |
| # Não suprime exceções | |
| return False | |