Agregación de Logs
Centraliza logs de servicios distribuidos con ELK, Fluentd y Loki para búsqueda, alertado y troubleshooting en producción.
Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.
Visión General
La agregación de logs centraliza registros de docenas o cientos de servicios en un único sistema searchable. En lugar de hacer SSH a servidores individuales, los equipos consultan un índice unificado para tracear requests a través de microservicios, investigar errores y detectar anomalías. Herramientas como el stack ELK, Fluentd y Grafana Loki han hecho el logging centralizado accesible para cualquier tamaño de equipo.
Cuándo Usar
Usa este recurso cuando:
- El debugging requiere correlacionar logs de 5+ servicios para una única request de usuario
- Compliance manda retención de logs y storage a prueba de manipulación
- Necesitas alertado en tiempo real basado en patrones de log (spikes de error, eventos de seguridad)
- Los volúmenes de log exceden la capacidad de storage local en hosts individuales
Solución
Fluentd a Elasticsearch (Docker Compose)
version: '3'
services:
fluentd:
image: fluent/fluentd:v1.16
volumes:
- ./fluent.conf:/fluentd/etc/fluent.conf
ports:
- "24224:24224"
elasticsearch:
image: elasticsearch:8.11.0
environment:
- discovery.type=single-node
- xpack.security.enabled=false
kibana:
image: kibana:8.11.0
ports:
- "5601:5601"
# fluent.conf
<source>
@type forward
port 24224
</source>
<filter app.**>
@type parser
format json
key_name log
</filter>
<match app.**>
@type elasticsearch
host elasticsearch
port 9200
logstash_format true
logstash_prefix app
</match>
Structured Logging con Correlation IDs (Node.js)
const winston = require('winston');
const logger = winston.createLogger({
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'app.log' })
]
});
function logWithContext(req, message, meta = {}) {
logger.info(message, {
traceId: req.headers['x-trace-id'],
userId: req.user?.id,
service: 'order-service',
...meta
});
}
// Uso
logWithContext(req, 'Order placed', { orderId: '123', amount: 99.99 });
Loki Query (LogQL)
# Encontrar todos los error logs para un trace específico
{service="payment-service"}
|="error"
| json
| traceId="abc123"
# Rate de errores 500 por servicio
sum by (service) (
rate(
{level="error", status_code="500"}[5m]
)
)
Explicación
Etapas del pipeline de logs:
- Collection: Fluent Bit, Promtail o Filebeat leen archivos de log locales
- Parsing: Extraen campos estructurados de texto crudo (JSON, regex, grok)
- Enrichment: Agregan metadata — labels de pods Kubernetes, IDs de instancias AWS, trace IDs
- Buffering: Kafka o Redis absorben spikes antes de indexar
- Storage: Elasticsearch, Loki o CloudWatch Logs indexan para búsqueda
- Query: Kibana, Grafana o UIs custom para exploración
Logs estructurados vs. no estructurados:
| Tipo | Searchable? | Tamaño | Ejemplo |
|---|---|---|---|
| No estructurado | Solo regex | Grande | ERROR: user login failed |
| Estructurado | Filtros de campo | Compacto | {"level":"error","event":"login_failed"} |
Variantes
| Stack | Componentes | Ideal Para |
|---|---|---|
| ELK | Elasticsearch, Logstash, Kibana | Full-text search; analytics complejos |
| EFK | Elasticsearch, Fluentd/Bit, Kibana | Kubernetes-native; agents livianos |
| PLG | Promtail, Loki, Grafana | Costo-eficiente; indexado basado en labels |
| Splunk | Universal Forwarder, Indexer | Enterprise; dashboards pre-construidos |
| CloudWatch | AWS Agent | AWS-native; integración IAM |
Mejores Prácticas
- Incluye correlation IDs: Cada entrada de log debería tener un
traceIdvinculando el journey completo de la request. Consulta distributed tracing. - Loggea al nivel correcto: DEBUG para desarrollo; INFO para operaciones normales; ERROR para issues accionables
- No loggees secrets: Enmascara PII, tokens y passwords antes de que lleguen al sistema de agregación
- Setea políticas de retención: 30 días de storage hot para troubleshooting; 1 año de archive cold para compliance. Usa una plantilla de política de retención de datos.
- Alerta en patrones, no líneas individuales: “5 ERRORs en 1 minuto” es más accionable que una línea de log
Errores Comunes
- Loggear todo en INFO: Crea ruido que oculta issues reales; usa DEBUG apropiadamente
- Sin estandarización de timezone: Tiempos mixtos UTC y local hacen la correlación imposible
- Contexto de request faltante:
ERROR: database connection failedsin saber qué servicio o usuario es inútil - Ignorar backpressure: Agents de log que no pueden seguir el paso dropean logs silenciosamente durante spikes de tráfico
- Almacenar logs en la misma base de datos que datos de aplicación: Compite por recursos; mantiene analysts fuera de producción
Preguntas Frecuentes
P: ¿Cómo manejo costos de alto volumen de logs? R: Samplea logs DEBUG, agrega métricas en el edge, y usa tiers de storage más baratos (S3, GCS) para logs viejos.
P: ¿Debería agregar métricas o logs? R: Ambos. Métricas para dashboards y alertas. Logs para debugging y audit trails. No alertes solo con logs.
P: ¿Cómo aseguro logs agregados? R: Acceso role-based, transporte encriptado (TLS), y storage encriptado (AES-256). Trata los logs como datos sensibles. Consulta mejores prácticas de seguridad.
Recursos Relacionados
Observability Dashboards with Grafana and Prometheus
Build interactive Grafana dashboards that visualize Prometheus metrics with panels, variables, and alerts for comprehensive service observability
RecipeMetrics Collection and Alerting with Prometheus
Instrument applications and infrastructure with Prometheus metrics, configure alerting rules, and set up recording rules for efficient monitoring of service health
RecipePrometheus API Monitoring
Monitor API performance and health with Prometheus metrics, custom collectors, and alerting rules.
RecipeStructured Logging
Implement structured logging with JSON output, correlation IDs, and log aggregation for production observability.
RecipeDistributed Tracing
Trace requests across distributed microservices with OpenTelemetry, Jaeger, and Zipkin for latency debugging and performance optimization.