Fluent Bit es un procesador y reenviador de logs escrito en C, pensado para ejecutarse en cada servidor o nodo con un consumo mínimo de memoria y CPU. Lee logs de archivos, journald o la red, los analiza y filtra, y los envía a destinos como Grafana Loki, Elasticsearch o S3. En este tutorial instalarás Fluent Bit en Ubuntu 24.04 desde su repositorio oficial, lo configurarás con el formato YAML para leer los logs de Nginx y de journald, descartarás el ruido y enviarás el resultado a Loki.
Requisitos previos
Para seguir esta guía necesitas:
- Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath.
- Un usuario no root con privilegios
sudo. - Nginx instalado y sirviendo tráfico, que se usa como fuente de logs del ejemplo. Si no lo tienes, instálalo con
sudo apt install nginx. - Opcional para el paso 6: un servidor Grafana Loki accesible desde este servidor. Hasta ese paso, los eventos se envían a la salida estándar.
Paso 1: Añadir el repositorio de Fluent Bit
Los paquetes de Ubuntu no incluyen versiones recientes de Fluent Bit, así que usarás el repositorio oficial del proyecto. Descarga su clave de firma en formato binario a /etc/apt/keyrings:
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://packages.fluentbit.io/fluentbit.key | sudo gpg --dearmor -o /etc/apt/keyrings/fluentbit.gpg
Añade el repositorio para Ubuntu 24.04 (noble), limitado a esa clave:
echo "deb [signed-by=/etc/apt/keyrings/fluentbit.gpg] https://packages.fluentbit.io/ubuntu/noble noble main" | sudo tee /etc/apt/sources.list.d/fluent-bit.list
Instala el paquete:
sudo apt update
sudo apt install -y fluent-bit
El binario se instala en /opt/fluent-bit/bin/fluent-bit, fuera del PATH. Comprueba la versión:
/opt/fluent-bit/bin/fluent-bit --version
Fluent Bit v5.1.2
Paso 2: Pasar el servicio al formato YAML
El paquete instala la unidad fluent-bit.service, que arranca con /etc/fluent-bit/fluent-bit.conf en el formato clásico. Ese formato quedará obsoleto a finales de 2026, y YAML admite todo lo que admite el clásico y más, así que usarás un archivo fluent-bit.yaml. Fluent Bit elige el formato por la extensión del archivo.
Crea un override de systemd que cambie el archivo de configuración sin modificar la unidad del paquete:
sudo systemctl edit fluent-bit
En el editor, escribe lo siguiente entre las líneas de comentario que indican dónde hacerlo. La línea ExecStart= vacía es necesaria para anular el comando original antes de definir el nuevo:
[Service]
ExecStart=
ExecStart=/opt/fluent-bit/bin/fluent-bit -c /etc/fluent-bit/fluent-bit.yaml
Guarda y cierra. Crea también el directorio donde Fluent Bit guardará la posición de lectura de cada fuente:
sudo mkdir -p /var/lib/fluent-bit
La unidad no define User=, así que Fluent Bit se ejecuta como root y puede leer cualquier log del sistema sin cambiar permisos.
Paso 3: Leer y analizar los logs de Nginx
Una configuración YAML de Fluent Bit tiene tres secciones principales: service (opciones globales), parsers (cómo convertir texto en campos) y pipeline, con sus inputs, filters y outputs. Cada evento lleva una etiqueta (tag) que asigna la entrada, y filtros y salidas deciden con match a qué etiquetas se aplican.
Crea el archivo:
sudo nano /etc/fluent-bit/fluent-bit.yaml
service:
flush: 1
log_level: info
http_server: on
http_listen: 127.0.0.1
http_port: 2020
parsers:
- name: nginx_combined
format: regex
regex: '^(?<remote>[^ ]*) - (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$'
time_key: time
time_format: '%d/%b/%Y:%H:%M:%S %z'
types: code:integer size:integer
pipeline:
inputs:
- name: tail
tag: nginx.access
path: /var/log/nginx/access.log
parser: nginx_combined
db: /var/lib/fluent-bit/nginx-access.db
mem_buf_limit: 10MB
skip_long_lines: on
outputs:
- name: stdout
match: '*'
format: json_lines
Qué hace cada parte:
http_serveractiva el servidor de monitorización de Fluent Bit en127.0.0.1:2020, solo accesible localmente.- El parser
nginx_combinedsepara el formato de log por defecto de Nginx en campos, usa la hora de la petición como marca de tiempo del evento y conviertecodeysizeen números. - La entrada
tailsigueaccess.log. El archivodbguarda la posición de lectura, para que tras un reinicio no se repitan ni se pierdan líneas, ymem_buf_limitpausa la lectura si el destino no da abasto en lugar de consumir memoria sin límite. - La salida
stdoutimprime los eventos, que systemd guarda en el journal. Sirve para comprobar el resultado antes de configurar un destino real.
Valida la configuración con --dry-run, que la carga y comprueba sin arrancar el pipeline:
sudo /opt/fluent-bit/bin/fluent-bit -c /etc/fluent-bit/fluent-bit.yaml --dry-run
configuration test is successful
Reinicia el servicio para aplicar el override y la nueva configuración:
sudo systemctl restart fluent-bit
sudo systemctl status fluent-bit --no-pager
● fluent-bit.service - Fluent Bit
Loaded: loaded (/usr/lib/systemd/system/fluent-bit.service; enabled; preset: enabled)
Drop-In: /etc/systemd/system/fluent-bit.service.d
└─override.conf
Active: active (running) since ...
Main PID: 4121 (fluent-bit)
CGroup: /system.slice/fluent-bit.service
└─4121 /opt/fluent-bit/bin/fluent-bit -c /etc/fluent-bit/fluent-bit.yaml
La línea CGroup confirma que el servicio usa el archivo YAML.
Paso 4: Comprobar los eventos
Genera un par de peticiones a Nginx:
curl -s -o /dev/null http://localhost/
curl -s -o /dev/null http://localhost/no-existe
Consulta los últimos eventos en el journal:
sudo journalctl -u fluent-bit -n 2 --no-pager -o cat
{"date":1790331123.0,"remote":"127.0.0.1","user":"-","method":"GET","path":"/","code":200,"size":615,"referer":"-","agent":"curl/8.5.0"}
{"date":1790331124.0,"remote":"127.0.0.1","user":"-","method":"GET","path":"/no-existe","code":404,"size":162,"referer":"-","agent":"curl/8.5.0"}
Cada línea de texto se ha convertido en un registro con campos. Si en lugar de eso ves un único campo log con la línea completa, el parser no ha encajado: revisa que Nginx usa el formato combined.
También puedes consultar las métricas internas de Fluent Bit en el servidor HTTP local:
curl -s http://127.0.0.1:2020/api/v1/metrics | python3 -m json.tool
La salida muestra, por cada entrada y salida, los registros y bytes procesados, los reintentos y los errores.
Paso 5: Filtrar el ruido y añadir journald
Añade la sección filters dentro de pipeline para descartar health checks y peticiones de favicon.ico, y una segunda entrada que lea los logs de los servicios de systemd desde journald. Edita el archivo:
sudo nano /etc/fluent-bit/fluent-bit.yaml
Sustituye la sección pipeline completa por esta:
pipeline:
inputs:
- name: tail
tag: nginx.access
path: /var/log/nginx/access.log
parser: nginx_combined
db: /var/lib/fluent-bit/nginx-access.db
mem_buf_limit: 10MB
skip_long_lines: on
- name: systemd
tag: journal.*
read_from_tail: on
strip_underscores: on
db: /var/lib/fluent-bit/journal.db
filters:
- name: grep
match: nginx.access
exclude: path ^/(health|healthz|favicon\.ico)$
outputs:
- name: stdout
match: '*'
format: json_lines
Detalles de estos cambios:
- El filtro
grepelimina los registros cuyo campopathcoincide con la expresión regular. Conregexen lugar deexcludeharías lo contrario: conservar solo los que coinciden. - La entrada
systemdlee el journal. Contag: journal.*, Fluent Bit sustituye el asterisco por el nombre de la unidad (por ejemplojournal.ssh.service), lo que permite enrutar por servicio.read_from_tailevita reenviar todo el historial en el primer arranque, ystrip_underscoresconvierte campos como_SYSTEMD_UNITenSYSTEMD_UNIT.
Valida y reinicia:
sudo /opt/fluent-bit/bin/fluent-bit -c /etc/fluent-bit/fluent-bit.yaml --dry-run
sudo systemctl restart fluent-bit
Para comprobar el filtro, haz una petición a http://localhost/health y otra a http://localhost/: en el journal de fluent-bit solo debe aparecer la segunda. Para ver la entrada de journald, reinicia cualquier servicio (por ejemplo sudo systemctl restart cron) y verás sus mensajes con el campo SYSTEMD_UNIT.
Paso 6: Enviar los logs a Grafana Loki
Con los eventos correctos, sustituye la salida stdout por Loki. Cambia your_loki_host por la dirección de tu servidor Loki y your_hostname por el nombre de este servidor:
outputs:
- name: loki
match: 'nginx.*'
host: your_loki_host
port: 3100
labels: job=nginx, host=your_hostname
line_format: json
- name: loki
match: 'journal.*'
host: your_loki_host
port: 3100
labels: job=journal, host=your_hostname
label_keys: $SYSTEMD_UNIT
line_format: json
labels fija etiquetas constantes y label_keys convierte un campo del registro en etiqueta, aquí la unidad de systemd. Usa como etiquetas solo campos con pocos valores distintos: path o remote tienen miles y degradan el rendimiento de Loki, así que se quedan dentro de la línea JSON.
Comprueba que Loki responde desde este servidor antes de aplicar el cambio:
curl http://your_loki_host:3100/ready
ready
Valida, reinicia y revisa que no haya errores de envío:
sudo /opt/fluent-bit/bin/fluent-bit -c /etc/fluent-bit/fluent-bit.yaml --dry-run
sudo systemctl restart fluent-bit
sudo journalctl -u fluent-bit -n 20 --no-pager
En Grafana, las consultas {job="nginx"} y {job="journal", SYSTEMD_UNIT="ssh.service"} deberían devolver datos en unos segundos.
Consejosi Loki está en otra red, envía los logs por la red privada o pon Loki tras un proxy con TLS y autenticación. La salida
lokiadmitetls: on,http_useryhttp_passwdpara ese caso.
Solución de problemas
El servicio sigue usando fluent-bit.conf. Comprueba el override con systemctl cat fluent-bit. Deben aparecer las dos líneas ExecStart del paso 2; si no, repite sudo systemctl edit fluent-bit y reinicia.
Los registros llegan con un único campo log. El parser no coincide con el formato de las líneas. Compara una línea real de /var/log/nginx/access.log con la expresión regular; si has cambiado log_format en Nginx, adapta el parser.
Las líneas se repiten o se pierden tras un reinicio. Falta la opción db en la entrada o /var/lib/fluent-bit no existe. Sin ese archivo, tail no recuerda por dónde iba.
Errores failed to flush chunk o no upstream connections available. Fluent Bit no puede conectar con el destino. Revisa la dirección y el puerto, el firewall entre los dos servidores y la respuesta de curl http://your_loki_host:3100/ready. Fluent Bit reintenta los envíos fallidos automáticamente.
Conclusión
Tienes Fluent Bit en Ubuntu 24.04 configurado en YAML, leyendo los logs de acceso de Nginx y de journald, convirtiéndolos en registros estructurados, filtrando el ruido y enviándolos a Grafana Loki. Como siguientes pasos puedes activar el almacenamiento en disco (storage.path en service y storage.type: filesystem en las entradas) para no perder datos durante cortes largos, añadir más archivos de log con comodines en path o desplegar Fluent Bit como DaemonSet en Kubernetes con el chart de Helm oficial.
