Desmitificando el ELK stack

ELK stack es un conjunto de tres herramientas casi mágicas que combinadas forman un tridente casi perfecto, su enfoque principal es poder solucionar uno de los problemas fundamentales de muchas  aplicaciones/herramientas/servicios relacionados con en el área  de tecnología y es que a pesar de la cantidad de herramientas, lenguajes de programación y servicios de nube que existen todos ellos tienen algo en común y es que escriben archivos .log (o deberían)

De quién es la culpa?

Cuando se tiene sistemas que están integrados con diferentes servicios todo lo que pueda salir mal , seguramente saldrá mal y en ese momento nace la pregunta de quién o de cual de todos los servicios es la culpa? qué funcionó mal o que no funciono como debia, generalmente lo que sucede aquí es un proceso de debug y de tratar de recrear las situaciones que generaron estos problemas donde el primer paso es ir a los logs, estos archivos inmensos con una cantidad de información y formatos que no entiende nadie y que además algunas veces no tienen contexto, entonces cómo se consulta esta información actualmente? bueno el clásico tail nunca falla o si? Ver Figura 1

Figura 1: Uso del comando tail sin grep obtenido de https://dzone.com/articles/when-you-tail-f-but-forget-to-grep-comic

El objetivo de este conjunto de herramientas es sencillo, lograr centralizar los diferentes tipos de logs que se recolectan desde diferentes herramientas para lograr poder consultar la información que están generando nuestras aplicaciones, pero además de ello un universo gigante de beneficios como la automatización, informes gráficos y eventos en tiempo real, bueno y todo esto cómo lo logra? Ver Figura 2

Figura 2: Arquitectura del funcionamiento de ELK stack tomado de https://www.amazon.com/-/es/Saurabh-Chhajed/dp/1785887157

E : Elasticsearch

Es un motor de búsqueda basada en apache Lucene una de sus principales características es que usa json por medio de RESTful API, además ofrece el beneficio de trabajar con index data sin conocer su estructura, este motor es especialmente eficiente para búsqueda con textos es uno de las herramientas más usadas por grandes empresas como Github y SoundCloud

L: Logstash

LogStash es una herramienta la cual su función principal es recolectar, analizar y parsear data con diferentes estructuras generadas por diferentes aplicaciones, este contiene una variedad de posibles configuraciones con diferentes plugins que permiten tener diferentes entradas de información y diferentes salidas como por ejemplo salida por consola o guardar esta información en una instancia de elasticsearch

K: Kibana

Kibana es la herramienta final del stack es una herramienta la cual su función es la visualización de información utilizando el poder de elasticsearch y alto rendimiento en la búsquedas de textos esto le permite a kibana no solo visualizar información si no que además  tiene un montón de características como alertas y notificaciones permitiendo con sus histogramas, geomaps, pie charts, graphs, tables y demás graficos entender mejor las grandes cantidades de volúmenes de información que son generados por las aplicaciones, esta herramienta está hecha en html y javascript y utiliza RestAPI para consumir información de elasticsearch tiene otras características adicionales pero estas si son licenciadas

Iniciamos con Logstash

Iniciare primero por la herramienta logstash si bien no es la primera del ELK si es la primera herramienta que inicia el proceso de recolección ya que su función principal es transformar y recolectar archivos o información relacionada a logs, básicamente es un daemon que constantemente está leyendo  información, transformándola y enviándola a algún lugar

Instalación

Logstash es una herramienta que corre sobre una jvm (java virtual machine) para instalar podemos dirigirnos a los archivos binarios

si tenemos una distribución basada en debian podemos seguir los siguientes comandos

wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
sudo apt-get install apt-transport-https
echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-7.1.list
sudo apt-get update && sudo apt-get install logstash

para saber que quedó instalado podemos ejecutar el comando

sudo service logstash status

y para poder saber en que carpeta quedo instalada se ejecuta el comando

whereis logstash

en mi caso quedó instalado en la carpeta usr/share

logstash: /etc/logstash /usr/share/logstash

Configuración

Logstash se compone de archivos.conf (pueden existir varios archivos) siguiendo el mismo concepto de nginx con los archivos de configuración, sin embargo estos archivos tienen su propia estructura un poco  similar a los objetos JSON componiendose inicialmente de tres pipelines como se aprecia a continuación

input {
  ...
}

filter {
  ...
}

output {
  ...
}

input

como su nombre lo indica hace parte de la lectura o carga de información que logstash debe estar frecuentemente revisando, aquí entra a jugar el concepto de plugins y los plugins son "helpers" que le ayudaran hacer el trabajo más fácil a logstash entre estos plugins de entrada podemos encontrar

  • file  lee información de archivos y detecta "rotación" en cada línea de este archivo
  • redis lee información generada desde una instancia de redis
  • stdin lee información de un de input de entrada por consola
  • s3 lee información alojada en el servicios AWS S3

como en mi caso quiero leer información de un archivo por ende voy a utilizar el plugin file, como se aprecia en el siguiente ejemplo

input {
 
file {
    path => "shopapp/logFile.log"
    start_position => "begining"
    tags => ["backend]
    type => "Shop App"
}

}

aquí estoy usando algunos componentes que describire a continuacion

  • path contiene la locación en donde se encuentra el archivo del cual requiero recolectar información
  • start_position es la linea donde empezará a leer en este caso será desde el principio pero si se cambia a "end" leerá desde la última linea de log
  • tags valores que se pueden poner que hacen parte de la información y que en un futuro se pueden usar como filtro
  • type se usará para enmarcar un tipo de evento sucedió este type además se agrega automáticamente a la metadata de la información que se guardara por lo tanto también se puede usar a futuro para realizar filtros

filter

Es una sección enfocada a transformar la información como mencione anteriormente la descripción de logstash incluía también transformación y en este pipeline es donde se realizará ese proceso, este pipeline se activa cada vez que logstash detecte un cambio o genere un evento sobre la información que se tiene, la información que tendrá que parsear y procesar será la siguiente

2021-08-28 13:08:27 ERROR-Log Message
2021-08-28 13:08:27 CRITICAL-Log Message
2021-08-28 13:08:27 CRITICAL-Log Message
2021-08-28 13:08:27 WARNING-Log Message
2021-08-28 13:08:27 CRITICAL-Log Message
2021-08-28 13:08:27 CRITICAL-Log Message
2021-08-28 13:08:27 WARNING-Log Message
2021-08-28 13:08:27 ERROR-Log Message
2021-08-28 13:08:27 WARNING-Log Message
2021-08-28 13:08:27 WARNING-Log Message
2021-08-28 13:08:27 WARNING-Log Message
2021-08-28 13:08:27 ERROR-Log Message
2021-08-28 13:08:27 ERROR-Log Message
2021-08-28 13:08:27 WARNING-Log Message
2021-08-28 13:08:27 ERROR-Log Message
2021-08-28 13:18:01 CRITICAL-Log Message
2021-08-28 13:18:01 WARNING-Log Message
2021-08-28 13:18:01 ERROR-Log Message
2021-08-28 13:18:01 WARNING-Log Message
2021-08-28 13:18:01 WARNING-Log Message
2021-08-28 13:18:01 WARNING-Log Message
2021-08-28 13:18:01 ERROR-Log Message
2021-08-28 13:18:01 WARNING-Log Message
2021-08-28 13:18:01 CRITICAL-Log Message
2021-08-28 13:18:01 CRITICAL-Log Message
2021-08-28 13:18:01 WARNING-Log Message
2021-08-28 13:18:01 CRITICAL-Log Message
2021-08-28 13:18:01 CRITICAL-Log Message
2021-08-28 13:18:01 WARNING-Log Message
2021-08-28 13:18:01 CRITICAL-Log Message

siguiendo entonces el mismo concepto de plugins filter también tiene los suyos

  • date este plugin es usado para parsear un evento de entrada en formato fecha en donde se aplica automáticamente una conversión a timestamp ISO 8601
  • drop este plugin  es usado para eliminar algún evento que haga match con el parámetro que sea proporcionado
  • grok este plugin es uno de los mas usados y más poderosos se usa para parsear información que tiene diferente estructura
  • mutate este filtro ayuda a agregar modificar o cambiar variables que se han creado a partir de otros filtros aplicados

existen más que pueden consultar en su documentación, en este ejemplo usare grok complementado y siguiendo el código que teníamos quedaría de la siguiente forma

input {
 
file {
    path => "shopapp/logFile.log"
    start_position => "begining"
    tags => ["backend]
    type => "Shop App"
}

}

filter {
grok{
 match => {"message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:log-level}-%{GREEDYDATA:details}"}
 }

}

en este caso usare el plugin grok este plugin trabaja utilizando unos text pattern que buscan hacer match con un texto de entrada (recuerde que logstash lee linea por linea de log) en este caso utilizare match=> para indicar la estructura que tiene el archivo .log y esto se guardara en una variable message,  ademas el match tiene la siguiente estructura %{SYNTAX:SEMANTIC} donde SINTAX es el patrón pre-cargado y SEMANTIC es el nombre de la variable que tomara ese dato que encaje en ese patrón,  por lo tanto logstash tiene algunos patrones predefinidos como TIMESTAMP_ISO8601 que es un  patrón para convertir fecha a formato iso 8601, LOGLEVEL que tiene la capacidad de encontrar niveles de error ["ERROR", "INFO"] y GREEDYDATA es un patrón especial para capturar cadenas de texto y caracteres pero además tiene una regla que captura todo lo que viene  desde esa posición a la derecha, es decir si tengo un log con un mensaje "Hola", pero después un log con un track del error, independientemente de que tan grande sea el mensaje lo tomara y guardara en la variable details

output

Finalmente el pipeline de output que hace referencia a donde se mandará la información después de ser procesada, en este caso tengo el mismo concepto de plugins, aqui utilizare el plugin elasticsearch que me permitirá guardar la información en una instancia de este motor, como se aprecia a continuación

input {
 
file {
    path => "shopapp/logFile.log"
    start_position => "begining"
    tags => ["backend]
    type => "Shop App"
}

}

filter {
grok{
 match => {"message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:log-level}-%{GREEDYDATA:details}"}
 }

}
output{
 elasticsearch{
 hosts => ["localhost:9200"]
index => "stage"}
stdout{codec => rubydebug}
}

con esto ya tendría el archivo de logstash configurado ahora la pregunta es donde se guardará? como mencione al principio este sigue el concepto de nginx y los sites config, es decir logstash tiene una carpeta ubicada en etc/logstash/conf.d donde se guardaran los archivos de configuración y cuando se inicia logstash automáticamente se cargan, en mi caso crearé uno que se llama stage.conf. Para verificar que el archivo cumple con la estructura propuesta por logstash se puede ejecutar el siguiente comando

/usr/share/logstash/bin/logstash -f stage.conf

si todo está bien debería ver algo como la siguiente figura

Figura 3: Salida del comando de verificación del archivo de configuracion

y si lo dejamos ejecutando y escribimos mas logs sobre el archivo deberíamos ver como va detectando los cambios con un mensaje parecido al siguiente

{
       "details" => "Log Message",
     "log-level" => "WARNING",
      "@version" => "1",
    "@timestamp" => 2021-08-28T18:18:02.218Z,
          "host" => "localhost",
       "message" => "2021-08-28 13:18:01 WARNING-Log Message",
          "path" => "/shoapp/logFile.log",
     "timestamp" => "2021-08-28 13:18:01"
}

cuando están seguro que la configuración es correcta simplemente reinician el service de logstash para que tome los cambios  con el siguiente comando

service logastash restart

para finalizar entro a mi instancia de kibana y visualizo los datos enviados como se aprecia en la figura

Figura 4: Análisis de logs desde kibana

Conclusiones

ELK stack es un conjunto de herramientas completisimas en donde la licencia básica incluye bastantes opciones disponibles que ayudar a mejorar el proceso de búsqueda de errores, fallos de seguridad y sobre el proceso de alerta temprana para evitar fallos aún más graves dentro del sistemas agregando la capacidad de resolverlos más rápido debido a la trazabilidad que se termina haciendo con todas estas herramientas, en nuestros próximos post seguiremos hablando más de este stack