Mascota Jacar — leyendo contigo Un portátil cuyos ojos siguen el cursor mientras lees.
Tecnología

Loki a escala: lecciones de logs a gran volumen

Loki a escala: lecciones de logs a gran volumen

Actualizado: 2026-05-03

Loki[1] de Grafana Labs ha ganado terreno como alternativa a Elasticsearch para logs. Su promesa — “como Prometheus pero para logs” — es atractiva: solo indexar labels, no el contenido, reduciendo drásticamente el coste de almacenamiento e indexación. Funciona muy bien para equipos medianos. A gran escala, los compromisos se notan. Este artículo recoge lecciones de operar Loki con volúmenes reales (>1 TB/día) y los patrones que evitan dolores de cabeza en producción.

Puntos clave

  • Loki indexa solo labels, no contenido: cada combinación única de label-valores genera un stream.
  • La cardinalidad explosiva es el incidente número uno — revisar nuevos labels antes de mergear cualquier cambio.
  • Separar los paths de lectura y escritura es imprescindible en escala seria; una query gorda no debe saturar la ingesta.
  • Grafana Alloy reemplaza a Promtail para deployments nuevos — un único agente para logs, métricas y trazas.
  • Saber cuándo Loki no es la herramienta adecuada (búsqueda forense profunda, compliance estricto) es tan importante como saber cómo operarlo.

El modelo Loki en 30 segundos

Loki indexa solo labels (pares clave-valor como {app="api", env="prod"}) y almacena el chunk de logs sin indexar en un object store (S3, GCS, MinIO). Las queries filtran primero por labels, luego escanean los chunks resultantes con regex o filtros de texto.

Ventajas del modelo:

  • Storage barato (S3 más compresión).
  • Ingestión rápida — no hay pipeline de parsing pesado.
  • Labels compatibles con Prometheus.

Límites del modelo:

  • Queries no-label sobre mucho volumen son lentas.
  • La cardinalidad de labels es el coste — cada combinación única genera un stream.

Cardinalidad: el asesino silencioso

El error más común es labels de alta cardinalidad. Ejemplos que no deben ser labels:

  • user_id (millones de valores).
  • request_id (único por request).
  • timestamp o cualquier valor temporal.
  • url completa sin normalizar.

Cada valor único genera un stream. 10 000 usuarios × 5 entornos × 3 servicios = 150 000 streams activos. El índice se infla, las queries se degradan, el coste de object store se dispara por el gran número de ficheros pequeños.

La regla de oro: labels para lo que filtras (app, env, cluster, severity, tenant si son pocos); contenido para lo que buscas (user_id en el mensaje, consultable con regex).

Diseño de labels sano

Patrón práctico para equipos medianos:

  • {app, env, cluster, component} — eje fijo. 50-500 combinaciones típicas.
  • {level} — log level (info/warn/error).
  • Sin IDs únicos.
  • Sin valores libres del usuario.

Con este esquema, un entorno de 50 servicios × 3 environments × 2 clusters × 5 components × 4 levels = 6 000 streams. Perfectamente manejable.

Separar read y write paths

En escala seria, un mismo proceso no puede gestionar ingestión y queries sin que interfieran. El diseño recomendado:

  • Distributor + Ingester: pipeline de escritura. Recibe logs de Promtail/Alloy, los guarda en memoria y los escribe al object store en chunks.
  • Querier + Query-frontend: pipeline de lectura. Paraleliza queries, cachea y envía resultados.
  • Compactor: proceso batch que compacta chunks periódicamente.
  • Ruler: evalúa reglas de alerta sobre logs.
  • Index Gateway: sirve el índice a las queries sin fricción si usas boltdb-shipper o TSDB.

Una query gorda no debe saturar la ingesta — esa separación es la garantía.

Promtail → Alloy

Promtail[2] era el shipper tradicional. Grafana Alloy[3] (antes Grafana Agent) lo reemplaza con un único agente que envía logs, métricas y trazas. Para deployments nuevos, Alloy es la elección correcta.

loki.source.file "logs" {
  targets = [{__path__ = "/var/log/app/*.log"}]
  forward_to = [loki.process.parse.receiver]
}

loki.process "parse" {
  forward_to = [loki.write.default.receiver]
  stage.regex {
    expression = `level=(?P<level>w+)`
  }
  stage.labels {
    values = { level = "" }
  }
}

loki.write "default" {
  endpoint {
    url = "https://loki.example.com/loki/api/v1/push"
  }
}

Menos magia, más explícito que Promtail.

Queries LogQL: patrones útiles

LogQL es el lenguaje de consulta. Queries que ofrecen el mayor valor operativo:

# Top errores por servicio en 1h
sum by (app) (count_over_time({env="prod", level="error"}[1h]))

# Latencia extraída de logs (requiere stage de parseo)
histogram_quantile(0.95,
  sum by (le) (rate(
    {app="api"}
    | json
    | unwrap duration
    | __error__=""
    [5m]
  ))
)

# Buscar patrón en una ventana
{app="api", env="prod"} |= "payment failed" | json | user_id = "12345"

Las queries eficientes siempre empiezan con un label matcher selectivo. Cada query sin label matcher actúa sobre todos los streams y puede tumbar el cluster.

Alertas sobre logs

Loki soporta reglas estilo Prometheus sobre métricas extraídas de logs:

yaml
groups:
  - name: api-errors
    rules:
      - alert: HighErrorRate
        expr: |
          sum by (app) (rate({env="prod", level="error"}[5m])) > 10
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "High error rate on {{ $labels.app }}"

Esto convierte a Loki en herramienta de alerting también. No cubre todo el rango de Elasticsearch/Kibana, pero cubre el 80% de los casos prácticos. Las alertas de Loki se integran bien con las mismas políticas de SLOs y error budgets que se definen para métricas de latencia.

Arquitectura de observabilidad con Prometheus, Loki y Grafana mostrando los flujos de métricas y logs

Cuándo Loki NO es la herramienta

Ser honesto sobre los límites ahorra frustraciones:

  • Búsqueda full-text sofisticada: Elasticsearch gana.
  • Análisis forense profundo: Splunk y Elasticsearch tienen herramientas específicas para eso.
  • Compliance estricto con auditoría integrada: Splunk Enterprise está diseñado para eso.
  • Volumen masivo con necesidad de queries ad-hoc rápidas sobre periodos largos: Loki empieza a sufrir.

Loki es excelente para “monitoring-grade logs” — logs ingestados y consultados rutinariamente con patrones conocidos. Para “investigación forense de pasado profundo”, hay opciones mejores.

Lecciones operacionales

Un año operando Loki en serio deja un conjunto de reglas claras:

  • Cardinalidad explosiva es el incidente número uno. Revisar nuevos labels antes de mergear cualquier PR.
  • Query cap y timeouts. Un usuario con una query mal construida puede tumbar el cluster entero.
  • Backup del object store. Perder el bucket es perder todos los logs.
  • Monitorear Loki con Loki es circular. Usar Prometheus más las métricas que Loki expone.
  • Rate limiting en ingesta por tenant. Un servicio que genera spam de logs no debe afectar a los demás.

La observabilidad basada en eBPF puede complementar la capa de logs de Loki con visibilidad a nivel de kernel sin necesidad de instrumentación adicional.

Conclusión

Loki es una elección sólida para logs en la mayoría de contextos cloud-native. Su diseño basado en labels ofrece ventajas enormes pero requiere disciplina — la cardinalidad mal gestionada arruina la experiencia. A escala seria, separar read/write paths, invertir en cache y compactación, y elegir bien el object store son decisiones clave. Para equipos que ya tienen Prometheus + Grafana, completar con Loki es uno de los cambios con mejor retorno en observabilidad.

¿Te ha resultado útil?
[Total: 0 · Media: 0]
  1. Loki
  2. Promtail
  3. Grafana Alloy

Escrito por

CEO - Jacar Systems

Apasionado de la tecnología, la infraestructura cloud y la inteligencia artificial. Escribe sobre DevOps, IA, plataformas y software desde Madrid.