solo campos necesarios

This commit is contained in:
2025-10-31 18:45:02 +01:00
parent 210d23f949
commit 9755fda5ea
+21 -34
View File
@@ -36,7 +36,7 @@ class LokiLogger:
:param default_labels: etiquetas estáticas comunes (ej: {"env": "dev"})
:param timeout: timeout en segundos para la petición HTTP
:param min_level: nivel mínimo para enviar logs
:param service_name: nombre del servicio (se usará también como 'job')
:param service_name: nombre del servicio (usado como 'service_name' label)
"""
self.endpoint = endpoint
self.timeout = timeout
@@ -47,9 +47,9 @@ class LokiLogger:
raise ValueError(f"min_level debe estar en {self.ALLOWED_LEVELS}")
self.min_level = min_level
# Base labels: incluye el job automáticamente
# 🔹 Labels base (solo service_name + default_labels)
self.default_labels = dict(default_labels or {})
self.default_labels["service"] = self.service_name
self.default_labels["service_name"] = self.service_name
self._level_order = {
"TRACE": 0,
@@ -75,9 +75,9 @@ class LokiLogger:
level: str,
message: str,
labels: Optional[Dict[str, str]] = None,
metadata: Optional[Dict[str, Any]] = None,
metadata: Optional[Dict[str, Any]] = None, # mantenemos metadata por compatibilidad
) -> None:
"""Envía un log a Loki con los campos mínimos + metadata opcional."""
"""Envía un log a Loki con los campos mínimos (timestamp + message)."""
level = level.upper()
if level == "WARNING":
level = "WARN"
@@ -88,22 +88,23 @@ class LokiLogger:
if not self._should_log(level):
return
# Combinar etiquetas
final_labels = dict(self.default_labels)
# 🔸 Construimos labels: base + detected_level + custom
final_labels = {
"service_name": self.service_name,
"detected_level": level,
}
# Agrega default_labels (si existen)
final_labels.update(self.default_labels)
# Agrega labels personalizados
if labels:
final_labels.update(labels)
payload_metadata = {
"service": self.service_name,
"level": level,
}
if metadata:
payload_metadata.update(metadata)
# 🧾 El log line solo lleva timestamp y message
log_line = json.dumps({
"timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
"message": message,
**payload_metadata,
})
body = {
@@ -138,15 +139,10 @@ class LokiLogger:
self.log("ERROR", message, labels, metadata)
def exception(self, exc: Exception, labels=None, metadata=None):
"""
Registra una excepción con traceback incluido.
Uso típico dentro de un bloque try/except.
"""
"""Registra una excepción con traceback incluido."""
tb = traceback.format_exc()
message = str(exc)
metadata = metadata or {}
metadata["traceback"] = tb
self.log("ERROR", message, labels=labels, metadata=metadata)
self.log("ERROR", f"{message}\n{tb}", labels=labels)
def fatal(self, message, labels=None, metadata=None):
self.log("FATAL", message, labels, metadata)
@@ -157,17 +153,9 @@ class LokiLogger:
def unknown(self, message, labels=None, metadata=None):
self.log("UNKNOWN", message, labels, metadata)
# 🧩 Nuevo decorador
# 🧩 Decorador para capturar excepciones
def catch_exceptions(self, reraise: bool = False):
"""
Decorador que captura cualquier excepción dentro de la función,
la loguea con traceback, y opcionalmente la relanza.
Ejemplo:
@logger.catch_exceptions()
def run_job():
...
"""
"""Decorador que captura excepciones y las loguea."""
def decorator(func: Callable):
@wraps(func)
def wrapper(*args, **kwargs):
@@ -176,8 +164,7 @@ class LokiLogger:
except Exception as e:
tb = traceback.format_exc()
self.error(
f"Exception en función '{func.__name__}': {e}",
metadata={"traceback": tb},
f"Exception en función '{func.__name__}': {e}\n{tb}"
)
if reraise:
raise