Centralización de Logs: ELK vs Fluentd vs Graylog (Guía 2026)
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.