--- title: "Cómo instalar Grafana Loki en Ubuntu 24.04 para tus logs" description: "Instala Grafana Loki 3 en Ubuntu 24.04 desde el repositorio APT oficial, guarda los logs 30 días, envía los de journald con Alloy y consúltalos con LogQL." category: "Stack de Observabilidad" language: es source: https://cubepath.com/es/docs/stack-de-observabilidad/instalacion-de-loki-para-agregacion-de-registros updated: 2026-09-25 --- # Cómo instalar Grafana Loki en Ubuntu 24.04 para tus logs Grafana Loki es un sistema de agregación de logs que indexa solo un pequeño conjunto de etiquetas de cada flujo de logs y guarda las líneas en sí como bloques comprimidos (chunks). Ese diseño mantiene los requisitos de almacenamiento y memoria muy por debajo de los motores de búsqueda de texto completo, a cambio de depender de las etiquetas y de filtrar en el momento de la consulta. En este tutorial instalarás Loki 3 en Ubuntu 24.04 desde el repositorio APT oficial de Grafana, lo configurarás como binario único con almacenamiento local y una retención de 30 días, le enviarás los logs de journald del servidor con Grafana Alloy y los consultarás con LogQL. ## Requisitos previos Para seguir esta guía necesitas: - Un servidor con Ubuntu 24.04 LTS y al menos 2 GB de RAM, por ejemplo un VPS de CubePath. - Un usuario no root con privilegios `sudo` y UFW activado con SSH permitido. - Espacio en disco suficiente para tu volumen de logs. Como referencia, Loki guarda los logs comprimidos a una décima parte aproximada de su tamaño original. - `curl` y `jq` instalados (`sudo apt install -y curl jq`). Esta guía cubre el servidor Loki. Para añadir encima paneles de Grafana, pipelines de procesado de logs y alertas, sigue después la guía de configuración completa de Grafana, Loki y Alloy de esta misma sección. ## Paso 1: Añadir el repositorio APT de Grafana Grafana Labs publica Loki, Alloy y Grafana como paquetes Debian en un repositorio firmado. Instala las herramientas necesarias para descargar la clave de firma: ```bash sudo apt update sudo apt install -y gpg wget ``` Descarga la clave en `/etc/apt/keyrings` y añade el repositorio, limitado a esa clave: ```bash sudo mkdir -p /etc/apt/keyrings wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list sudo apt update ``` Comprueba que apt ve el paquete de Loki en el nuevo repositorio: ```bash apt-cache policy loki ``` ```output loki: Installed: (none) Candidate: 3.x.x Version table: 3.x.x 500 500 https://apt.grafana.com stable/main amd64 Packages ``` ## Paso 2: Instalar Loki Instala el paquete: ```bash sudo apt install -y loki ``` El paquete crea un usuario de sistema `loki`, instala el binario en `/usr/bin/loki`, una configuración de ejemplo en `/etc/loki/config.yml` y una unidad de systemd `loki` que lee ese archivo. La configuración de ejemplo guarda los datos en `/tmp`, que se vacía al reiniciar, así que la sustituirás en el siguiente paso. Crea un directorio de datos persistente propiedad del usuario del servicio: ```bash sudo mkdir -p /var/lib/loki sudo chown loki:loki /var/lib/loki ``` ## Paso 3: Configurar el almacenamiento, el esquema y la retención Haz una copia del archivo de ejemplo y abre la configuración: ```bash sudo cp /etc/loki/config.yml /etc/loki/config.yml.orig sudo nano /etc/loki/config.yml ``` Sustituye su contenido por esta configuración para un único nodo: ```yaml auth_enabled: false server: http_listen_port: 3100 grpc_listen_port: 9096 log_level: info common: instance_addr: 127.0.0.1 path_prefix: /var/lib/loki storage: filesystem: chunks_directory: /var/lib/loki/chunks rules_directory: /var/lib/loki/rules replication_factor: 1 ring: kvstore: store: inmemory schema_config: configs: - from: 2024-04-01 store: tsdb object_store: filesystem schema: v13 index: prefix: index_ period: 24h limits_config: retention_period: 720h compactor: working_directory: /var/lib/loki/compactor retention_enabled: true retention_delete_delay: 2h delete_request_store: filesystem analytics: reporting_enabled: false ``` Qué hace cada bloque: - `auth_enabled: false` ejecuta Loki en modo de un solo inquilino. Los clientes no tienen que enviar la cabecera `X-Scope-OrgID`. - `common` define rutas compartidas por todos los componentes, y `inmemory` para el anillo de hash, que es lo correcto con una sola instancia. - `schema_config` usa el índice `tsdb` y el esquema `v13`, la combinación recomendada actualmente. La fecha `from` debe estar en el pasado en una instalación nueva. No edites nunca una entrada de esquema existente; para cambiarlo más adelante se añade una entrada nueva con una fecha `from` futura. - `limits_config.retention_period: 720h` conserva los logs 30 días. - El `compactor` fusiona los archivos de índice y, con `retention_enabled`, borra de verdad los chunks más antiguos que el periodo de retención. Sin él, `retention_period` no tiene efecto. - `analytics.reporting_enabled: false` desactiva el envío anónimo de estadísticas de uso a Grafana Labs. Comprueba la configuración antes de arrancar el servicio: ```bash sudo -u loki /usr/bin/loki -config.file=/etc/loki/config.yml -verify-config ``` ```output level=info ... msg="config is valid" ``` ## Paso 4: Iniciar Loki Activa el servicio y reinícialo para que cargue el nuevo archivo: ```bash sudo systemctl enable loki sudo systemctl restart loki sudo systemctl status loki ``` ```output ● loki.service - Loki service Loaded: loaded (/usr/lib/systemd/system/loki.service; enabled; preset: enabled) Active: active (running) ``` Loki tarda unos 15 segundos tras arrancar en estar listo. Consulta el endpoint de disponibilidad: ```bash curl -s http://localhost:3100/ready ``` ```output ready ``` Si responde `Ingester not ready: waiting for 15s after being ready`, espera unos segundos y vuelve a probar. Envía una línea de prueba por la API HTTP. Las marcas de tiempo son época Unix en nanosegundos, que es lo que produce `date +%s%N`: ```bash curl -s -X POST http://localhost:3100/loki/api/v1/push \ -H "Content-Type: application/json" \ --data-raw "{\"streams\":[{\"stream\":{\"job\":\"test\"},\"values\":[[\"$(date +%s%N)\",\"hola desde curl\"]]}]}" ``` Un envío correcto devuelve HTTP 204 con el cuerpo vacío. Léela con una consulta LogQL sobre la última hora, que es el rango por defecto de `query_range`: ```bash curl -s -G http://localhost:3100/loki/api/v1/query_range --data-urlencode 'query={job="test"}' | jq -r '.data.result[].values[][1]' ``` ```output hola desde curl ``` ## Paso 5: Enviar el journal del sistema con Grafana Alloy Loki solo guarda lo que los clientes le envían. Grafana Alloy es el recolector que recomienda Grafana para Loki; sustituye a Promtail, que llegó al final de su vida útil en 2026 y ya no recibe actualizaciones. Instálalo desde el mismo repositorio: ```bash sudo apt install -y alloy ``` Alloy se ejecuta con el usuario `alloy`. Añádelo al grupo `systemd-journal` para que pueda leer el journal, y a `adm` para que pueda leer más adelante archivos de `/var/log`: ```bash sudo usermod -aG systemd-journal,adm alloy ``` Abre la configuración de Alloy: ```bash sudo nano /etc/alloy/config.alloy ``` Sustituye su contenido por este pipeline, que lee el journal, convierte el nombre de la unidad de systemd en una etiqueta `unit` y lo envía todo a Loki: ```alloy loki.relabel "journal" { forward_to = [] rule { source_labels = ["__journal__systemd_unit"] target_label = "unit" } rule { source_labels = ["__journal_priority_keyword"] target_label = "level" } } loki.source.journal "system" { max_age = "12h" relabel_rules = loki.relabel.journal.rules labels = { job = "systemd-journal", host = constants.hostname } forward_to = [loki.write.local.receiver] } loki.write "local" { endpoint { url = "http://127.0.0.1:3100/loki/api/v1/push" } } ``` Los campos `__journal_*` solo existen durante el reetiquetado y se descartan después, así que a Loki solo llegan las etiquetas que copias (`unit`, `level`) más las estáticas `job` y `host`. Limita las etiquetas a valores de baja cardinalidad como estos; nunca conviertas en etiquetas identificadores de petición, de usuario ni direcciones IP. Activa Alloy y reinícialo: ```bash sudo systemctl enable alloy sudo systemctl restart alloy sudo journalctl -u alloy -n 20 --no-pager ``` El log debería mostrar los componentes arrancando sin líneas `level=error`. Pasados unos segundos, lista las etiquetas que ha recibido Loki: ```bash curl -s http://localhost:3100/loki/api/v1/labels | jq ``` ```output { "status": "success", "data": [ "host", "job", "level", "service_name", "unit" ] } ``` Loki añade `service_name` automáticamente a partir de las demás etiquetas, para usarla en las vistas de exploración de logs de Grafana. ## Paso 6: Consultar los logs con LogQL Una consulta LogQL empieza siempre con un selector de flujos entre llaves, que usa el índice para elegir flujos por etiqueta, seguido de filtros opcionales que se aplican a las líneas. Define una pequeña función para lanzar consultas desde la shell: ```bash logq() { curl -s -G http://localhost:3100/loki/api/v1/query_range --data-urlencode "query=$1" --data-urlencode "limit=${2:-20}" | jq -r '.data.result[].values[][1]'; } ``` Muestra las últimas líneas de log de SSH: ```bash logq '{job="systemd-journal", unit="ssh.service"}' ``` Quédate solo con los intentos de acceso fallidos usando un filtro de línea. `|=` significa "contiene", `!=` "no contiene" y `|~` aplica una expresión regular: ```bash logq '{unit="ssh.service"} |= "Failed password"' logq '{job="systemd-journal"} |~ "(?i)error|fail"' 50 ``` Las consultas de métricas convierten los logs en números. Esta cuenta las líneas de log por unidad en los últimos 5 minutos y usa el endpoint instantáneo `query`: ```bash curl -s -G http://localhost:3100/loki/api/v1/query \ --data-urlencode 'query=sum by (unit) (count_over_time({job="systemd-journal"}[5m]))' \ | jq -r '.data.result[] | "\(.value[1])\t\(.metric.unit)"' | sort -rn | head ``` ```output 42 cron.service 18 ssh.service 7 alloy.service ``` Las mismas consultas funcionan sin cambios en la vista Explore de Grafana en cuanto añades Loki como origen de datos. ## Paso 7: Recibir logs de otros servidores Para centralizar los logs, instala Alloy en cada servidor con la misma configuración y cambia la URL de `loki.write` a `http://your_loki_server_ip:3100/loki/api/v1/push`. Con `auth_enabled: false`, Loki no tiene autenticación, así que no expongas nunca el puerto 3100 a Internet. Permítelo solo desde los servidores que envían logs, con una regla por IP de origen: ```bash sudo ufw allow from client_server_ip to any port 3100 proto tcp ``` Para clientes fuera de una red privada, coloca Loki detrás de un proxy inverso con TLS y autenticación básica, y añade un bloque `basic_auth` al `endpoint` del `loki.write` de cada cliente. ## Solución de problemas **`systemctl status loki` muestra que se reinicia en bucle.** Ejecuta `sudo journalctl -u loki -n 50 --no-pager`. Las causas habituales son un error de sangrado en el YAML, o `permission denied` en `/var/lib/loki` si el directorio no pertenece a `loki`. **Los envíos se rechazan con `entry too far behind` o `timestamp too old`.** Por defecto Loki rechaza muestras de más de una semana. Reduce `max_age` en `loki.source.journal` si el journal es más antiguo. **Alloy registra `permission denied` al leer el journal.** El cambio de grupo solo se aplica al reiniciar el servicio. Compruébalo con `id alloy` y reinicia Alloy. **Los logs antiguos no se borran.** Confirma que `retention_enabled: true` y `delete_request_store` están en el bloque `compactor`. El borrado ocurre tras el ciclo de compactación más `retention_delete_delay`, así que cuenta con un retraso de algunas horas. **Las consultas fallan con `maximum of series (500) reached`.** La consulta selecciona demasiados flujos; acota el selector con más etiquetas. ## Conclusión Tienes una instancia de Loki 3 de un solo nodo en Ubuntu 24.04 que guarda los logs en el disco local, los borra a los 30 días y recibe el journal del sistema a través de Grafana Alloy, con LogQL disponible por la API HTTP. A partir de aquí puedes añadir Grafana para explorar y graficar los logs, procesar logs de aplicaciones como los de acceso de Nginx para extraer campos con las etapas `loki.process` de Alloy y mover el almacenamiento de chunks a un bucket compatible con S3 cuando el volumen supere lo que cabe en un disco local.