File size: 2,923 Bytes
8ca0bfb
 
 
 
 
 
 
 
 
 
6cab750
8ca0bfb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# FILE: api/utils/debug_utils.py
# DESCRIPTION: A utility for detailed function logging and debugging.

import os
import functools
import logging
import torch

# Define o nível de log. Mude para "INFO" para desativar os logs detalhados.
# Você pode controlar isso com uma variável de ambiente.
LOG_LEVEL = "DEBUG" #os.environ.get("ADUC_LOG_LEVEL", "DEBUG").upper()
logging.basicConfig(level=LOG_LEVEL, format='[%(levelname)s] [%(name)s] %(message)s')
logger = logging.getLogger("AducDebug")


def _format_value(value):
    """Formata os valores dos argumentos para uma exibição concisa e informativa."""
    if isinstance(value, torch.Tensor):
        return f"Tensor(shape={list(value.shape)}, device='{value.device}', dtype={value.dtype})"
    if isinstance(value, str) and len(value) > 70:
        return f"'{value[:70]}...'"
    if isinstance(value, list) and len(value) > 5:
        return f"List(len={len(value)})"
    if isinstance(value, dict) and len(value.keys()) > 5:
        return f"Dict(keys={list(value.keys())[:5]}...)"
    return repr(value)

def log_function_io(func):
    """
    Um decorador que registra as entradas, saídas e exceções de uma função.
    Ele é ativado apenas se o nível de log estiver definido como DEBUG.
    """
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        # Só executa a lógica de log se o nível for DEBUG
        if logger.isEnabledFor(logging.DEBUG):
            # Obtém o nome do módulo e da função
            func_name = f"{func.__module__}.{func.__name__}"
            
            # Formata os argumentos de entrada
            args_repr = [_format_value(a) for a in args]
            kwargs_repr = {k: _format_value(v) for k, v in kwargs.items()}
            signature = ", ".join(args_repr + [f"{k}={v}" for k, v in kwargs_repr.items()])

            # Log de Entrada
            logger.debug(f"================ INÍCIO: {func_name} ================")
            logger.debug(f"  -> ENTRADA: ({signature})")

            try:
                # Executa a função original
                result = func(*args, **kwargs)
                
                # Formata e registra o resultado
                result_repr = _format_value(result)
                logger.debug(f"  <- SAÍDA: {result_repr}")
                
            except Exception as e:
                # Registra qualquer exceção que ocorra
                logger.error(f"  <-- ERRO em {func_name}: {e}", exc_info=True)
                raise  # Re-lança a exceção para não alterar o comportamento do programa
            finally:
                # Log de Fim
                logger.debug(f"================ FIM: {func_name} ================\n")
            
            return result
        else:
            # Se o log não estiver em modo DEBUG, executa a função sem nenhum overhead.
            return func(*args, **kwargs)
            
    return wrapper