File size: 3,281 Bytes
5b467cd
8ca0bfb
 
 
 
 
 
 
 
a5cd3be
52a061c
 
 
 
a5cd3be
 
 
 
 
 
5450aad
3523023
5450aad
 
 
 
8ca0bfb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3523023
 
8ca0bfb
 
 
 
 
 
 
3523023
8ca0bfb
 
 
3523023
8ca0bfb
 
 
3523023
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
71
72
73
74
75
76
77
78
79
80
81
82
83
# FILE: utils/debug_utils.py
# DESCRIPTION: A utility for detailed function logging and debugging.

import os
import functools
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.
import logging
import warnings
warnings.filterwarnings("ignore", category=UserWarning)
warnings.filterwarnings("ignore", category=FutureWarning)
warnings.filterwarnings("ignore", message=".*")
from huggingface_hub import logging as ll
ll.set_verbosity_error()
ll.set_verbosity_warning()
ll.set_verbosity_info()
ll.set_verbosity_debug()

LOG_LEVEL = "DEBUG" #os.environ.get("ADUC_LOG_LEVEL", "DEBUG").upper()
logging.basicConfig(level=LOG_LEVEL, format='%(message)s')
logger = logging.getLogger("AducDebug")

logging.basicConfig(level=logging.DEBUG)
logger.setLevel(logging.DEBUG)


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"\n\n== INÍCIO: {func_name} ==========")
            logger.debug(f"\n  -> ENTRADA: \n({signature})")

            try:
                # Executa a função original
                result = func(*args, **kwargs)
                
                # Formata e registra o resultado
                result_repr = _format_value(result)
                logger.debug(f"\n\n  <- SAÍDA: \n{result_repr}")
                
            except Exception as e:
                # Registra qualquer exceção que ocorra
                logger.error(f"\n  <-- ERRO em \n{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"============================================\n\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