api-admim/app/common/debug.py

63 lines
2.0 KiB
Python

# app/common/debug.py
from __future__ import annotations
import os
import builtins as _bi
from functools import lru_cache
from typing import Callable
# Chaves que aceitamos para ligar o debug (use APP_DEBUG como padrão)
_DEBUG_ENV_KEYS = ("APP_DEBUG", "DEBUG", "NOVO_INQUILINO_DEBUG")
_TRUE = {"1", "true", "yes", "on", "debug"}
@lru_cache(maxsize=1)
def debug_enabled() -> bool:
"""
Lê as variáveis de ambiente uma única vez (cache).
Prioridade: APP_DEBUG > DEBUG > NOVO_INQUILINO_DEBUG.
"""
for key in _DEBUG_ENV_KEYS:
val = os.getenv(key)
if val is not None:
return val.lower() in _TRUE
return False
def make_dbg(prefix: str) -> Callable[..., None]:
"""
Retorna uma função _dbg(msg, *args, **kwargs) que:
- formata msg somente quando debug está ON
- prefixa com [<prefix>][DEBUG]
- é NO-OP quando debug está OFF
Uso: _dbg = make_dbg("MeuModulo")
"""
if debug_enabled():
def _dbg(msg: str = "", *args, **kwargs) -> None:
if args or kwargs:
try:
msg = msg.format(*args, **kwargs)
except Exception:
# Não quebra log por erro de formatação
pass
_bi.print(f"[{prefix}][DEBUG] {msg}")
return _dbg
else:
def _dbg(*args, **kwargs) -> None:
return None
return _dbg
def make_dbg_lazy(prefix: str) -> Callable[[Callable[[], object]], None]:
"""
Versão “preguiçosa”: recebe um callable que só é executado quando o debug está ON.
Uso: _dbg_lazy(lambda: f"payload grande: {json.dumps(obj)}")
"""
if debug_enabled():
def _dbg_lazy(builder) -> None:
try:
_bi.print(f"[{prefix}][DEBUG] {builder()}")
except Exception as e:
_bi.print(f"[{prefix}][DEBUG] [lazy-error] {e}")
return _dbg_lazy
else:
def _dbg_lazy(*args, **kwargs) -> None:
return None
return _dbg_lazy