Cómo usar Canvas en Kibana
Desde el inicio de los tiempos, Elastic nos tiene acostumbrados a sacar nuevas versiones de sus productos a un ritmo bastante alto, haciendo que, los que somos más inquietos, estemos siempre a la espera de la nueva versión para poder analizar y probar las nuevas funcionalidades.
En algunos casos, los cambios son menores o, al menos, no muy atractivos. Sin embargo, en otras ocasiones, llegan mejoras que eran esperadas con ansia desde hacía tiempo o que, sin ser esperadas, aportan un nuevo valor al conjunto del stack. Dentro de estas mejoras, siempre suelen llamar especialmente la atención las realizadas sobre Kibana ya que, admitámoslo, es una herramienta que tradicionalmente siempre ha tenido mucho margen de mejora.
Por eso, la llegada de la versión 6.5, que vino plagada de mejoras en Kibana, ha sido recibida con los brazos abiertos.
Vamos a aprovechar esta entrada de blog para hablar de una de estas mejoras: Canvas.
Canvas nos va a permitir darle vida y color a nuestros datos, pudiendo saltarnos las barreras de los dashboards tradicionales y presentar los datos que almacenamos en Elasticsearch de una manera tan vistosa como alcancemos a imaginar. Sin duda, una gran herramienta para hacer presentaciones de los datos para construir nuestros propios paneles informativos.
Siguiendo una serie de pasos, vamos a ver con un ejemplo práctico cómo utilizar Canvas para crear una presentación personalizada de nuestros datos.
Objetivo
El objetivo de este ejemplo será el de crear una presentación con datos procedentes de un log de una aplicación ficticia. Este log contiene trazas de performance, acceso de usuarios y errores propios de java.
Para la presentación, nos centraremos únicamente en las trazas de Login, teniendo como objetivo final mostrar información sobre los usuarios que más acceden a la aplicación, así como medir el número de intentos de login correctos o fallidos como muestra de la salud de nuestra aplicación.
Las trazas que se utilizan tienen este formato:
INFO 2019-01-15 17:05:45 \[main\] a.b.t.loggenerator.LogGenerator – LOGIN|400|Pantuflo|88.148.79.157
INFO 2019-01-15 17:05:45 \[main\] a.b.t.loggenerator.LogGenerator – PERFORMANCE|4.17|DOWNLOAD DOCUMENT|FAILURE|Sacarino
ERROR 2019-01-15 17:05:45 \[main\] a.b.t.loggenerator.LogGenerator – Error connecting to database|
java.lang.Exception: Error connecting to database
at am.ballesteros.training.loggenerator.LogGeneratorKt.generateExceptionTrace(LogGenerator.kt:66)
at am.ballesteros.training.loggenerator.LogGeneratorKt.generateTraces(LogGenerator.kt:31)
at am.ballesteros.training.loggenerator.LogGeneratorKt$main$1.invoke(LogGenerator.kt:17)
at am.ballesteros.training.loggenerator.LogGeneratorKt$main$1.invoke(LogGenerator.kt)
at com.xenomachina.argparser.SystemExitExceptionKt.mainBody(SystemExitException.kt:74)
at com.xenomachina.argparser.SystemExitExceptionKt.mainBody$default(SystemExitException.kt:72)
at am.ballesteros.training.loggenerator.LogGeneratorKt.main(LogGenerator.kt:14)
INFO 2019-01-15 17:05:45 \[main\] a.b.t.loggenerator.LogGenerator – PERFORMANCE|4.204|DOWNLOAD DOCUMENT|FAILURE|Robin
INFO 2019-01-15 17:05:45 \[main\] a.b.t.loggenerator.LogGenerator – PERFORMANCE|5.844|EXPORT DATA|FAILURE|Pantuflo
INFO 2019-01-15 17:05:45 \[main\] a.b.t.loggenerator.LogGenerator – LOGIN|400|Thor|196.197.86.15
INFO 2019-01-15 17:05:45 \[main\] a.b.t.loggenerator.LogGenerator – PERFORMANCE|2.304|DELETE USER|SUCCESS|Superman
INFO 2019-01-15 17:05:45 \[main\] a.b.t.loggenerator.LogGenerator – PERFORMANCE|6.885|SEND EMAIL|SUCCESS|IronFish
Como nota adicional, estos logs se han tratado posteriormente con Logstash para enriquecer parte de la información mostrada. Aunque no es necesario conocer todos los cambios realizados para poder seguir el ejemplo que realizaremos, baste con conocer que se han enriquecido las trazas de Login para geolocalizar a los usuarios en base a su IP, y para añadir una traducción textual del código de respuesta recibido.
Entorno de pruebas
Este ejemplo se ha realizado utilizando el siguiente entorno de pruebas:
- macOS Mojave
- Java 1.8.0
- Logstash 6.5.4
- Elasticsearch 6.5.4
- Kibana 6.5.4
Recursos
Para crear el Canvas final, se utilizarán los recursos gráficos que se pueden encontrar en la siguiente URL: https://bitbucket.org/ballesterosam/elastic-canvas/src/master/imgs/
Partiendo de las imágenes, gracias a la potencia que nos brinda Canvas, llegaremos a este resultado final:
Paso a paso
Una vez seleccionados los recursos a utilizar, estaremos preparados para comenzar a diseñar nuestro Canvas.
1. En primer lugar, desde Kibana, accederemos al menú Canvas y utilizaremos la opción de Crear nuevo Workpad.
2. Pinchando sobre el lienzo vacío, podremos configurarlo, indicando un nombre para el Canvas y las medidas que utilizaremos. En este caso, lo llamaremos Login Panel y seleccionaremos un tamaño de 720p para que coincida con las proporciones de la imagen que vamos a utilizar de fondo.
3. Ahora que nos enfrentamos al temible lienzo en blanco, es hora de importar todos los recursos gráficos que vamos a usar utilizando el botón de Add Element. Seleccionamos Image y, en la columna derecha, seleccionamos la opción de pegar la URL de la imagen para ir incorporando las imágenes. Repetiremos este paso por cada una de las imágenes que vamos a utilizar (por ahora no incluiremos el relleno del termómetro). En el caso de los post-it, la incluiremos tantas veces como la vayamos a necesitar.
4. Con todas las imágenes sobre el lienzo, iremos distribuyéndolas y ajustando sus tamaños en función del diseño final que queramos alcanzar.
5. Es el momento de empezar a definir nuestras visualizaciones y explotar los datos que tenemos almacenados en Elasticsearch. Aprovechando más ventajas que nos ofrece Elasticsearch, vamos a utilizar Elasticsearch SQL para extrar y filtrar los datos del índice. Las visualizaciones y elementos que añadiremos al Canvas son los siguientes:
– Un elemento de tipo Markdown para el título del Canvas. En este ejemplo, he utilizado el siguiente código para definirlo (el código se coloca en la columna derecha, en el apartado de Display):
# **Login Stats*
– Otro elemento adicional de tipo Markdown para colocar sobre el post-it que encabezará la sección de usuarios:
## **USERS**
– Añadiremos también un selector de fecha, Time Filter, que nos permitirá seleccionar los rangos temporales a partir de los que se obtendrán los datos. Este tipo de selectores serán de carácter obligatorio para todos aquellos Canvas en los que se vaya a trabajar con datos temporales (histogramas, time series, etc.)
– Incluiremos ahora una visualización gráfica de Líneas Verticales para obtener un listado de los usuarios que interactúan con la aplicación. En la columna derecha, bajo la pestaña de Data seleccionaremos la opción de cambiar la fuente de datos y seleccionaremos Elasticsearch SQL como nuevo origen de datos. Con el formato de índice que hemos definido, esta sentencia devolverá los datos adecuados:
SELECT user FROM «log-generator\*» WHERE type= ‘LOGIN’ ORDER BY user
– Sobre la misma columna derecha, en la pestaña de Display podemos definir tanto el comportamiento del gráfico como su diseño. Por un lado, podemos escoger entre las distintas paletas de colores para adaptar la visualización a nuestro diseño. Por otro, será necesario definir el comportamiento del gráfico en si mismo. En este caso, utilizaremos los siguientes valores:
– X-axis: un Count sobre el campo user.
– Y-axis: el Value del campo user.
– Color: de nuevo, el Value del campo user.
– Para la siguiente visualización, añadiremos un elemento de tipo Donut. La sentencia de Elasticsearch SQL que extraerá los datos apropiados será la siguiente:
SELECT responseCode, responseText FROM «log-generator-\*» WHERE type=‘LOGIN’
– Como en el caso anterior, en la pestaña de Display podemos configurar totalmente esta visualización, incluyendo la paleta de colores, el tamaño del agujero del Donut, la colocación de la legenda, etc. Además, deberemos especificar el comportamiento concreto del gráfico para tratar los datos extraídos. En este caso, lo configuraremos de la siguiente manera:
– Slice labels: seleccionaremos el Value del campo responseText.
– Slice angles: seleccionaremos un Count sobre el campo responseCode
– A continuación añadiremos los dos elementos que muestran los valores absolutos de Logins correctos y fallidos. Para ello, utlizaremos dos elementos de tipo Metric con las siguientes sentencias de Elasticsearch SQL. En el campo Label de cada una de ellas añadiremos los valores OK y KO respectivamente:
SELECT responseCode FROM»log-generator-\*»WHERE type=‘LOGIN’ and responseCode<300
SELECT responseCode FROM»log-generator-\*»WHERE type= ‘LOGIN’ and responseCode\>300
– Por último, solo nos falta añadir el elemento que va a hacer de indicador de temperatura en el termómetro. El uso de este elemento requerirá algo de pericia, ya que nos implicará tener que suponer la imagen que ya tenemos del contorno del termómetro con la imagen de su relleno, de manera que, visualmente, formen una imagen única. Para incorporar el relleno, utilizaremos un nuevo elemento de tipo Image Reveal y añadiremos la siguiente URL para la imagen en la columna derecha: https://bitbucket.org/ballesterosam/elastic-canvas/raw/5e069c952ae5f97e712e464ef5de034e8d63f672/imgs/termometro-relleno.png.
– Para configurar el comportamiento de esta visualización, no podremos utilizar ninguna de las medidas que aparecen pre-seleccionadas en la columna de la derecha, ya que los cálculos a realizar no vienen determinados por ninguna de esas posibilidades. Funcionalmente, tendremos que hacer una correlación entre el número de Login correctos frente al número de Login fallidos para, en función del porcentaje de esta relación, mostrar más o menos parte visible de la imagen. Para poder definir esta función, tendremos que utilizar el editor de expresiones que se encuentra en la parte inferior derecha de la pantalla. La expresión completa es la siguiente:
| essql
query=»SELECT responseText, responseCode FROM \\»log-generator-\*\\» WHERE type=’LOGIN'»
| mapColumn «responseCode» exp={getCell «responseCode» | if {lt 300} then=1 else=0}
| math «sum(responseCode) / count(responseCode)»
| revealImage origin=»bottom»
image=»https://bitbucket.org/ballesterosam/elastic-canvas/raw/5e069c952ae5f97e712e464ef5de034e8d63f672/imgs/termometro-relleno.png»
| render
– Por un lado, esta expresión incluye la query a utilizar (que también se podría añadir como hemos hecho en las visualizaciones anteriores) y, por otro, los cálculos a realizar para definir este porcentaje.
Con todos estos elementos, ya está preparado todo lo necesario para configurar este Canvas. A partir de aquí, pueden definirse más páginas para la presentación o dar el trabajo por finalizado. En este caso, nos detendremos ya en este punto.
A modo de resumen, las posibilidades que nos brinda Canvas para explotar los datos almacenados de manera visual, hace que esta herramienta se convierta en una gran alternativa para realizar presentaciones frente a los dashboards y las visualizaciones más tradicionales. Hay muchos más tipos de elementos que se pueden añadir a estos Canvas y que no se han utilizado en este ejemplo, si bien el mecanismo para utilizar cada uno de ellos es similar a los que se han descrito en esta entrada.
En la siguiente URL se pueden encontrar todos los recursos necesarios para realizar este ejemplo: https://bitbucket.org/ballesterosam/elastic-canvas/src/master/. En ese repositorio se podrá localizar una copia del Canvas final, así como ejemplos de trazas para logs, configuraciones de logstash y filebeat y una pequeña aplicación desarrollada en Kotlin para generar más trazas de ejemplo.
No es esta la única novedad que se ha ido incorporando en las últimas versiones de Kibana, en próximas entradas seguiremos analizando otras de ellas.