Envío de Logs con Filebeat a Elasticsearch
Filebeat es el agente ligero de Elastic para el envío de logs desde servidores hacia Elasticsearch o Logstash. Con sus módulos predefinidos para los servicios más comunes (Nginx, Apache, MySQL, PostgreSQL, systemd) y la posibilidad de definir inputs personalizados, Filebeat simplifica la configuración del pipeline de logs y añade capacidades de parsing y enriquecimiento antes de indexar los datos en Elasticsearch.
Requisitos Previos
- Ubuntu 22.04/20.04, Debian 11, o CentOS/Rocky Linux 8+
- Elasticsearch 8.x y Kibana accesibles en red
- El usuario que ejecuta Filebeat debe tener permisos de lectura en los archivos de log
- Espacio en disco suficiente para el buffer interno de Filebeat
Instalación de Filebeat
# Agregar el repositorio de Elastic (Ubuntu/Debian)
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | apt-key add -
echo "deb https://artifacts.elastic.co/packages/8.x/apt stable main" \
| tee /etc/apt/sources.list.d/elastic-8.x.list
apt update && apt install -y filebeat
# Para CentOS/Rocky Linux
rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch
cat > /etc/yum.repos.d/elastic.repo << 'EOF'
[elasticsearch]
name=Elasticsearch repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
EOF
yum install -y filebeat
# Verificar la instalación
filebeat version
Configuración de Inputs Personalizados
El archivo principal de configuración es /etc/filebeat/filebeat.yml.
cat > /etc/filebeat/filebeat.yml << 'EOF'
# ================ Filebeat Inputs ================
filebeat.inputs:
# Input tipo log: recopilar archivos de log
- type: filestream # Reemplaza al tipo "log" en versiones modernas
id: nginx-access-logs
enabled: true
paths:
- /var/log/nginx/access.log
tags: ["nginx", "access", "produccion"]
fields:
service: nginx
environment: produccion
datacenter: eu-west-1
fields_under_root: true # Mover los fields al nivel raíz del documento
- type: filestream
id: nginx-error-logs
enabled: true
paths:
- /var/log/nginx/error.log
tags: ["nginx", "error"]
fields:
service: nginx
log_type: error
fields_under_root: true
# Input para la aplicación personalizada (logs JSON)
- type: filestream
id: mi-aplicacion
enabled: true
paths:
- /var/log/mi_aplicacion/*.log
tags: ["mi_aplicacion"]
# Parsear logs JSON directamente en Filebeat
parsers:
- ndjson:
target: "" # Mover los campos al nivel raíz
add_error_key: true
overwrite_keys: true
# Input del journal de systemd
- type: journald
id: systemd-journal
enabled: true
seek: cursor
units:
- sshd.service
- nginx.service
- postgresql.service
tags: ["systemd"]
# ================ Output a Elasticsearch ================
output.elasticsearch:
hosts: ["https://elasticsearch.miempresa.com:9200"]
username: "filebeat_writer"
password: "contraseña-segura"
# Usar SSL/TLS
ssl.certificate_authorities: ["/etc/filebeat/certs/ca.crt"]
ssl.certificate: "/etc/filebeat/certs/filebeat.crt"
ssl.key: "/etc/filebeat/certs/filebeat.key"
# Índice donde escribir los logs
index: "logs-%{[fields.service]}-%{+yyyy.MM.dd}"
# Número de workers de salida
worker: 2
# Tamaño del lote de documentos por petición bulk
bulk_max_size: 1000
# Tiempo máximo de espera para enviar un lote
flush_timeout: 5s
# ================ Configuración de ILM ================
setup.ilm.enabled: true
setup.ilm.rollover_alias: "filebeat"
setup.ilm.policy_name: "filebeat-policy"
# ================ Kibana (para instalar dashboards) ================
setup.kibana:
host: "https://kibana.miempresa.com:5601"
username: "elastic"
password: "contraseña-elastic"
# ================ Logging de Filebeat ================
logging.level: warning
logging.to_files: true
logging.files:
path: /var/log/filebeat
name: filebeat
keepfiles: 7
permissions: 0644
# ================ Configuración del registro de posición ================
filebeat.registry.path: /var/lib/filebeat/registry
filebeat.registry.flush: 1s
EOF
# Verificar la configuración
filebeat test config -c /etc/filebeat/filebeat.yml
# Probar la salida a Elasticsearch
filebeat test output -c /etc/filebeat/filebeat.yml
# Iniciar el servicio
systemctl enable filebeat && systemctl start filebeat
Módulos de Filebeat
Los módulos simplifican la configuración con parsers y dashboards predefinidos.
# Listar los módulos disponibles
filebeat modules list
# Activar los módulos más comunes
filebeat modules enable nginx
filebeat modules enable system
filebeat modules enable mysql
filebeat modules enable postgresql
filebeat modules enable elasticsearch
filebeat modules enable logstash
filebeat modules enable kibana
# Ver la configuración del módulo de Nginx
cat /etc/filebeat/modules.d/nginx.yml
# Personalizar el módulo de Nginx con rutas no estándar
cat > /etc/filebeat/modules.d/nginx.yml << 'EOF'
- module: nginx
access:
enabled: true
var.paths: ["/var/log/nginx/access.log", "/var/log/nginx/*/access.log"]
error:
enabled: true
var.paths: ["/var/log/nginx/error.log", "/var/log/nginx/*/error.log"]
EOF
# Personalizar el módulo de MySQL
cat > /etc/filebeat/modules.d/mysql.yml << 'EOF'
- module: mysql
error:
enabled: true
var.paths: ["/var/log/mysql/error.log"]
slowlog:
enabled: true
var.paths: ["/var/log/mysql/slow-query.log"]
var.convert_timezone: true
EOF
# Instalar los assets de los módulos (índices, pipelines, dashboards)
filebeat setup --modules nginx,system,mysql \
-E output.elasticsearch.hosts='["https://elasticsearch:9200"]' \
-E output.elasticsearch.username=elastic \
-E output.elasticsearch.password=contraseña \
-E setup.kibana.host=https://kibana:5601
# Reiniciar Filebeat para aplicar los módulos
systemctl restart filebeat
Manejo de Logs Multilínea
# Configurar Filebeat para manejar stack traces de Java u otros logs multilínea
cat >> /etc/filebeat/filebeat.yml << 'EOF'
# Agregar este input para logs Java con stack traces
- type: filestream
id: java-aplicacion
enabled: true
paths:
- /var/log/mi-java-app/application.log
parsers:
- multiline:
type: pattern
# Una nueva entrada de log siempre empieza con timestamp ISO
pattern: '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}'
negate: true # El patrón se cumple cuando NO coincide
match: after # Las líneas sin patrón se agregan a la anterior
max_lines: 500 # Número máximo de líneas por entrada
timeout: 5s # Tiempo máximo antes de enviar el evento
EOF
# Ejemplo: log de Python con traceback multilínea
cat >> /etc/filebeat/filebeat.yml << 'EOF'
- type: filestream
id: python-app
paths:
- /var/log/python-app/app.log
parsers:
- multiline:
type: pattern
# Los tracebacks empiezan con "Traceback" y terminan con la excepción
pattern: '^(ERROR|WARNING|INFO|DEBUG|CRITICAL)\s+\d{4}-\d{2}-\d{2}'
negate: true
match: after
EOF
Procesadores y Transformaciones
# Los procesadores de Filebeat transforman los eventos antes de enviarlos
cat >> /etc/filebeat/filebeat.yml << 'EOF'
processors:
# Agregar la IP del host automáticamente
- add_host_metadata:
when.not.contains.tags: forwarded
# Agregar información del proceso que escribe el log
- add_process_metadata:
match_pids: [1]
include_fields: ["process.name", "process.pid"]
# Enriquecer con geolocalización de IPs (requiere base de datos GeoIP)
- geoip:
field: source.ip
target_field: source.geo
database_file: /etc/filebeat/GeoLite2-City.mmdb
ignore_missing: true
# Eliminar campos que no queremos indexar (para reducir tamaño)
- drop_fields:
fields: ["agent.ephemeral_id", "ecs.version"]
ignore_missing: true
# Renombrar campos
- rename:
fields:
- from: "nginx.access.remote_ip"
to: "source.ip"
- from: "nginx.access.response_code"
to: "http.response.status_code"
ignore_missing: true
# Filtrar eventos que no queremos enviar (health checks)
- drop_event:
when:
or:
- contains:
nginx.access.url: "/health"
- contains:
nginx.access.url: "/metrics"
- equals:
nginx.access.remote_ip: "127.0.0.1"
EOF
Dashboards de Kibana
# Instalar todos los dashboards predefinidos de Filebeat
filebeat setup \
--dashboards \
-E output.elasticsearch.hosts='["https://elasticsearch:9200"]' \
-E output.elasticsearch.username=elastic \
-E output.elasticsearch.password=contraseña \
-E setup.kibana.host=https://kibana:5601
# Instalar solo los índices (sin dashboards)
filebeat setup \
--index-management \
-E output.elasticsearch.hosts='["https://elasticsearch:9200"]' \
-E output.elasticsearch.username=elastic \
-E output.elasticsearch.password=contraseña
# Ver los dashboards disponibles en Kibana
# Navegar a: Kibana → Analytics → Dashboard
# Buscar "Filebeat" para ver los dashboards instalados
# Verificar que los índices se están creando correctamente
curl -s -u elastic:contraseña \
"https://elasticsearch:9200/_cat/indices/filebeat-*?v&s=index"
Ingest Node Pipelines
# Los Ingest Pipelines de Elasticsearch procesan los documentos antes de indexarlos
# Crear un pipeline personalizado para parsear logs de Nginx
curl -s -X PUT \
-H "Content-Type: application/json" \
-u elastic:contraseña \
"https://elasticsearch:9200/_ingest/pipeline/parse-nginx-logs" \
-d '{
"description": "Pipeline para parsear logs de acceso de Nginx",
"processors": [
{
"grok": {
"field": "message",
"patterns": [
"%{IPORHOST:source.ip} - %{DATA:user.name} \\[%{HTTPDATE:@timestamp}\\] \"%{WORD:http.method} %{DATA:url.original} HTTP/%{NUMBER:http.version}\" %{NUMBER:http.response.status_code:int} %{NUMBER:http.response.body.bytes:int}"
]
}
},
{
"date": {
"field": "@timestamp",
"formats": ["dd/MMM/yyyy:HH:mm:ss Z"]
}
},
{
"geoip": {
"field": "source.ip",
"target_field": "source.geo",
"ignore_missing": true
}
},
{
"remove": {
"field": "message",
"ignore_missing": true
}
}
]
}'
# Configurar Filebeat para usar el pipeline
cat >> /etc/filebeat/filebeat.yml << 'EOF'
# Usar el pipeline de ingest para los logs de Nginx
- type: filestream
id: nginx-con-pipeline
paths:
- /var/log/nginx/custom_access.log
pipeline: "parse-nginx-logs"
EOF
Solución de Problemas
Filebeat no envía logs:
# Ver los logs de Filebeat
journalctl -u filebeat -f
tail -f /var/log/filebeat/filebeat
# Verificar la conexión a Elasticsearch
filebeat test output
# Ver las métricas internas de Filebeat
curl -s http://localhost:5066/stats | jq '.filebeat.events'
# Forzar el reenvío desde el principio (CUIDADO: puede duplicar logs)
systemctl stop filebeat
rm /var/lib/filebeat/registry/filebeat/*
systemctl start filebeat
Harvester deja de leer el archivo:
# Verificar que Filebeat tiene permisos de lectura
ls -la /var/log/nginx/access.log
id filebeat
# Agregar el usuario filebeat al grupo que tiene acceso a los logs
usermod -aG adm filebeat
# Verificar que el archivo no está rotado sin notificar a Filebeat
# En /etc/logrotate.d/nginx, asegurarse de usar "copytruncate" o "postrotate/reload"
Conclusión
Filebeat proporciona un agente de recolección de logs maduro y bien integrado con el ecosistema Elastic. Sus módulos predefinidos reducen drásticamente la configuración necesaria para los servicios más comunes, mientras que los procesadores y los Ingest Pipelines permiten enriquecer y transformar los eventos antes de indexarlos. Para organizaciones que ya utilizan Elasticsearch y Kibana, Filebeat es la solución natural para completar el pipeline de observabilidad con una gestión centralizada de logs.


