Guías · Nivel 3

Kibana y Elasticsearch: paneles de logs, reglas de alerta, ciclo de vida de índices con data streams y un clúster en solo lectura por disco lleno

Un panel de Kibana para los logs de Windows y Linux, una regla de tipo Elasticsearch query con su conector, una política ILM con rollover y borrado sobre un data stream propio, y el lunes en que Elasticsearch deja de aceptar logs porque el disco ha pasado la marca de flood-stage.

Qué vas a conseguir

Pasar de "los logs están en Elasticsearch" a que te avisen: un panel que el equipo abre cada mañana, una regla que manda un mensaje cuando hay demasiados inicios de sesión fallidos, los índices con fecha de caducidad automática gracias a ILM y los data streams, y la rutina para el día en que el disco se llena y Elasticsearch se pone en solo lectura.

Antes de empezar

  • Elasticsearch y Kibana 8.x funcionando, como en la guía de ELK para centralizar logs, con un usuario con permisos de administración.
  • Winlogbeat en los servidores Windows y Filebeat con el módulo system en los Linux. En 8.x escriben en los data streams winlogbeat-8.x.x y filebeat-8.x.x.
  • En kibana.yml, la clave xpack.encryptedSavedObjects.encryptionKey con al menos 32 caracteres. Sin ella, Kibana no deja crear reglas ni conectores.
  • Licencia: con Basic solo están los conectores Index y Server log. Email, Microsoft Teams o Webhook necesitan una suscripción de pago (Gold o superior) o la prueba de 30 días.

1. Un panel para los logs de Windows y Linux

Primero las vistas de datos (data views), que dicen a Kibana qué índices leer:

Kibana · Stack Management › Data Views › Create data view
NameWindows
Index patternwinlogbeat-*
Timestamp field@timestamp
Save data view to Kibana

Otra igual con filebeat-* para Linux. Después Analytics › Dashboards › Create dashboard › Create visualization y, con Lens, cuatro paneles:

PanelVistaFiltro (KQL)Gráfico
Inicios de sesión fallidosWindowsevent.code: 4625Barras por hora, top 10 de winlog.event_data.TargetUserName
Cuentas bloqueadasWindowsevent.code: 4740Tabla con hora, cuenta y host.name
SSH fallido en LinuxLinuxevent.dataset: "system.auth" and system.auth.ssh.event: "Failed"Top 10 de source.ip
Equipos que más registranAmbas(ninguno)Barras por host.name

Guarda el panel con una etiqueta (Tags: operaciones) y el intervalo Last 24 hours. El cuarto panel es el que avisa antes que nadie de un servidor con el log en modo depuración: lo vas a necesitar en el paso 6.

2. El conector

El conector es el canal por el que sale el aviso. Se crea una vez y lo usan todas las reglas:

Kibana · Stack Management › Alerts and Insights › Connectors › Create connector
Microsoft Teams
Connector nameTeams · Operaciones
Webhook URLhttps://contoso.webhook.office.com/webhookb2/...
Save & test
  • La URL del webhook la crea el propietario del canal en Teams. Trátala como una contraseña: quien la tenga puede escribir en el canal.
  • Save & test envía un mensaje de prueba. Si no llega, el servidor de Kibana no tiene salida a Internet o necesita proxy (xpack.actions.proxyUrl en kibana.yml).
  • Con licencia Basic, el conector Index escribe la alerta en un índice; útil para un panel de alertas, pero no avisa a nadie.

3. Una regla de tipo Elasticsearch query

Kibana · Stack Management › Alerts and Insights › Rules › Create rule › Elasticsearch query
NameWindows · más de 20 logons fallidos en 5 min
Query typeKQL or Lucene
Data viewWindows
Queryevent.code: 4625
Whencount() over top 5 host.name
ThresholdIS ABOVE 20
Time windowFor the last 5 minutes
Check every1 minute
Test query
ActionsTeams · Operaciones
Action frequencyOn status changes
Run whenQuery matched
Message{{rule.name}} · {{context.title}} · {{context.link}}
Create rule
  • Test query dice cuántos documentos encuentra ahora mismo. Si devuelve miles, el umbral está mal o falta un filtro.
  • On status changes manda un mensaje cuando salta y otro cuando se recupera (añade una segunda acción con Run when: Recovered), no uno cada minuto.
  • {{context.link}} lleva directo a los documentos en Discover: quien recibe el aviso no tiene que construir la búsqueda.
  • Pon nombre que diga qué pasa y dónde. "Alerta 3" a las tres de la mañana no ayuda.

4. Una política ILM con rollover y borrado

La guía anterior usaba un índice por día y una política que solo borraba. Con rollover, Elasticsearch crea un índice nuevo cuando el actual llega a un tamaño o una edad, y la fase de borrado cuenta desde ese momento. En Dev Tools:

Kibana · Dev Tools · política ILM
PUT _ilm/policy/logs-contoso-30d{  "policy": {    "phases": {      "hot": {        "actions": {          "rollover": { "max_primary_shard_size": "10gb", "max_age": "1d" }        }      },      "delete": {        "min_age": "30d",        "actions": { "delete": {} }      }    }  }}
  • max_age: 1d y max_primary_shard_size: 10gb: lo primero que se cumpla. Con poco volumen, un índice por día; si un día se dispara, se parte antes.
  • min_age: 30d en delete se mide desde el rollover: un índice vive unos 31 días.
  • Los Beats y los data streams logs-*-* usan por defecto las políticas integradas (logs, filebeat, winlogbeat), que hacen rollover pero no borran nunca. Revísalas en Stack Management › Index Lifecycle Policies y añádeles una fase de borrado, o asigna la tuya en su plantilla.

5. Un data stream propio

Un data stream es un nombre lógico (logs-contoso.servers-default) detrás del que hay índices ocultos (.ds-logs-contoso.servers-default-2026.11.03-000001). Se escribe siempre en el nombre y Elasticsearch hace el resto. Lo crea una plantilla de índice con data_stream:

Kibana · Dev Tools · plantilla del data stream
PUT _index_template/logs-contoso.servers{  "index_patterns": ["logs-contoso.servers-*"],  "data_stream": {},  "priority": 200,  "template": {    "settings": {      "index.lifecycle.name": "logs-contoso-30d",      "number_of_replicas": 0    }  }}
  • priority: 200, porque la plantilla integrada logs (patrón logs-*-*, prioridad 100) también encaja con ese nombre y gana la de prioridad más alta.
  • Los documentos necesitan @timestamp: el data stream lo exige.

En Logstash, la salida pasa de un índice con fecha al data stream:

/etc/logstash/conf.d/30-output.conf
output {  elasticsearch {    hosts => ["https://10.20.5.10:9200"]    data_stream => "true"    data_stream_type => "logs"    data_stream_dataset => "contoso.servers"    data_stream_namespace => "default"    user => "logstash_writer"    password => "${ES_PWD}"  }}

Para comprobar que la política se aplica: GET _data_stream/logs-contoso.servers-default muestra los índices y la política, y GET logs-contoso.servers-default/_ilm/explain la fase de cada uno. Un índice en ERROR en el explain es una política que no avanza y un disco que se llena.

En un data stream no se puede borrar el índice de escritura (el más reciente). Si necesitas cerrarlo, primero POST logs-contoso.servers-default/_rollover.

6. El ticket: "Kibana no muestra logs desde el sábado"

Lunes, 9:00. El panel del paso 1 está vacío desde el sábado a las 3:12. Logstash escribe esto en su log sin parar:

srv-elk-01 · journalctl -u logstash
retrying failed action with response code: 429 ({"type"=>"cluster_block_exception", "reason"=>"index [.ds-logs-contoso.servers-default-2026.11.01-000032] blocked by: [TOO_MANY_REQUESTS/12/disk usage exceeded flood-stage watermark, index has read-only-allow-delete block];"})

Elasticsearch tiene tres marcas de disco por nodo: low (85 %, deja de asignar shards nuevos), high (90 %, intenta mover shards a otro nodo) y flood-stage (95 %). Al pasar la última pone en todos los índices de ese nodo el bloqueo index.blocks.read_only_allow_delete: se puede leer y borrar, pero no escribir.

Kibana · Dev Tools
GET _cat/allocation?v&h=node,disk.percent,disk.used,disk.availnode         disk.percent disk.used disk.availsrv-elk-01             96   479.6gb     20.3gbGET _cluster/health?filter_path=status,number_of_nodes,unassigned_shards{"status":"yellow","number_of_nodes":1,"unassigned_shards":4}GET _cat/indices?v&s=store.size:desc&h=index,store.size&expand_wildcards=allindex                                                  store.size.ds-logs-contoso.servers-default-2026.11.01-000032          61.2gb.ds-logs-contoso.servers-default-2026.10.31-000031          58.7gb.ds-logs-contoso.servers-default-2026.10.04-000004           4.1gb
  • La salud del clúster sigue en amarillo, como siempre en un nodo único con réplicas pendientes. El bloqueo por disco no la pone en rojo: por eso nadie lo vio en el panel de estado.
  • Los dos últimos índices pesan quince veces lo normal. El panel de "equipos que más registran" señala a srv-app-07, que desde el viernes tiene la aplicación en nivel de log DEBUG.

Pasos:

  1. Cortar la causa: devolver el log de srv-app-07 a INFO (o parar su Filebeat mientras tanto).
  2. Liberar espacio borrando lo más antiguo que ya no se necesita. Con el bloqueo, borrar está permitido: DELETE .ds-logs-contoso.servers-default-2026.10.04-000004. Nunca borres ficheros a mano en el directorio de datos.
  3. Esperar a que se levante el bloqueo. Desde la versión 7.4, Elasticsearch quita read_only_allow_delete por sí solo cuando el disco del nodo baja de la marca high (90 %). Comprueba con GET _cat/allocation?v que estás por debajo.
  4. Si el disco ya está por debajo y los índices siguen bloqueados, quítalo a mano:
Kibana · Dev Tools · quitar el bloqueo
PUT */_settings?expand_wildcards=all{  "index.blocks.read_only_allow_delete": null}
  1. Comprobar que entra todo: Logstash reintenta los 429 por su cuenta. Mira en Discover que llegan eventos nuevos y si hay hueco. Lo que Filebeat no pudo enviar lo reintenta desde su registro; lo que se perdió, se anota en el ticket.

Subir la marca de flood-stage al 98 % para "salir del paso" solo aplaza el problema unas horas y deja el nodo sin margen. Si lo haces, vuelve a ponerla en null en cuanto liberes espacio.

Para que no se repita: la regla de Stack Monitoring Disk Usage threshold (o una regla propia sobre el disco) avisando al 80 %, la política del paso 4 con fase de borrado en todos los data streams y un tope de volumen por servidor revisado en el panel.

En el ticket: hora de inicio del bloqueo, servidor y causa del volumen, índices borrados, hora de vuelta a la normalidad y hueco de logs si lo hubo.

Siguientes pasos

  • La guía de ELK para centralizar logs cubre la instalación, el pipeline de Logstash y la búsqueda en Kibana.
  • La de Grafana sirve si el equipo prefiere tener los paneles y las alertas de Elasticsearch junto a los de otras fuentes.
  • Con más de un nodo, la fase warm de ILM mueve los índices viejos a discos más baratos, y las réplicas dejan el clúster en verde.

¿Falta algo o en tu entorno es distinto? Escríbeme y lo corrijo.

Tech Career Lab · newsletter

¿Te ha servido? Cada dos semanas envío una idea práctica para perfiles IT: LinkedIn, proyectos, networking y procesos de selección.

Apúntate y llévate las 33 ideas →