Resumen

Domina los logs en producción con estructura, niveles correctos y alertas accionables. Aquí se explica cómo pasar de simples prints a un sistema fiable basado en structured logging, exception tracking y una cultura de responsabilidad on call que reduce caos y acelera la respuesta ante fallos.

¿Por qué los logs en producción requieren estructura y niveles claros?

Cuando producción falla, no puedes “reiniciar y probar” como en local. Los logs deben ser moderados, útiles y siempre parseables. Con miles de máquinas y un flujo inmenso, el texto libre no escala: necesitas structured logging en JSON para que cualquier sistema pueda agregar, filtrar y analizar sin fricción.

  • Usa niveles de log: logger.info, logger.warn, logger.error, logger.fatal. Cada uno comunica severidad y urgencia.
  • Estandariza el formato: structured logging en JSON permite parsear y agregar. Evita mezclar texto libre con objetos sin estándar.
  • Priorización efectiva: busca fatal cuando el servicio cae. Trata como error lo que controlas internamente. Deja en info fallos de servicios externos que no controlas, si no impactan la disponibilidad.
  • Ejemplo de herramientas: Pino en Node facilita structured logging en JSON.

Ideas clave: - “Ser moderado con los logs” porque cuestan y pueden saturar. Aun así, cuando “todo se rompe”, los logs son tu ancla. - Sin estructura, no podrás “meterlo en ningún sistema de logs para agregar”. La estandarización es no negociable.

¿Qué ventajas aporta el structured logging en JSON?

  • Parseo confiable: cada entrada es un objeto con claves predecibles.
  • Búsquedas precisas: filtra por nivel, servicio, request-id o error-id.
  • Agregación y visualización: integra con tu pila de observabilidad sin hacks.

¿Cómo decidir el nivel correcto de cada evento?

  • Evalúa impacto en usuario y estado del servicio.
  • Define reglas claras por dominio: qué es info, warn, error, fatal en tu aplicación.
  • Mantén consistencia para que los filtros funcionen cuando más importa.

¿Cómo organizar la responsabilidad y el on call para incidentes?

La persona o equipo que despliega es quien debe estar on call. No delegues en un operador ajeno: quien tiene más contexto soluciona más rápido y mejor.

  • Recibe alertas de lo crítico y haz seguimiento de cada incidente.
  • Evita buscar a ciegas en un “stream infinito”: usa un exception tracker para errores no manejados.
  • Envía excepciones a un “bucket” especial: priorízalas y dales visibilidad.

Prácticas recomendadas: - Integraciones útiles: crear un issue en GitHub, enviar alerta a Slack, o ambas según severidad. - Usa reglas de severidad: si es crítico, que suene el teléfono; si es menor, que vaya a un backlog para revisión sin prisa. - Observa el life cycle por release: relaciona excepciones con despliegues para rastrear regresiones rápido.

¿Por qué un exception tracker cambia el juego?

  • Centraliza errores no manejados con contexto suficiente para actuar.
  • Permite reglas de alerta por severidad e impacto.
  • Prioriza: lo que llega al exception tracker merece más atención que el ruido de logs generales.

¿Qué decisiones tomar sobre exception tracking y datos sensibles?

Hay soluciones abiertas como Sentry (puedes auto-hospedar) o usar el servicio del proveedor. Considera:

  • Si lo corres en tu infraestructura y se cae, también caen las alertas: te quedas ciego.
  • Prefiere no enviar datos personales en errores: minimiza riesgo y habilita proveedores externos con tranquilidad.
  • Define una integración entre tu logger y el exception tracker para no duplicar código.

¿Cómo mapear niveles de log a Sentry sin esfuerzo extra?

Un patrón productivo: asociar niveles altos a envíos automáticos al exception tracker. Así, quien usa la librería no debe “pensarlo”.

// Ejemplo conceptual con Pino + Sentry (Node.js)
import pino from 'pino'
import * as Sentry from '@sentry/node'

Sentry.init({ dsn: process.env.SENTRY_DSN })
const logger = pino({ level: 'info' })

function log(level, msg, context = {}) {
  logger[level]({ msg, ...context })
  if (['error', 'fatal'].includes(level)) {
    Sentry.captureMessage(msg, level.toUpperCase())
  }
}

// Uso
log('info', 'servicio iniciado', { service: 'api' })
log('error', 'falló dependencia interna', { service: 'api', code: 'EDEP' })
log('fatal', 'servicio caído', { service: 'api' })

Beneficios prácticos reportados: - Menos llamadas a operaciones y más control del equipo dueño del servicio. - Alertas alineadas a quien puede arreglar el problema. - Flujo natural: logger.error y logger.fatal van a Sentry; el resto, solo a la pila de logs.

¿Tienes una práctica útil de structured logging o un flujo de on call que te funciona? Comparte tu enfoque y qué alertas realmente te ayudan a reaccionar a tiempo.