La gestión de logs en entornos distribuidos es uno de los mayores desafios operativos que enfrentan los equipos de DevOps e infraestructura. Cuando una aplicación se ejecuta en decenas o cientos de contenedores, rastrear un error a traves de logs dispersos en multiples nodos se convierte en una tarea que consume horas. La centralización de logs resuelve este problema reuniendo toda la información en un único punto de consulta, análisis y alerta.

En esta guía cubriremos la arquitectura general de una solución de logging centralizado, la implementación práctica con ELK Stack y Fluentd, la alternativa Graylog, y las mejores prácticas para entornos de producción.

Por que centralizar los logs

En una arquitectura de microservicios o distribuida, cada componente genera sus propios logs. Sin centralización, el equipo de operaciones enfrenta estos problemas:

  • Fragmentación: los logs estan repartidos en distintos servidores, contenedores o servicios cloud, lo que dificulta la correlación de eventos.
  • Falta de contexto: un error en el servicio A puede originarse por una falla en el servicio B, pero sin una vista unificada es imposible detectarlo rápidamente.
  • Cumplimiento normativo: regulaciones como GDPR, PCI-DSS o SOC 2 exigen retener logs de auditoria en un sistema centralizado con acceso controlado.
  • Análisis y alertas: solo con logs centralizados es posible configurar alertas proactivas, dashboards y busquedas ad-hoc sobre todo el ecosistema.

La centralización no es un lujo; es un requisito para cualquier organización que opere sistemas en producción con expectativas de disponibilidad razonables.

Arquitectura general de logging centralizado

Independientemente de las herramientas que elijas, una solución de logging centralizado sigue un patron de tres capas:

Capa de recolección (agentes/collectors)

Los agentes se despliegan en cada nodo o contenedor y se encargan de capturar los logs desde archivos, stdout/stderr o syslog. Las opciones mas comunes son:

  • Fluent Bit: agente ligero (escrito en C), ideal para contenedores y entornos con recursos limitados. Consume entre 1-5 MB de RAM.
  • Fluentd: mas pesado que Fluent Bit pero con un ecosistema de plugins mucho mas amplio. Escrito en Ruby y C.
  • Filebeat: parte del ecosistema Elastic, optimizado para enviar logs a Elasticsearch o Logstash.
  • Vector: alternativa moderna escrita en Rust, con excelente rendimiento y soporte para multiples destinos.

Capa de procesamiento y transformación

Los logs crudos rara vez son útiles tal como llegan. Esta capa se encarga de:

  • Parsing: extraer campos estructurados de logs en texto plano (por ejemplo, parsear una linea de access log de Nginx en campos como status_code, request_path, response_time).
  • Enriquecimiento: agregar metadatos como nombre del pod en Kubernetes, región de AWS o versión del deployment.
  • Filtrado: eliminar logs de debug en producción, redactar información sensible (tokens, IPs de usuarios).
  • Normalización: unificar formatos de timestamp, niveles de severidad y nombres de campos.

Capa de almacenamiento y consulta

Los logs procesados se almacenan en un backend optimizado para busqueda y retención:

  • Elasticsearch: motor de busqueda distribuido, el mas popular para logging. Soporta busqueda full-text y agregaciones.
  • OpenSearch: fork open source de Elasticsearch mantenido por AWS.
  • Loki: solución de Grafana Labs que indexa solo los labels (no el contenido), reduciendo costos de almacenamiento significativamente.

Implementación con ELK Stack

ELK (Elasticsearch, Logstash, Kibana) es la solución de logging centralizado mas adoptada en la industria. Veamos como configurar cada componente.

Elasticsearch: almacenamiento y busqueda

Elasticsearch actua como el motor de almacenamiento e indexación. Una configuración básica para un cluster de producción:

# elasticsearch.yml
cluster.name: logs-production
node.name: es-node-1
network.host: 0.0.0.0
discovery.seed_hosts: ["es-node-1", "es-node-2", "es-node-3"]
cluster.initial_master_nodes: ["es-node-1", "es-node-2", "es-node-3"]

# Configuracion de indices para logs
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true

Para gestionar la retención de logs, configura Index Lifecycle Management (ILM):

{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": {
            "max_size": "50gb",
            "max_age": "1d"
          }
        }
      },
      "warm": {
        "min_age": "7d",
        "actions": {
          "shrink": { "number_of_shards": 1 },
          "forcemerge": { "max_num_segments": 1 }
        }
      },
      "delete": {
        "min_age": "30d",
        "actions": { "delete": {} }
      }
    }
  }
}

Logstash: procesamiento de logs

Logstash recibe logs, los transforma y los envia a Elasticsearch. Un pipeline tipico para logs de aplicación:

# /etc/logstash/conf.d/app-logs.conf
input {
  beats {
    port => 5044
  }
}

filter {
  if [fields][type] == "nginx" {
    grok {
      match => { "message" => "%{COMBINEDAPACHELOG}" }
    }
    date {
      match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
    }
    geoip {
      source => "clientip"
    }
  }

  mutate {
    remove_field => ["agent", "ecs", "host"]
  }
}

output {
  elasticsearch {
    hosts => ["https://es-node-1:9200"]
    index => "logs-%{[fields][type]}-%{+YYYY.MM.dd}"
    user => "logstash_writer"
    password => "${ES_PASSWORD}"
  }
}

Kibana: visualización y busqueda

Kibana proporciona la interfaz web para buscar logs, crear visualizaciones y configurar alertas. Las funcionalidades clave para operaciones incluyen:

  • Discover: busqueda ad-hoc con filtros por tiempo, servicio, nivel de log y texto libre.
  • Dashboards: paneles con gráficos de volumen de logs, distribución de errores por servicio y tendencias.
  • Alertas: notificaciones cuando el volumen de errores supera un umbral o cuando aparecen patrones específicos.

Fluentd y Fluent Bit como colectores

Fluentd y Fluent Bit son las opciones mas populares para recolectar logs en entornos de contenedores, especialmente en Kubernetes.

Fluent Bit como DaemonSet en Kubernetes

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluent-bit
  namespace: logging
spec:
  selector:
    matchLabels:
      app: fluent-bit
  template:
    metadata:
      labels:
        app: fluent-bit
    spec:
      serviceAccountName: fluent-bit
      containers:
      - name: fluent-bit
        image: fluent/fluent-bit:3.1
        resources:
          limits:
            memory: 128Mi
            cpu: 200m
          requests:
            memory: 64Mi
            cpu: 100m
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: containers
          mountPath: /var/lib/docker/containers
          readOnly: true
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: containers
        hostPath:
          path: /var/lib/docker/containers

Configuración de Fluentd con multiples outputs

Fluentd permite enviar logs a distintos destinos segun el tag o contenido:

<source>
  @type forward
  port 24224
</source>

<filter kubernetes.**>
  @type kubernetes_metadata
</filter>

<match kubernetes.var.log.containers.app-**>
  @type elasticsearch
  host elasticsearch.logging.svc
  port 9200
  logstash_format true
  logstash_prefix app-logs
  <buffer>
    @type file
    path /var/log/fluentd-buffers/app
    flush_interval 5s
    retry_max_interval 30
    chunk_limit_size 8M
  </buffer>
</match>

<match kubernetes.var.log.containers.infra-**>
  @type s3
  s3_bucket infra-logs-archive
  s3_region us-east-1
  path logs/%Y/%m/%d/
  <buffer time>
    @type file
    path /var/log/fluentd-buffers/s3
    timekey 3600
    timekey_wait 10m
  </buffer>
</match>

Graylog como alternativa

Graylog es una plataforma de gestión de logs que compite directamente con ELK Stack. Usa Elasticsearch (u OpenSearch) como backend de almacenamiento pero proporciona su propia interfaz web y motor de procesamiento.

Ventajas de Graylog frente a ELK

  • Control de acceso granular: Graylog incluye RBAC nativo con permisos por stream, dashboard y busqueda.
  • Pipelines de procesamiento: reglas de transformación mas intuitivas que los filtros de Logstash.
  • Alertas integradas: sistema de alertas robusto sin necesidad de plugins adicionales.
  • Menor complejidad operativa: un solo componente a gestionar (además de Elasticsearch/MongoDB).

Caso de uso ideal

Graylog es especialmente recomendable para equipos que necesitan gestión de permisos por equipo o departamento, ya que su sistema de streams y roles es mas maduro que el de Kibana en la versión open source.

Logging estructurado: la base de todo

Independientemente de la herramienta que uses, la calidad de tu logging centralizado depende de la calidad de los logs que generas. El logging estructurado significa emitir logs en formato JSON en lugar de texto plano:

{
  "timestamp": "2025-10-22T10:15:30.123Z",
  "level": "ERROR",
  "service": "payment-api",
  "trace_id": "abc123def456",
  "message": "Failed to process payment",
  "error": "ConnectionTimeout",
  "customer_id": "cust_789",
  "amount": 150.00,
  "currency": "USD",
  "latency_ms": 5023
}

Comparado con un log no estructurado como 2025-10-22 10:15:30 ERROR - Failed to process payment for customer cust_789, el formato JSON permite busquedas precisas, agregaciones y correlación automática.

Niveles de log y cuando usarlos

  • FATAL/CRITICAL: el servicio no puede continuar operando. Requiere acción inmediata.
  • ERROR: fallo en una operación específica, pero el servicio sigue funcionando.
  • WARN: situación inesperada que no impide la operación pero merece atención.
  • INFO: eventos relevantes del ciclo de vida (inicio, shutdown, request completado).
  • DEBUG: información detallada para diagnóstico. Nunca activar en producción de forma permanente.

Políticas de retención

Los logs consumen almacenamiento de forma constante. Sin políticas de retención claras, los costos crecen de manera insostenible:

  • Hot tier (0-7 dias): discos SSD, replicas completas, busqueda rápida.
  • Warm tier (7-30 dias): discos HDD, indices reducidos (shrink), busqueda aceptable.
  • Cold tier (30-90 dias): almacenamiento en objeto (S3, GCS), acceso infrecuente.
  • Eliminación: logs mas alla del período de retención regulatorio se eliminan automáticamente.

Define la retención segun la criticidad: logs de seguridad y auditoria pueden requerir 1-7 años; logs de debug pueden eliminarse despues de 7 dias.

Patrones de logging en Kubernetes

En Kubernetes, los logs tienen caracteristicas particulares que afectan el diseño de la solución:

  • stdout/stderr: la práctica estandar es que los contenedores escriban logs a stdout/stderr. El kubelet los almacena en /var/log/containers/.
  • Sidecar pattern: para aplicaciones que escriben logs a archivos, se despliega un contenedor sidecar que lee esos archivos y los envia al sistema centralizado.
  • DaemonSet pattern: un agente (Fluent Bit, Filebeat) como DaemonSet lee los logs de todos los contenedores del nodo.
  • Labels y annotations: usa labels de Kubernetes para enriquecer los logs con metadata del pod, namespace y deployment.

Conclusion

La centralización de logs no es un proyecto de fin de semana: requiere planificación de la arquitectura, selección de herramientas adecuadas para tu escala y contexto, y definición de políticas de retención y acceso. ELK Stack sigue siendo la opción mas completa y con mayor ecosistema, Graylog ofrece una experiencia mas integrada con mejor control de acceso, y la combinación de Fluent Bit con cualquiera de estos backends es la forma mas eficiente de recolectar logs en entornos Kubernetes.

Lo mas importante: invierte tiempo en logging estructurado desde el inicio. Ningun sistema de centralización puede compensar logs mal formateados o con información insuficiente.

Recursos