Cuando nuestro sistema de contenedores en docker comienza a crecer y crecer el sistema de logs configurado por defecto deja de ser práctico (o más bien, un infierno) sobre todo al realizar búsquedas.

Graylog es un sistema de recolección, análisis y visualización de logs basado en Elasticsearch. Con este sistema, además de poder recoger los logs de nuestros contenedores de docker para analizarlos y realizar búsquedas, podemos configurarlo para recoger logs de otros sistemas a través de protocolos como syslog, como routers o logs del sistema).

Para esto vamos a usar dos componentes: Graylog, que ya debe de estar previamente instalado y Promtail, un enrutador de logs.

En este post damos por hecho que Graylog ya lo tenemos instalando y funcionando. Si tengo tiempo escribiré también un post sobre como instalar Graylog en una VM sobre Proxmox, que es como lo tengo actualmente corriendo.

Graylog

La configuración “inicial” en Graylog para empezar a recibir logs es muy sencilla, solo es necesario crear un input para que empiece a escuchar logs en un puerto y los almacene.

Definición de Input

Creamos un Input en Graylog asociado a estos logs de Docker. Para ello desde la consola de Graylog vamos a System -> Inputs. En el menú desplegable seleccionamos GELF UDP y a continuación pulsamos en Launch new input. Podemos dejar toda la configuración por defecto, solo debemos de indicar un título.

Logspout

Antes de usar Logspout intenté configurar el driver de logs de docker para escribiera directamente en Graylog con el driver GELF. Sin embargo, me encontré con estos problemas:

Por tanto, estudiamos la posibilidad de usar un contendor para realizar esta operación, y encontramos Logspout, que entre otras cosas nos proporciona:

Configuración

Logspout de forma nativa trabaja con un servidor de syslog. Tenemos dos opciones: configurar Graylog para actuar como servidor de syslog o usar un módulo de Logspout que permita enviar los logs en formato GELF como logspout-gelf. GELF tiene mejoras respecto a syslog interesantes.

No he encontrado ninguna imagen actualizada de logspout-gelf, por lo que he partido de esta versión para crear mi propio Dockerfile con la última versión disponible en este momento, la 3.2.13. Recuerda cambiar la versión (LOGSPOUT_VERSION) y la suma de verificación (LOGSPOUT_DOWNLOAD_SHA256) a la última versión disponible.

FROM golang:alpine as build
ENV LOGSPOUT_VERSION=3.2.13
ENV LOGSPOUT_DOWNLOAD_SHA256=825f00025413dd35144a2c2f30a4371d212bf5be78dd2ff934baeef333d0131c
RUN mkdir -p /go/src
WORKDIR /go/src
VOLUME /mnt/routes
EXPOSE 80

RUN apk --no-cache add curl git gcc musl-dev
RUN curl -fSL -o logspout.tar.gz "https://github.com/gliderlabs/logspout/archive/v${LOGSPOUT_VERSION}.tar.gz" \
    && echo "$LOGSPOUT_DOWNLOAD_SHA256 *logspout.tar.gz" | sha256sum -c - \
    && tar -zxvf logspout.tar.gz \
    && rm logspout.tar.gz \
    && mkdir -p /go/src/github.com/gliderlabs/ \
    && mv logspout-${LOGSPOUT_VERSION} /go/src/github.com/gliderlabs/logspout

WORKDIR /go/src/github.com/gliderlabs/logspout
RUN echo 'import ( _ "github.com/micahhausler/logspout-gelf" )' >> /go/src/github.com/gliderlabs/logspout/modules.go
RUN go get -d -v ./...
RUN go build -v -ldflags "-X main.Version=$(cat VERSION)" -o ./bin/logspout

FROM alpine:latest
COPY --from=build /go/src/github.com/gliderlabs/logspout/bin/logspout /go/bin/logspout
ENTRYPOINT ["/go/bin/logspout"]

Y en el fichero docker-compose definimos un contenedor con la imagen del Dockerfile que hemos creado antes. Cambiamos la variable de entorno ROUTE_URIS con la dirección IP de Graylog.

version: "2.4"
services:
  logspout:
    container_name: logspout
    build: ./logspout # Folder where is the logspout-gelf Dockerfile
    volumes:
      - '/var/run/docker.sock:/var/run/docker.sock'
    environment:
      LOGSTASH_TAGS: "docker,production"
      ROUTE_URIS: "gelf://XX.XX.XX.XX:12201" # Graylog server IP and GELF UDP port configured in Graylog GUI

Arrancamos el contenedor con un docker-compose up -d.

Pruebas

Para comprobar que todo está funcionando bien volvemos a Graylog, en el apartado de Input y veremos que el input que hemos creado anteriormente ya está recibiendo mensajes.

Graylog Input

Se puede ver tráfico en el campo Network IO, lo que significa que ya están llegando mensajes. Si vamos al apartado de Search podremos ver los mensajes de logs que nos llegan.

Graylog Search

Este es un log de unos de los contendores que tengo instalados (concretamente, Nextcloud).

Graylog Extractors, Dashboards, Alerts and more

Hasta aquí hemos conseguido volcar nuestros logs a la plataforma Graylog. Ahora llega lo más interesante, configurar las herramientas propias de Graylog para explotar todos esos logs con estadísticas, dashboards, búsquedas que nos faciliten el trabajo de depuración y obtención de estadísticas, fallos, etc.

En los próximos posts iré analizando cada una de las opciones con las que podemos extraer más de este sistema de logs.