Logging Estructurado

Formatos, niveles, centralización y buenas prácticas para logging en sistemas distribuidos.

¿Por qué logging estructurado?

En un sistema monolítico, leer logs en texto plano puede ser suficiente. Pero en una arquitectura distribuida con decenas de servicios, los logs no estructurados se vuelven inmanejables. El logging estructurado — donde cada entrada es un objeto con campos bien definidos — es la base para poder buscar, filtrar y correlacionar eventos a escala.

Formatos de log

JSON como estándar

El formato más adoptado para logs estructurados es JSON. Cada línea de log es un objeto con campos consistentes:

{
  "timestamp": "2024-01-15T10:30:00.123Z",
  "level": "INFO",
  "service": "order-service",
  "traceId": "abc123def456",
  "message": "Orden creada exitosamente",
  "orderId": "ORD-789",
  "userId": "USR-456",
  "duration_ms": 145
}

Campos esenciales

Todo log estructurado debería incluir como mínimo:

  • timestamp: Momento exacto en formato ISO 8601 con zona horaria UTC.
  • level: Severidad del evento (DEBUG, INFO, WARN, ERROR, FATAL).
  • service: Nombre del servicio que emite el log.
  • traceId / correlationId: Identificador para correlacionar logs entre servicios.
  • message: Descripción legible del evento.

Niveles de log

Los niveles de log permiten filtrar por severidad y controlar el volumen de información:

NivelUsoEjemplo
DEBUGDetalle interno para desarrollo”Query ejecutada en 12ms”
INFOEventos normales del negocio”Orden ORD-789 creada”
WARNSituaciones anómalas no críticas”Retry #2 al servicio de pagos”
ERRORFallos que requieren atención”Timeout al conectar con DB”
FATALEl servicio no puede continuar”No se pudo iniciar el pool de conexiones”

Buenas prácticas con niveles

  • Usá INFO para eventos de negocio significativos, no para cada línea de código.
  • Reservá ERROR para situaciones que realmente necesitan intervención humana.
  • Configurá niveles dinámicamente por servicio — poder subir a DEBUG en producción sin redeploy es invaluable.
  • Evitá loguear datos sensibles (contraseñas, tokens, PII) en cualquier nivel.

Centralización de logs

El problema de los logs distribuidos

Cuando tenés 20 microservicios corriendo en múltiples instancias, los logs están dispersos en decenas de contenedores. Sin centralización, diagnosticar un problema requiere conectarse manualmente a cada instancia.

Stack de centralización

El patrón más común es el stack ELK (Elasticsearch, Logstash, Kibana) o su variante EFK (Elasticsearch, Fluentd, Kibana):

  1. Recolección: Cada servicio escribe logs a stdout/stderr. Un agente (Fluentd, Filebeat, Fluent Bit) los recolecta.
  2. Procesamiento: Los logs se parsean, enriquecen y transforman antes de almacenarse.
  3. Almacenamiento: Elasticsearch indexa los logs para búsqueda rápida.
  4. Visualización: Kibana permite buscar, filtrar y crear dashboards sobre los logs.

Alternativas modernas

  • Loki (Grafana): Almacena logs indexando solo las etiquetas, no el contenido completo. Más económico que Elasticsearch para volúmenes altos.
  • CloudWatch Logs (AWS): Solución managed para entornos AWS.
  • Datadog Logs: Plataforma SaaS con correlación automática entre logs, métricas y trazas.

Buenas prácticas

Contexto, no ruido

Cada línea de log debe aportar contexto útil. Preguntate: “Si me despierta una alerta a las 3 AM, ¿este log me ayuda a entender qué pasó?”

Correlation IDs

Propagá un traceId o correlationId en cada request que atraviese múltiples servicios. Esto permite reconstruir el flujo completo de una operación filtrando por un solo ID.

Sampling en producción

Para servicios de alto tráfico, loguear cada request puede ser costoso. Implementá sampling: logueá el 100% de errores pero solo un porcentaje de requests exitosos.

Retención y rotación

Definí políticas claras de retención:

  • Logs de ERROR/FATAL: 90 días mínimo.
  • Logs de INFO: 30 días.
  • Logs de DEBUG: Solo en ambientes de desarrollo o habilitados temporalmente.

No loguear datos sensibles

Nunca incluyas en logs: contraseñas, tokens de acceso, números de tarjeta, datos personales identificables (PII). Usá masking o redacción automática si es necesario.

Logging en la práctica

Patrón: Request logging middleware

Un middleware que loguea automáticamente cada request entrante y su respuesta:

→ REQUEST  | method=POST path=/api/orders traceId=abc123 userId=USR-456
← RESPONSE | method=POST path=/api/orders traceId=abc123 status=201 duration=145ms

Patrón: Error logging con contexto

Cuando ocurre un error, incluí todo el contexto necesario para diagnosticarlo sin necesidad de reproducirlo:

ERROR | service=payment-service traceId=abc123 orderId=ORD-789
       message="Pago rechazado por el proveedor"
       provider=stripe errorCode=card_declined
       retryCount=0 userId=USR-456

Resumen

El logging estructurado es el primer pilar de la observabilidad. Logs bien formateados, centralizados y con contexto adecuado permiten diagnosticar problemas rápidamente, entender el comportamiento del sistema y cumplir con requisitos de auditoría. La inversión en una buena estrategia de logging se paga con creces la primera vez que necesitás investigar un incidente en producción.