--- title: "Enviar logs a Elasticsearch con Filebeat en Ubuntu 24.04" description: "Instala Filebeat en Ubuntu 24.04, activa el módulo de Nginx, recoge logs JSON y multilínea de tu aplicación y envíalos de forma segura a Elasticsearch y Kibana." category: "Gestión de Logs" language: es source: https://cubepath.com/es/docs/gestión-de-logs/envio-de-logs-con-filebeat-a-elasticsearch updated: 2026-09-25 --- # Enviar logs a Elasticsearch con Filebeat en Ubuntu 24.04 Filebeat es el agente ligero de Elastic que lee archivos de log en el servidor y los envía a Elasticsearch o Logstash, recordando hasta dónde ha leído cada archivo para no perder ni duplicar eventos. En este tutorial instalarás Filebeat en Ubuntu 24.04, lo conectarás por HTTPS a un clúster de Elasticsearch con un usuario de permisos mínimos, activarás el módulo de Nginx y añadirás un input propio para los logs JSON y multilínea de una aplicación. Al terminar verás los eventos en Kibana. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con un usuario no root con privilegios `sudo`. - Un clúster de Elasticsearch y Kibana en funcionamiento y accesible desde el servidor (por defecto Elasticsearch escucha en el puerto `9200` y Kibana en el `5601`). - La contraseña del usuario `elastic` (o de otro superusuario) para la configuración inicial, y el certificado de la CA del clúster si usa certificados autofirmados (en una instalación estándar está en `/etc/elasticsearch/certs/http_ca.crt` del nodo de Elasticsearch). - Nginx instalado en el servidor si quieres seguir el paso del módulo de Nginx. En los ejemplos se usan estos valores de ejemplo, que debes sustituir por los tuyos: **`your_es_host`** (nombre o IP de Elasticsearch) y **`your_kibana_host`** (nombre o IP de Kibana). > Nota: Filebeat debe tener la misma versión mayor que Elasticsearch. Esta guía usa el repositorio `9.x`. Si tu clúster es 8.x, cambia `9.x` por `8.x` en el paso 1. ## Paso 1: Instalar Filebeat desde el repositorio de Elastic Importa la clave con la que Elastic firma sus paquetes y guárdala en `/etc/apt/keyrings`: ```bash sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /etc/apt/keyrings/elastic.gpg ``` Añade el repositorio, firmado con esa clave: ```bash echo "deb [signed-by=/etc/apt/keyrings/elastic.gpg] https://artifacts.elastic.co/packages/9.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-9.x.list ``` Instala el paquete: ```bash sudo apt update sudo apt install filebeat ``` Comprueba la versión instalada: ```bash filebeat version ``` ```output filebeat version 9.1.4 (amd64), libbeat 9.1.4 [...] ``` Todavía no arranques el servicio: primero hay que configurar la salida. ## Paso 2: Crear un usuario de publicación en Elasticsearch Filebeat solo necesita escribir en sus propios índices, así que no uses el superusuario `elastic` para el día a día. Crea un rol con los permisos que Elastic documenta para publicar eventos y un usuario con ese rol. Ejecuta estos comandos desde el servidor de Filebeat (curl pedirá la contraseña de `elastic`). Crea un directorio para el certificado de la CA del clúster: ```bash sudo install -d -m 0755 /etc/filebeat/certs ``` Copia en él el archivo `http_ca.crt` desde el nodo de Elasticsearch (por ejemplo con `scp`) y comprueba que está en su sitio: ```bash ls -l /etc/filebeat/certs/http_ca.crt ``` Crea el rol `filebeat_writer`: ```bash curl --cacert /etc/filebeat/certs/http_ca.crt -u elastic -X POST \ "https://your_es_host:9200/_security/role/filebeat_writer" \ -H "Content-Type: application/json" -d '{ "cluster": ["monitor", "read_ilm", "read_pipeline"], "indices": [ { "names": ["filebeat-*"], "privileges": ["create_doc", "view_index_metadata", "auto_configure"] } ] }' ``` Crea el usuario `filebeat_internal` con ese rol. Sustituye **`your_strong_password`** por una contraseña larga y única: ```bash curl --cacert /etc/filebeat/certs/http_ca.crt -u elastic -X POST \ "https://your_es_host:9200/_security/user/filebeat_internal" \ -H "Content-Type: application/json" -d '{ "password": "your_strong_password", "roles": ["filebeat_writer"] }' ``` Ambas peticiones deben responder con `{"created":true}` (o `{"role":{"created":true}}` en el caso del rol). ## Paso 3: Guardar la contraseña en el keystore de Filebeat Para no dejar la contraseña en texto plano en `filebeat.yml`, guárdala en el keystore cifrado de Filebeat: ```bash sudo filebeat keystore create sudo filebeat keystore add ES_PWD ``` El segundo comando pide el valor: introduce la contraseña de `filebeat_internal`. Comprueba que la clave existe: ```bash sudo filebeat keystore list ``` ```output ES_PWD ``` ## Paso 4: Configurar la salida a Elasticsearch Haz una copia del archivo original y ábrelo: ```bash sudo cp /etc/filebeat/filebeat.yml /etc/filebeat/filebeat.yml.orig sudo nano /etc/filebeat/filebeat.yml ``` Sustituye todo su contenido por esta configuración mínima. Los inputs propios se añadirán en el paso 7: ```yaml filebeat.inputs: [] filebeat.config.modules: path: ${path.config}/modules.d/*.yml reload.enabled: false output.elasticsearch: hosts: ["https://your_es_host:9200"] username: "filebeat_internal" password: "${ES_PWD}" ssl.certificate_authorities: ["/etc/filebeat/certs/http_ca.crt"] setup.kibana: host: "https://your_kibana_host:5601" ssl.certificate_authorities: ["/etc/filebeat/certs/http_ca.crt"] processors: - add_host_metadata: ~ ``` > Nota: si Kibana usa un certificado firmado por otra CA, o HTTP sin TLS, ajusta el bloque `setup.kibana` en consecuencia. Valida la sintaxis y la conexión con Elasticsearch: ```bash sudo filebeat test config sudo filebeat test output ``` ```output Config OK elasticsearch: https://your_es_host:9200... parse url... OK connection... parse host... OK dns lookup... OK addresses: 203.0.113.10 dial up... OK TLS... security: server's certificate chain verification is enabled handshake... OK TLS version: TLSv1.3 dial up... OK talk to server... OK version: 9.1.4 ``` Si `talk to server` falla con un error de autenticación, revisa el usuario y el valor de `ES_PWD`. ## Paso 5: Activar el módulo de Nginx Los módulos traen la ruta de los logs, un pipeline de ingesta que los parsea en Elasticsearch y dashboards de Kibana. Activa el de Nginx: ```bash sudo filebeat modules enable nginx ``` En las versiones actuales, cada conjunto de logs (fileset) del módulo viene desactivado por defecto. Abre su configuración: ```bash sudo nano /etc/filebeat/modules.d/nginx.yml ``` Activa los logs de acceso y de error. Las rutas por defecto (`/var/log/nginx/access.log*` y `/var/log/nginx/error.log*`) son las de Ubuntu, así que no hace falta indicarlas: ```yaml - module: nginx access: enabled: true error: enabled: true ``` Comprueba que el módulo aparece como activo: ```bash sudo filebeat modules list | head -5 ``` ```output Enabled: nginx Disabled: activemq ``` ## Paso 6: Cargar la plantilla de índice y los dashboards `filebeat setup` crea en Elasticsearch la plantilla de índice, la política de ciclo de vida y el flujo de datos `filebeat-*`, y carga los dashboards en Kibana. Necesita más permisos que el usuario de publicación, por lo que se ejecuta una sola vez con el superusuario, pasando las credenciales solo en la línea de comandos: ```bash sudo filebeat setup -e \ -E output.elasticsearch.username=elastic \ -E output.elasticsearch.password='your_elastic_password' ``` El proceso tarda uno o dos minutos. Al terminar deberías ver: ```output Index setup finished. Loading dashboards (Kibana must be running and reachable) Loaded dashboards ``` Carga también los pipelines de ingesta del módulo de Nginx. El usuario de publicación solo puede leerlos, no crearlos, así que este paso también va con el superusuario: ```bash sudo filebeat setup --pipelines --modules nginx \ -E output.elasticsearch.username=elastic \ -E output.elasticsearch.password='your_elastic_password' ``` ```output Loaded Ingest pipelines ``` Repite este comando cada vez que actives un módulo nuevo. > Consejo: el comando queda en el historial de la shell con la contraseña. Bórralo después con `history -d` o antepón un espacio al comando si tu shell tiene `HISTCONTROL=ignorespace` (el valor por defecto en Ubuntu es `ignoreboth`, que lo incluye). Ahora arranca Filebeat y actívalo en el arranque: ```bash sudo systemctl enable --now filebeat sudo systemctl status filebeat --no-pager ``` ```output ● filebeat.service - Filebeat sends log files to Logstash or directly to Elasticsearch. Loaded: loaded (/usr/lib/systemd/system/filebeat.service; enabled; preset: enabled) Active: active (running) since ... ``` Genera algo de tráfico en Nginx (`curl -s http://localhost > /dev/null`) y comprueba que llegan documentos: ```bash curl --cacert /etc/filebeat/certs/http_ca.crt -u elastic \ "https://your_es_host:9200/filebeat-*/_count?pretty" ``` ```output { "count" : 42, ... } ``` ## Paso 7: Añadir un input propio para logs JSON y multilínea Para logs que ningún módulo cubre se usa el input `filestream`. Cada input necesita un `id` único y estable: Filebeat lo usa para recordar la posición de lectura. Supón una aplicación que escribe una línea JSON por evento en `/var/log/myapp/app.log`, y otra en Java o Python cuyos errores ocupan varias líneas (stack traces) en `/var/log/myapp/worker.log`. Abre de nuevo `filebeat.yml`: ```bash sudo nano /etc/filebeat/filebeat.yml ``` Sustituye la línea `filebeat.inputs: []` por este bloque: ```yaml filebeat.inputs: - type: filestream id: myapp-json paths: - /var/log/myapp/app.log parsers: - ndjson: target: "" overwrite_keys: true add_error_key: true fields: service: myapp fields_under_root: true - type: filestream id: myapp-worker paths: - /var/log/myapp/worker.log parsers: - multiline: type: pattern pattern: '^\d{4}-\d{2}-\d{2}' negate: true match: after max_lines: 500 fields: service: myapp-worker fields_under_root: true processors: - drop_event: when: regexp: message: '^\S+ \S+ DEBUG ' ``` Qué hace cada parte: - `ndjson` con `target: ""` coloca los campos del JSON en la raíz del documento, y `add_error_key` marca las líneas que no son JSON válido en lugar de descartarlas. - El parser `multiline` considera que un evento nuevo empieza por una fecha `AAAA-MM-DD`; cualquier línea que no empiece así (`negate: true`) se une a la anterior (`match: after`). Así un stack trace completo llega como un solo documento. - `fields` añade un campo `service` para filtrar en Kibana, y `drop_event` descarta las líneas de nivel `DEBUG` antes de enviarlas. Adapta el `pattern` al formato de fecha de tu aplicación. Valida y reinicia: ```bash sudo filebeat test config sudo systemctl restart filebeat ``` Para probar el input JSON, escribe una línea de ejemplo: ```bash sudo mkdir -p /var/log/myapp echo '{"level":"error","msg":"pago rechazado","order_id":1234}' | sudo tee -a /var/log/myapp/app.log ``` Busca el evento en Elasticsearch: ```bash curl --cacert /etc/filebeat/certs/http_ca.crt -u elastic \ "https://your_es_host:9200/filebeat-*/_search?q=service:myapp&size=1&pretty" ``` El documento devuelto debe tener `level`, `msg` y `order_id` como campos de primer nivel. ## Paso 8: Ver los logs en Kibana Abre Kibana en el navegador y ve a **Analytics > Discover**. Selecciona la vista de datos `filebeat-*` y filtra por `service : "myapp"` o `event.module : "nginx"`. Para los dashboards del módulo, ve a **Analytics > Dashboards** y busca `nginx`. El dashboard **[Filebeat Nginx] Overview ECS** muestra peticiones por código de respuesta, URL más visitadas y origen geográfico de los clientes. ## Solución de problemas **`filebeat test output` falla con `x509: certificate signed by unknown authority`.** La ruta de `ssl.certificate_authorities` no apunta a la CA que firmó el certificado de Elasticsearch. Copia de nuevo `http_ca.crt` desde el nodo de Elasticsearch. **El servicio arranca pero no llegan eventos.** Revisa el log del servicio: ```bash sudo journalctl -u filebeat -n 50 --no-pager ``` Un error `403 Forbidden` con `action [indices:data/write/bulk]` indica que al rol le faltan permisos o que el nombre del índice no coincide con `filebeat-*`. **Un archivo ya existente no se vuelve a leer.** Filebeat guarda la posición de cada archivo en `/var/lib/filebeat/registry`. Es el comportamiento esperado: no reenvía lo que ya envió. Si necesitas reenviar todo desde el principio en un entorno de pruebas, para el servicio, borra ese directorio y arranca de nuevo, sabiendo que los eventos se duplicarán en Elasticsearch. **Los eventos multilínea llegan partidos.** El `pattern` no coincide con el inicio real de las líneas. Revisa unas líneas del log con `head` y ajusta la expresión regular. ## Conclusión Tienes Filebeat instalado desde el repositorio oficial, enviando por TLS a Elasticsearch con un usuario de permisos mínimos, los logs de Nginx parseados por su módulo y un input propio para logs JSON y multilínea. Como siguientes pasos puedes activar otros módulos (`sudo filebeat modules list` muestra los disponibles, como `system` o `mysql`), definir alertas en Kibana sobre los errores de tu aplicación o ajustar la política de ciclo de vida `filebeat` para controlar cuántos días se conservan los datos.