Introducción a ELK (Elasticsearch, Logstash y Kibana) (parte 1)

Se trata de un gestor de logs, o eso es al menos lo que nos venden.

En realidad yo lo veo como algo mucho más genérico: una navaja suiza para gestión de datos que permite su transporte entre máquinas, procesamiento y consulta en tiempo real.

En este artículo escribiré sobre logstash para en artículos posteriores hablar de su integración con Elasticsearch y Kibana.

Cuando conozcas la potencia de ELK no sabrás como has sido capaz de vivir sin él hasta ahora.

Ventajas aplicadas a archivos de log

Con logstash no necesitas hacer una recolección de logs porque ya te la hace él, y tampoco necesitas hacer un tratamiento de los datos porque se le puede decir que te lo haga él o programarle una rutina que te actualice lo que sea en tiempo real. De esta forma en cualquier momento puedes saber lo que está pasando en tus sistemas y aplicaciones.

Se puede usar tanto para procesar logs de apache como para procesar logs de aplicaciones internas o bases de datos por lo que puedes generar informes útiles tanto para la dirección como para ti o el equipo de desarrolladores. Por ejemplo, tal como viene "de fábrica" se le puede pedir un diagrama de barras con el número de peticiones que ha hecho un cliente a tu API agrupadas cada 5 minutos.

Ahora imagínate que tienes un montón de instancias en Amazon que están constantemente creándose y destruyéndose en función de la carga pero quieres saber qué está pasando con ellas: cuando las creas configuras un logstash en ellas para que envíe los datos que te interesan a tu servidor de logs y problema solucionado. El accesorio perfecto para la descentralización de sistemas.

Cómo funciona: el sistema de plugins/

Pues como todos los programas: recibe unas entradas, las procesa y crea unas salidas. Sólo que es en sentido literal. Para ilustrarlo mira este dibujo:

En él puedes ver lo que es logstash y en los plugins en los que que tienes que pensar cuando vas a diseñar un sistema con él: entradas, codecs/filtros y salidas.

Una entrada es un plugin que utiliza logstash para extraer datos de algún sitio y pasársela al plugin de codec/filtro que devuelve otros datos y por último pasársela al plugin de salida.

Intencionalmente he juntado los codecs y los filtros en el mismo saco porque aunque esto es incorrecto, me parece más didáctico. Más adelante lo aclararé.

A estas alturas te habrás dado cuenta, y sino te lo digo yo, que lo realmente importante no es logstash sino sus plugins. En logstash todo gira alrededor de los plugins. Te puedes encontrar un listado abajo en la página de documentación.

Instalación básica

En este post me centraré más en mostrar cómo funciona logstash, no cómo se instala en producción así que ve a la página de http://logstash.net/docs/1.4.1/repositories, agrega el repositorio y ejecuta apt-get install logstash logstash-contrib. También hay paquetes para CentOS.

Si no usas Debian ni CentOS puedes ir a http://logstash.net, pinchar en el botón gordo que pone "Download" y deja el archivo en algún sitio. Necesitarás java así que instálalo con un apt-get install default-jdk.

Ejemplo de uso

Vamos a suponer que en tu site hay una nueva página llamada /my/machines.html y quieres saber si la visita alguien así que haremos que cuando aparezca una entrada con ese texto en tu archivo de log, te llegue un mensaje al correo avisándote.

Instala un apache en tu PC con un apt-get install apache2.

Vamos a la página de documentación donde están los plugins disponibles y elegimos los que nos interesan:

  • plugin de entrada: file
  • plugin para filtro: grep
  • plugin de salida: email

Pinchando en el plugin de entrada file podemos ver que para procesar los archivos de log que están en /var/log/apache2/*log debemos decirle algo como:

input {
  file {
    path = ["/var/log/apache2/*log"]
  }
}

Pinchando en el plugin para filtro grep y teniendo en cuenta que una línea de log sería algo así:

127.0.0.1 - - [20/Jul/2013:08:16:58 +0200] "POST /my/machines.html HTTP/1.1" 404 443 "-" "-"

Tendríamos que configurarlo de esta forma:

filter {
  grep {
    match = {"message", "/my/machines.html"}
  }
}

Y por último, pinchando en el plugin de salida email y suponiendo que utilizaremos una cuenta de correo de un proveedor externo para enviar los correos tenemos que poner como plugin de salida:

output {
  email {
    subject => "Nueva visita"
    to => "direccion@gmail.com"
    from => "direccion@gmail.com"
    body => "%{message}"
    via => "smtp"
    options => [
      "smtpIporHost", "smtp.gmail.com",
      "port", "587",
      "enable_ssl", "true",
      "authenticationType", "plain",
      "userName", "cuentaDeEnvio",
      "password", "contrasenyaDeCuentaDeEnvio",
      "starttls", "true"
    ]
  }
}

Cada vez que ejecutemos esto:
wget http://localhost/my/machines.html
nos aparecerá en nuestro archivo de log el acceso a esa página, logstash lo verá y nos enviará un e-mail advirtiéndolo.

Este ejemplo no es muy útil porque nadie quiere que le inunden el correo con líneas de log pero nos da una idea de lo que se puede hacer con los filtros y plugins.

En marcha

Si has seguido los pasos de arriba ya tienes instalado todo lo que necesitas así que vamos a ponerlo todo junto.

Crea un archivo llamado /etc/logstash/conf.d/logstash.conf con el contenido:

input {
  file {
    path => ["/var/log/apache2/*log"]
  }
}
filter {
  grep {
    match => {"message" => "/my/machines.html"}
  }
}
output {
  stdout {}
  email {
    subject => "Nueva visita"
    to => "direccion@gmail.com"
    from => "direccion@gmail.com"
    body => "%{message}"
    via => "smtp"
    options => [
      "smtpIporHost", "smtp.gmail.com",
      "port", "587",
      "enable_ssl", "true",
      "authenticationType", "plain",
      "userName", "cuentaDeEnvio",
      "password", "contrasenyaDeCuentaDeEnvio",
      "starttls", "true"
    ]
  }
}

Advertencias en producción

Esto es sólo un ejemplo muy didáctico para ver cómo funciona el sistema de plugins en Logstash: entrada, procesado y salida. Así que me he permitido introducir un par de incorrecciones.

El filtro grep no se usa

La forma correcta sería con el input que he descrito, sin filter y metiendo dentro del output una condición para que se envíe el e-mail cuando la línea la cumpla. Más adelante lo aclararé.

Cuando encuentra un error muchas veces Logstash se para

En el ejemplo utilizamos como salida el smtp de gmail y esto es una mala idea porque en caso de estar inaccesible mientras Logstash intenta enviar un e-mail, nos devolverá un error y se parará. Si mientras nos damos cuenta de que está parado se rotan los logs habremos "perdido" todo el procesamiento de esa información que está entre la parada y el momento de rotar los logs.

Con esto quiero decir que es siempre mejor tener un relay de correo en local configurado para reenviar los correos al relay de tu red o a tu proveedor externo.

Comentarios

Felicitaciones

Entretenido y diverso tu blog, llegué a este porque buscando una solución a una necesidad encontré elk.

Ojalá publiques la parte 2 y siguientes pronto.

Un saludo desde Santiago de Chile

David

Me gusta que sea útil

Ya tienes el siguiente post de la serie. He tardado tanto porque he querido hacer un ejemplo original y que funcione bien.

Me alegra que os sea útil a todos y comentarios como el tuyo me animan a escribir más.

Muchas gracias.