type prospector filebeat elk elastic configuracion beats docker logstash elastic-stack logstash-forwarder

prospector - Registro de aplicaciones de Docker con Filebeat y Logstash



kibana docker (6)

Aquí hay una forma de reenviar los docker logs de la ventana docker logs a la pila ELK (requiere la ventana acoplable> = 1.8 para el controlador de registro gelf):

  1. Inicie un contenedor de Logstash con el complemento de entrada gelf para leer desde gelf y enviar a un host de Elasticsearch (ES_HOST: puerto):

    docker run --rm -p 12201:12201/udp logstash / logstash -e ''input { gelf { } } output { elasticsearch { hosts => ["ES_HOST:PORT"] } }''

  2. Ahora inicie un contenedor Docker y use el controlador de registro gelf Docker . Aquí hay un ejemplo tonto:

    docker run --log-driver=gelf --log-opt gelf-address=udp://localhost:12201 busybox / /bin/sh -c ''while true; do echo "Hello $(date)"; sleep 1; done''

  3. Carga Kibana y las cosas que habrían aterrizado en los docker logs ventana docker logs ahora son visibles. El código fuente de gelf muestra que algunos campos útiles se generan para usted (hat-tip: Christophe Labouisse ): _container_id , _container_name , _image_id , _image_name , _command , _tag , _created .

Si usa docker-compose (asegúrese de usar docker-compose> = 1.5) y agregue la configuración adecuada en docker-compose.yml después de iniciar el contenedor de logstash:

log_driver: "gelf" log_opt: gelf-address: "udp://localhost:12201"

Tengo un conjunto de aplicaciones acopladas en varios servidores que intentan configurar el registro centralizado de nivel de producción con ELK. Estoy bien con la parte de ELK en sí, pero estoy un poco confundido acerca de cómo reenviar los registros a mis logstashes. Estoy tratando de usar Filebeat, debido a su característica de equilibrio de carga. También me gustaría evitar empaquetar Filebeat (o cualquier otra cosa) en todas mis dockers, y mantenerlo separado, acoplado o no.

¿Cómo puedo proceder?

He estado intentando lo siguiente. Mis Dockers inician sesión en stdout, así que con un Filebeat no acoplado configurado para leer desde stdin lo hago:

registros de la ventana acoplable -f mycontainer | ./filebeat -e -c filebeat.yml

Eso parece funcionar al principio. Los primeros registros se envían a mi logstash. El de caché supongo. Pero en algún momento se atasca y sigue enviando el mismo evento.

¿Es solo un error o me dirijo en la dirección equivocada? ¿Qué solución has configurado?



Docker le permite especificar el logDriver en uso. A esta respuesta no le importa Filebeat o el equilibrio de carga.

En una presentación, utilicé syslog para reenviar los registros a una instancia de Logstash (ELK) en el puerto 5000. El siguiente comando envía constantemente mensajes a través de syslog a Logstash:

docker run -t -d --log-driver=syslog --log-opt syslog-address=tcp://127.0.0.1:5000 ubuntu /bin/bash -c ''while true; do echo "Hello $(date)"; sleep 1; done''


Solo para ayudar a otros que necesitan hacer esto, simplemente puede usar Filebeat para enviar los registros. Utilizaría el contenedor de @ brice-argenson, pero necesitaba soporte SSL, así que fui con una instancia de Filebeat instalada localmente.

El buscador de filebeat es (repita para más contenedores):

- input_type: log paths: - /var/lib/docker/containers/<guid>/*.log document_type: docker_log fields: dockercontainer: container_name

Apesta un poco que necesita conocer los GUID, ya que podrían cambiar en las actualizaciones.

En el servidor de logstash, configure la fuente de entrada de archivos de archivo habitual para logstash, y use un filtro como este:

filter { if [type] == "docker_log" { json { source => "message" add_field => [ "received_at", "%{@timestamp}" ] add_field => [ "received_from", "%{host}" ] } mutate { rename => { "log" => "message" } } date { match => [ "time", "ISO8601" ] } } }

Esto analizará el JSON de los registros de Docker y establecerá la marca de tiempo en la que notificó Docker.

Si está leyendo los registros de la imagen de Docker de nginx, también puede agregar este filtro:

filter { if [fields][dockercontainer] == "nginx" { grok { match => { "message" => "(?m)%{IPORHOST:targethost} %{COMBINEDAPACHELOG}" } } mutate { convert => { "[bytes]" => "integer" } convert => { "[response]" => "integer" } } mutate { rename => { "bytes" => "http_streamlen" } rename => { "response" => "http_statuscode" } } } }

Los conversiones / renombramientos son opcionales, pero corrigen una omisión en la expresión COMBINEDAPACHELOG donde no se convierten estos valores en enteros, lo que hace que no estén disponibles para la agregación en Kibana.


Usando filebeat puedes simplemente canalizar la salida de los docker logs ventana docker logs como lo has descrito. El comportamiento que está viendo definitivamente suena como un error, pero también puede ser la configuración de lectura de línea parcial que lo golpea (reenvíe líneas parciales hasta que se encuentre el símbolo de nueva línea).

Un problema que veo con la tubería es una posible contrapresión en caso de que no haya logstash disponible. Si filebeat no puede enviar ningún evento, almacenará eventos internamente y en algún momento dejará de leer desde la entrada estándar. No tengo idea de cómo / si la ventana acoplable protege de la salida estándar que deja de responder. Otro problema con las tuberías podría ser el comportamiento de reinicio de filebeat + docker si está usando docker-compose. docker-compose por defecto reutiliza imágenes + estado de imagen. Por lo tanto, cuando reinicie, enviará todos los registros antiguos nuevamente (dado que el archivo de registro subyacente aún no se ha girado).

En lugar de canalizar, puede intentar leer los archivos de registro escritos por la ventana acoplable al sistema host. El controlador de registro predeterminado de la ventana acoplable es el controlador de registro json . Puede y debe configurar el controlador de registro json para realizar la rotación de registros y mantener algunos archivos antiguos (para almacenar en búfer en el disco). Ver opciones de tamaño máximo y archivo máximo. El controlador json coloca una línea de datos ''json'' para cada línea que se va a registrar. En el sistema host de la ventana acoplable, los archivos de registro se escriben en /var/lib/docker/containers/container_id/container_id-json.log. Filebeat reenviará estos archivos a logstash. Si logstash o la red deja de estar disponible o se reinicia el archivo, continúa reenviando las líneas de registro a la izquierda (los archivos dados no se han eliminado debido a la rotación del registro). No se perderán eventos. En logstash puede usar el códec o filtro json_lines para analizar las líneas json y un filtro grok para obtener más información de sus registros.

Ha habido github.com/elastic/libbeat/issues/37 sobre el uso de libbeat (utilizado por filebeat para enviar archivos de registro) para agregar un nuevo controlador de registro a la ventana acoplable. Tal vez sea posible recopilar registros a través de dockerbeat en el futuro utilizando la api de registros de la dockerbeat acoplable (aunque no estoy al tanto de ningún plan sobre la utilización de la API de registros).

El uso de syslog también es una opción. Tal vez pueda obtener algo de syslog relay en los eventos de registro de equilibrio de carga del host de la ventana acoplable. O haga que syslog escriba los archivos de registro y use filebeat para reenviarlos. Creo que rsyslog tiene al menos algún modo de conmutación por error. Puede usar logstash syslog input plugin y rsyslog para reenviar registros para logstash con soporte de conmutación por error en caso de que la instancia de logstash activa no esté disponible.


Verifiqué lo que escribió erewok arriba en un comentario:

De acuerdo con los documentos, debería poder usar un patrón como este en su prospectors.paths: /var/lib/docker/containers/*/*.log - erewok 18 de abril a las 21:03

Las guías del contenedor de la ventana acoplable, representadas como el primer ''*'', se resuelven correctamente cuando se inicia Filebeat. No sé qué pasa cuando se agregan contenedores.