Monitoring Production Methodologically (Talk with the transcript)
Tags: monitoring, observability, sre, devops
Published: 2020-07-21 01:17:30

# Versión en Español
[(English version)](https://dev.to/dpsoft/monitoring-production-methodologically-talk-with-transcript-80g)

*Fecha: 11/06/2020*
*Autores:* {% user dpsoft %} {% user cspinetta %}

Esta es una transcripción *editada* y *sintetizada* de la charla [Monitoring Production Methodologically] que dimos en [Despegar](https://www.linkedin.com/company/despegarcom/) el 11 de Junio del 2020. En los últimos 5 años hemos trabajado juntos en diferentes proyectos como desarrolladores, y en el camino, hemos investigado y probado diferentes herramientas y técnicas para monitorear las apps. Esta charla, incluye muchas lecciones y técnicas aprendidas durante estos años.

## Transcripción:

![Slide 01](https://dev-to-uploads.s3.amazonaws.com/i/jdspj7a7ct0ivez0e1ch.jpg)

Esta es una charla sobre los aspectos a tener en cuenta a la hora de armar nuestro sistema de monitoreo.

![Slide 02](https://dev-to-uploads.s3.amazonaws.com/i/xeetnto4j4b8xxxoxfly.jpg)

Estas son algunas de las preguntas que queremos responder. Intentaremos ahondar el tema desde un punto de vista práctico. Si bien mostraremos ejemplos con algunas herramientas concretas, el foco estará en hablar sobre los lineamientos y aspectos a tener en cuenta, no en qué herramienta podemos usar.

Las ideas que vamos a compartir son *aspiracionales*, es decir, lineamientos que creemos que sirven de guía para lograr un sistema de monitoreo exitoso. Luego cada uno tendrá que analizar y decidir cuál es la forma más conveniente de bajarlo a su propio sistema.

![Slide 03](https://dev-to-uploads.s3.amazonaws.com/i/i6ulg4k8h9uostxk76xd.jpg)

![Slide 04](https://dev-to-uploads.s3.amazonaws.com/i/jspccz7ha25ei29625vj.jpg)

En algún momento seguramente nos hicimos preguntas como estas, que fueron disparadores para empezar a pensar cómo construir o elegir un sistema de monitoreo para nuestras aplicaciones.

![Slide 06](https://dev-to-uploads.s3.amazonaws.com/i/y6pq1dov33ol36jo9woy.jpg)

Y es posible que después de un buen esfuerzo, lleguemos a responder todas las preguntas que se nos han ocurrido, e incluso en el camino se nos ocurrieron muchas más, y las fuimos agregando. Como en este ejemplo, en el que *“total, ya que estamos…”*, le agregamos hasta el clima y el pronóstico del tiempo.

![Slide 07](https://dev-to-uploads.s3.amazonaws.com/i/iayhdn6dwkaignqk3nwu.jpg)

Si bien ese dashboard puede parecer muy completo, ¿qué tan eficaz es para resolver problemas en producción? ¿Es útil para hacer troubleshooting o comprender qué está andando mal?

Lo que sucede muchas veces, es que terminamos con dashboards que son como una sábana laaaarga, llena de métricas de todo tipo. Y luego, en medio de un problema en producción, nos volvemos locos tratando de comprender qué gráfico mirar y qué información nos está mostrando.

![Slide 08](https://dev-to-uploads.s3.amazonaws.com/i/ac5lnq1bq2wohgbmd3fh.jpg)

![Slide 09](https://dev-to-uploads.s3.amazonaws.com/i/3hjplwz2fk0yynp16c8n.jpg)

*Entonces, ¿Qué preguntas de verdad importan? ¿cuáles deberíamos responder con nuestro sistema de monitoreo?*

Hay 2 preguntas claves que debería responder: **qué está roto** y **por qué**.

**Estas dos preguntas deberían guiar nuestro sistema de monitoreo.**

Cuando intentamos responder *qué está roto*, estamos hablando de *los síntomas* que presenta nuestro sistema, lo cual es equivalente al *impacto* que estamos generando sobre los usuarios (ya sean personas, u otras aplicaciones).

Cuando intentamos responder *por qué se produjo ese síntoma*, estamos hablando de la causa que lo generó.

[Cindy Sridharan](https://medium.com/@copyconstruct), en un post sobre [Monitoring And Observability](https://medium.com/@copyconstruct/monitoring-and-observability-8417d1952e1c), dice que nuestro sistema de monitoreo debería hacer visible o evidente cuál es el impacto que estamos generando sobre nuestros usuarios (**what’s broken**), como así también comprobar que el impacto desapareció, cuando subimos un fix.

Dejamos un link al [capítulo 6](https://landing.google.com/sre/sre-book/chapters/monitoring-distributed-systems/) del libro de SRE de Google, de donde extrajimos este primer lineamiento, respecto al *qué* y el *cómo*. Y a continuación, vamos a centrarnos en cómo estas dos preguntas pueden guiar el diseño de nuestro sistema de monitoreo.

![Slide 10](https://dev-to-uploads.s3.amazonaws.com/i/xff80dz5tse7jt4azdub.jpg)

Para comprender mejor a qué nos referimos, veamos 3 simples ejemplos de **Síntoma** Vs. **Causa**.

* En el primer caso, tenemos una `API` que responde `500s`. El síntoma, es decir, lo que se percibe externamente, y por ende, la forma en que estamos impactando al usuario, es el hecho de estar devolviendo `500s`. Mientras que la causa en este caso es que la Base de Datos nos rechaza las conexiones.
* En el segundo caso, la `API` está respondiendo, pero de manera más lenta de lo esperado. Ese es el síntoma que se puede observar externamente. Mientras que la causa es que se están encolando requests. Es una causa intermedia, habría que analizar por qué se están encolando.
* En el tercer caso, el síntoma es que los usuarios no se pueden loguear, y la causa es que el cliente de autenticación, está recibiendo `503`.

Se llama *"monitoreo de caja negra"* a aquellos que capturan los síntomas, ya que estamos obteniendo una visión externa del sistema. Mientras que son *"monitoreo de caja blanca"*, aquellos que capturan eventos internos del sistema, y que generalmente permiten comprender la causa.

Se dice que **distinguir entre el qué y el comó, nos permite diseñar sistemas de monitoreo con señales más claras, y con menos ruido**. Esta cita es extraída del [libro de SRE de Google](https://landing.google.com/sre/sre-book/toc).

Un detalle que está bueno notar, es que las causas de nuestro sistema podría ser un síntoma en otro. Ese sería el caso del tercer ejemplo, donde tenemos un cliente que recibe `503`, es decir, del otro lado hay un servicio que tiene el síntoma de no poder atender las requests.

![Slide 11](https://dev-to-uploads.s3.amazonaws.com/i/o1rqsd1tlfpxmbsnf2ua.jpg)

Hay diferencias claves entre monitoreo de *caja negra* y monitoreo de *caja blanca*. Conocerlas, nos puede ayudar a armar gráficas y paneles más efectivos, que hagan foco en lo que intentan mostrar, ya sea un síntoma o una causa.

En el caso de **caja negra**:

* El monitoreo debe pensarse desde el punto de vista del usuario (o bien, desde el requerimiento de negocio). Por ej, preguntas como *¿Qué tan rápido esperan los usuarios que les responda mi API?*, nos llevaría a armar un gráfico sobre tiempos de respuestas.
* Suelen estar controladas a través de *SLIs* y *SLOs* (luego veremos que son).
* Son relativamente fácil de conocer, dado que en general se conoce de antemano los requerimientos que el servicio intenta satisfacer.
* Este tipo de sistemas nos permite visualizar *problemas activos*, es decir, que ya están ocurriendo e impactando al usuario.
* Esto quiere decir que **debemos actuar de forma reactiva**: cuando vemos un problema, tenemos que salir corriendo a solucionarlo, porque se trata de algo que ya está impactando a los usuarios.
* En general, las alertas de un sistema de monitoreo de caja negra, tienden a ser las últimas en saltar.
* Usualmente se resuelven por las personas que están de guardia.
* Y generalmente están compuestos de pocas métricas, dado que el usuario típicamente no espera cosas muy complejas de nuestros servicios, simplemente quiere que funcione en tiempos adecuados, de forma adecuada, que no haya errores, etc.

En el caso de **caja blanca**:

* El monitoreo debe pensarse desde un punto de vista bien técnico, basado en la arquitectura de nuestro servicio.
Generalmente se controlan a través de umbrales, dentro de los cuales podemos afirmar que nuestros componentes funcionarán bien.
* En general, es más difícil saber qué nos interesa monitorear, y cómo, ya que depende de conocimiento y experiencia técnica sobre los componentes del sistema.
* Detectan *problemas inminentes*, es decir, que quizás aún no produjeron ninguna consecuencia, pero que de continuar así, pronto lo harán.
* **Permiten accionar de forma proactiva**, dado que permiten adelantarse a los síntomas que están por ocurrir. Por ejemplo, si vemos que el espacio en disco pasó un umbral, podemos afirmar que de continuar así, pronto nos quedaremos sin disco, lo cual puede ser algo que genere algún impacto sobre el usuario, y por lo tanto podemos reaccionar de forma temprana, previniendo el problema de quedarnos sin disco.
* En general tiende a tener alarmas tempranas, que nos pueden prevenir incidentes.
* Suele haber soluciones automáticas, por ejemplo, autoscaling, rollback automático, circuit breaker, etc.
* Y aquí si queremos tener bastante métricas, tantas como el sistema lo necesite para demostrarnos que está bajo un estado aceptable.

De todas estas diferencias, hay una que es clave: *el enfoque con el que se enfrentan los problemas*. Mientras que **en uno de caja negra, el enfoque es reactivo** (es decir, reaccionamos cuando el usuario está siendo afectado), **en uno de caja blanca, podemos actuar de forma proactiva**, antes de que el usuario se vea afectado.

Ambos tipos de monitoreo son importantes y se complementan.

![Slide 12](https://dev-to-uploads.s3.amazonaws.com/i/8yx6bmddgt9zi6e9nq9s.jpg)

![Slide 13](https://dev-to-uploads.s3.amazonaws.com/i/6gvvm6ah3b8itmnphr4i.jpg)

A continuación, algunas buenas prácticas que fuimos incorporando.

1. **La simplicidad es la principal optimización de cualquier sistema**. El sistema de monitoreo es como cualquier otro sistema de Software, fácilmente se puede complejizar y tornar inmanejable, entre otras deficiencias. Mantener las cosas simples, ayuda a que sea fácil de comprender, de mantener y de modificar.
2. Debe ser fácil de leer y comprender. En otras palabras, **tiene que ser expresivo**.
3. No desagregar innecesariamente. Por ejemplo, si estoy midiendo tiempos, elegir apropiadamente 3 o 4 percentiles, si quiero medir errores, elegir cómo contabilizarlos, si voy a contar cantidad de errores o cantidad de success, y contar solo uno, etc.
4. Mantener los gráficos limpios y ordenados.
5. Las métricas y alertas que rara vez usamos, son candidatas a ser eliminadas. O bien, deberíamos pensar que cambios hay que hacerle para que pase a ser más relevante.
6. En lo posible, tener pocas métricas, y no duplicarlas. A veces, tenemos la misma métrica tomada con distintos sistemas. Evitar la redundancia, si no, después no sabés que mirar.
7. Poner especial atención a cómo estamos midiendo. En general, usar series de tiempo, que permitan graficar líneas continuas, es preferible a hacer checks discretos, como haríamos con `Nagios` por ejemplo.
8. Evitar los promedios. Esto más que nada cuando estamos midiendo tiempos. Es preferible guardar los tiempos en buckets, y visualizar la distribución, por ejemplo, percentil 50 / 75 / 90 / 99 / 99.9 / etc. También tener presente cómo están configurados los buckets, y si son acorde a los tiempos que queremos registrar.
9. Poner un ojo en los picos, por ejemplo el percentil 99.9, o 99.99 (o más, eso depende mucho del servicio que estamos analizando). Es importante no olvidarnos de estos picos, que según la cantidad de tráfico, pueden ser significativos.
10. Seleccionar apropiadamente la resolución, acorde a lo que estamos midiendo. La mayoría de las veces, la default que traen los herramientas, no sirve.

![Slide 14](https://dev-to-uploads.s3.amazonaws.com/i/ihv23cscph7a35vv531c.jpg)

Ahora vamos a mostrar 2 de las metodologías más utilizadas para monitorear.

![Slide 15](https://dev-to-uploads.s3.amazonaws.com/i/3lk9ur1josuoxetd4ao7.jpg)

[USE Method] es una metodología creada por [Brendan Gregg], un especialista en análisis de Performance. Es una metodología orientada al análisis de performance, que se centra en analizar 3 aspectos de cada recurso: utilización, saturación y errores. El dice que analizando estos 3 aspectos de cada recursos, vamos a poder resolver el 80% de los casos.

* La utilización es qué porcentaje del tiempo está ocupado el recurso.
* La saturación se puede ver como una cola de tareas a despachar por el recurso. La cantidad de tareas que están encoladas, representa el grado de saturación del recurso.
* Errores tiene que ver con las fallas del recursos. Se puede contabilizar como un ratio del tipo `errores / total de requests`.

Si bien esta metodología fue creada para hacer análisis de performance, puede servir como guía para crear nuestro sistema de monitoreo de caja blanca, ya que podríamos analizar estas 3 características en cada componente / recurso que nos interese monitorear.

![Slide 16](https://dev-to-uploads.s3.amazonaws.com/i/uxl80jdiueyxrfd9z8g7.jpg)

[The Four Golden Signal] es una metodología presentada por Google en su libro de SRE. En este libro dicen que si solo pudieras medir 4 métricas de tu servicio, deberían ser la latencia, el throughput, los errores y la saturación. Esas métricas son suficiente para detectar la mayoría de los problemas.

Es una metodología para desarrollar un monitoreo de caja negra.

* La **Latencia**, es el tiempo que tardamos en realizar algo que nos solicita el usuario. En general es el tiempo que tardamos en responder una request, o el lag en un pipeline de datos.
* El **Tráfico**, es la cantidad de requests que estamos recibiendo. Es importante observar el tráfico, porque siempre debería cambiar de forma esperada. Si cambia de forma inesperada, puede ser síntoma de que alguien nos puso en una *blacklist*, o bien, que no está pudiendo consumir nuestro servicio.
* **Errores**. Siempre es importante conocer cuántos errores tenemos y si estamos bajo una cantidad de errores aceptables.
* **Saturación**, ¿Qué tan estresado está nuestro servicio?. Esta métrica puede estar compuesta por diferentes aspectos de nuestro sistema. Depende mucho del tipo de servicio que estemos ofreciendo. Podría ser la cantidad de requests encoladas, o bien, si es una app `CPU Bounded`, si la CPU está saturada podría indicarnos si el servicio está saturado o no, etc.

![Slide 17](https://dev-to-uploads.s3.amazonaws.com/i/5snt2vg4t3uv9f3chvt5.jpg)

Este es un ejemplo de uno de nuestros servicios, monitoreado con The 4 Golden Signals. En el caso de esta aplicación, como hace un procesamiento asincrónico de los eventos que recibe, un indicador de que el servicio está saturado es la cantidad de eventos que estamos reteniendo en la cola.

![Slide 18](https://dev-to-uploads.s3.amazonaws.com/i/a69nz40plwzlm2pfu93t.jpg)

Para armar nuestro sistema de monitoreo, podemos tomar algunas ideas y prácticas de SRE, ya que *monitoring* es una parte core de este rol.

Por supuesto que SRE es mucho más que monitorear aplicaciones, y ni hablar si tomamos en cuenta cómo lo aplica Google. Siendo consciente de que no somos Google, ni Twitter, ni Netflix, sí creemos que es interesar tomar las cosas que nos sirven de estas prácticas, y llevarlo a nuestra realidad.

![Slide 19](https://dev-to-uploads.s3.amazonaws.com/i/rx9s4ni0ggxphhfcrr42.jpg)

Uno de los objetivos centrales de SRE es medir qué tanto se está cumpliendo con las expectativas del usuario. Para poder cuantificarlo de manera objetiva, selecciona una serie de indicadores claves, llamados [SLI (Service Level Indicator)](https://landing.google.com/sre/sre-book/chapters/service-level-objectives/#indicators-o8seIAcZ), que permitan medir si se está cumpliendo con la calidad de servicio que se pretende brindar.

![Slide 20](https://dev-to-uploads.s3.amazonaws.com/i/zxmu5lm8ftc9amu4jsd3.jpg)

En Google, hay un *"menú de SLI"*, que tiene una lista de *SLIs* a aplicar en cada tipo de servicio, según la forma de interactuar que tenga el servicio con los usuarios. Por ejemplo, en un servicio donde los usuarios interactúan a través de un esquema *Request / Response*, 3 *SLIs* claves serían *la disponibilidad*, *la latencia* y *la calidad de las respuestas*. La calidad puede ser una métrica interesante, si tenemos algún mecanismo de *graceful degradation*. Del mismo modo, si tenemos un servicio que funciona como un *pipeline de datos*, donde los usuarios ingresan un evento para que este sea procesado y disponibilizado, nos va a interesar observar otro tipo de indicadores, y sí podemos continuar con otros tipos de servicios.

El menú sirve como una guía inicial, luego hay que analizar las necesidades particulares de cada servicio.

Entonces, la forma de elegir los *SLIs* apropiados para mi servicio sería la siguiente:

1. El primer paso sería elegir los *SLIs* apropiados para el servicio que quiero monitorear.
2. El segundo paso sería especificar qué eventos vamos a considerar *válidos* para el *SLI*, y qué condición deben cumplir para ser contabilizados como eventos *exitosos o buenos*.
3. Finalmente, como tercer paso, deberíamos especificar desde donde vamos a obtener estos eventos, básicamente que tan cerca del usuario o de las apps nos vamos a situar.

![Slide 21](https://dev-to-uploads.s3.amazonaws.com/i/32nt6aljczl4b8civiw7.jpg)

Aquí un ejemplo sobre cómo podríamos agregar 2 *SLIs* para medir *la disponibilidad* y *la latencia* de un servicio que expone información de los usuarios.

En el caso de la *Disponibilidad*, podemos especificar que queremos observar el porcentaje de `GETs` que se completan con éxito, y como implementación, podemos especificar que vamos a registrar como eventos válidos todas las requests que devuelven `200s` o `500s` como status code, y como eventos exitosos, los que devuelven `200s`. Entonces, podemos hacer un ratio de cantidad de `200s` sobre cantidad de `200s + 500s`, obteniendo *el porcentaje de `GETs` completados con éxito*.

Para la latencia, podemos especificar que nos interesa medir el porcentaje de requests que devuelven un `200s` como status code, *en menos de 500 milisegundos*. Como implementación, podemos especificar que los eventos válidos son todos los `200s`, y los exitosos son los `200s` que se resuelven en menos de 500 milisegundos.

![Slide 22](https://dev-to-uploads.s3.amazonaws.com/i/mirzhfyc4tckizl9w8tn.jpg)

Lo interesante es que definiendo eventos válidos y eventos exitosos para cada *SLI*, podemos llevar todas las mediciones a porcentajes, es decir, tendríamos una unidad en común para todos los *SLIs*. Luego, dado que son porcentajes, podemos establecer fácilmente **objetivos** sobre los mismos. Estos objetivos, se los llama [SLO (Service Level Objective)](https://landing.google.com/sre/sre-book/chapters/service-level-objectives/#objectives-g0s1tdcz), y tienen que tener una ventana de tiempo sobre las que van a ser medidos. Por ejemplo, para la disponibilidad podemos establecer un *SLO* de *99.9%*, medido a través de todos los servidores que exponen el servicio, y en ventanas de tiempo de 24 horas. De forma análoga, podemos definir otro *SLO* para la latencia, definiendo que queremos que por lo menos el *95%* de las requests GET que terminan con `200s`, se completen en menos de `500ms`, medido a través de todos los servidores que exponen el servicio, en ventanas de tiempo de 24 horas.

![Slide 23](https://dev-to-uploads.s3.amazonaws.com/i/nn903wro4diidmc8of26.jpg)

Este es un ejemplo de una de las aplicaciones que mantenemos. 
Es una app que expone un servicio para ingresar eventos y procesarlos asincrónicamente. En este servicio elegimos 3 *SLIs*: *disponibilidad*, *latencia* y *el tiempo transcurrido desde que ingresa el evento, hasta que termina de procesarse*.

Aún no definimos *SLOs*, porque queremos tener un mayor historial sobre cómo usarán el servicio, pero lo que sí hicimos, es elegir algunos valores como sugerencia, y los dejamos en el título y descripción de cada panel.

![Slide 24](https://dev-to-uploads.s3.amazonaws.com/i/yahy5pev8dg7qu57fk0z.jpg)

Un tema muy importante en nuestro sistema de monitoreo son las alertas. Mal usadas, pueden generar más problemas que si no las tuviéramos.

![Slide 25](https://dev-to-uploads.s3.amazonaws.com/i/y3w1hzcxad2iqdqmu8un.jpg)

Las alertas tienen que saltar solo cuando se trata de algo urgente, algo que no se puede postergar. Si la alerta está bien configurada, cuando aparece, debería querer salir corriendo. **Tienen que estar basadas en síntomas**, es decir, tiene que avisarme solo si estamos generando, o estamos en camino a generar, algún impacto negativo sobre el usuario.

Cuando esto no sucede, cuando las alarmas nos avisan de algo que puede esperar al otro día, o de algo que ni siquiera es un problema, entonces empiezan a surgir otros problemas que también son bastante serios:

* Acostumbrarnos a la falsa alarma y no ver a tiempo una alarma importante.
* Malgastar el tiempo, ya sea por el switch mental, o por interrumpirte en un momento personal.
* Desmoralizar, desmotivar, generar mal predisposición a monitorear.

Dejamos algunas preguntas que tomamos principalmente del libro de SRE de Google, que creemos que pueden servir de guía para armar bien las alarmas:

* La alarma que estoy creando, va a detectar una condición que me haga reaccionar con urgencia? La situación, tiene algún accionable? Le estará impactando inmediatamente a los usuarios? Por ej, si la situación es que se cortó la red en una región, y no queda otra que esperar, no hace falta que me molesten por eso. En todo caso, cuando vuelva, si mis servicios no se pudieron recuperar solos, ahí si debería haber alguna alarma.
* Cuando suceda, voy a poder tomar alguna acción? Es realmente urgente o puede esperar al otro día? Por ejemplo, si en el cluster de un servicio se cayeron algunas instancias, pero el tráfico se puede seguir sirviendo con las instancias que quedaron activas, no hace falta lanzar una alerta. En todo caso notificarlo por otra vía, tal de que al día siguiente lo pueda ver.
* La acción podría ser automatizable? Siempre que una acción se pueda automatizar, es preferible eso. Se ahorra tiempo, es menos error prone, y no depende del conocimiento de una persona en particular.
* La alerta, va a molestar a otra gente innecesariamente? Ojo con el encadenamiento de alertas, debería haber una dependencia. Hay sistemas de alertas que permiten configurar eso.

¿Que hacemos con las alertas que no son urgentes? Por ej. que se caiga un nodo de un cluster. Se puede usar otro canal de comunicaciones para este tipo de notificaciones. Uno que se revise en horario laboral, y que sea parte de las tareas de mantenimiento, no de la guardia.

![Slide 26](https://dev-to-uploads.s3.amazonaws.com/i/0r6ygnfhg4qtt4413p0d.jpg)

Ok, pero hasta acá no hablamos de logs, ni de trazas, ni de nada de todas esas herramientas que tanto se estuvieron hablando estos días. Al contrario, dijimos que el monitoreo no debe contener muchas métricas, solo las necesarias para responder **Qué está roto** y **Por Qué**.

Bueno, ahora vamos a ver que para todo el resto, están las herramientas de *observability*. Y vamos a hacer un breve repaso sobre las más importantes, dado que complementan con todo lo que nuestro sistema de monitoreo no nos alcanza a responder en momentos de **troubleshooting** y **debugging**.

![Slide 27](https://dev-to-uploads.s3.amazonaws.com/i/gqn9rl4akbaiu8086h8i.jpg)

El objetivo de *Observability* es diferente al de monitoring. El objetivo es permitirnos conocer con el mayor nivel de detalle posible, el comportamiento y estado interno de nuestro sistema. Algo que es muy importante para comprender el estado interno, es el contexto de ejecución, ya que nos permite comprender la causalidad de la serie de acciones o eventos que suceden internamente.

Como se puede ver en la imagen, observability incluye las herramientas de monitoring y va más allá. Se dice que abarca todo lo que monitoring no llega a cubrir.

Otro punto importante es que debe estar basado en evidencias, no en conjeturas u opiniones.

Observability es un término que generó  bastante debate en estos últimos años, y se lo uso mucho de forma marketinera. Sus orígenes vienen de teoría de control, y en lo que sí podemos ponernos de acuerdo a lo largo de todo el debate que se fue dando, es que tiene que ver con conocer el estado interno y el comportamiento de un sistema.

![Slide 28](https://dev-to-uploads.s3.amazonaws.com/i/1ujqtse4i3u8bb9x1c4v.jpg)

A continuación, vamos a hacer un breve repaso sobre las herramientas de observability más usadas en un contexto de sistemas distribuidos.

![Slide 29](https://dev-to-uploads.s3.amazonaws.com/i/tg4wr8jw6i0oheqfvljo.jpg)

Cuando intentamos resolver un problema, probablemente en algún punto queramos pasar a revisar el log.

Los logs son eventos discretos que generan las aplicaciones a medida que ejecutan su propia lógica. El log que se genera para hacer observability, en general tiene datos y detalles asociados a las decisiones y caminos que que la aplicación fue tomando, tal que luego sirva para hacer diagnóstico o evidenciar lo que la aplicación hizo. Algo importante es que **el log siempre nos habla sobre qué hizo la aplicación en el pasado**.

Algunos detalles a tener en cuenta cuando agregamos logs, son:

* Loguear con contexto. Ya sea un identificador por request, o algo que nos permita correlacionar varios logs asociados a un mismo evento.
* Estandarizar el log, tal de tener el mismo tipo de información en cada nivel de logueo.
* En lo posible, usar logs estructurado. Tal de que no esté limitado a ser leído por un humano, sino que también pueda procesarse programáticamente. Y por ejemplo, sacar métricas, agrupar, indexar fácilmente por campos específicos, etc.

Respecto a logs estructurados, dejamos una imágen mostrada en una [charla](https://www.youtube.com/watch?v=TcmvmqbrDKU) en la [GRAFANACON](https://grafana.com/about/events/grafanacon/2020/) de este año, donde a partir de unas líneas de logs, se puede sacar información extra sobre la cantidad de requests, por endpoint y status code, lo cual puede ser muy útil en medio de un incidente en producción. En este caso, lo están haciendo con una query sobre **Loki**, usando [LogQL](https://github.com/grafana/loki/blob/master/docs/logql.md), parecido a [PromQL](https://prometheus.io/docs/prometheus/latest/querying/basics/) de [Prometheus](https://prometheus.io/).

![Slide 30](https://dev-to-uploads.s3.amazonaws.com/i/0ohmr65jhq7so66mk3oc.jpg)

Aquí se ve un ejemplo de cómo listamos los logs de una aplicación, en este caso llamada *data-stream-in*, usando *Loki*.

![Slide 31](https://dev-to-uploads.s3.amazonaws.com/i/5v2p0hyaivna56xsrlf4.jpg)

Aquí otro ejemplo, filtrando solo los *warnings*.

![Slide 32](https://dev-to-uploads.s3.amazonaws.com/i/tqnfwnstcb6dsnjssdv3.jpg)

Y aquí otro ejemplo, armando una métrica de cantidad de logs por minuto, agrupado por nivel. En este caso vemos que tenemos logs en `INFO` y en `WARN`.

![Slide 33](https://dev-to-uploads.s3.amazonaws.com/i/kbqo9muo31d1ggsdxjks.jpg)

Otra herramienta fundamental, son las métricas. A diferencia del log, las métricas son valores agregados, tales como *contadores*, *histogramas*, *gauge* (valores que pueden crecer o decrecer). Las métricas se usan tanto para conocer el estado actual de un sistema, como la tendencia o evolución que está teniendo. Esto significa que son útiles para predecir hacia donde va el sistema. Por ej, con una métrica del espacio en disco utilizado, podemos ver si estamos agotando el espacio libre y si la tendencia es quedarnos sin disco, o por el contrario, estar ganando espacio en disco.

Además de las métricas del sistema en sí, como latencia, throughput, errores y saturación, es importante tener en cuenta otros aspectos subyacentes al sistema. Aspectos como los [hiccups](https://www.azul.com/giltene-how-java-got-the-hiccups/) que puede tener la *VM*, el uso de *CPU* y cantidad de pausas introducidos por la *GC*, son algunos de los que también hay que observar para comprender mejor la performance de nuestro sistema.

![Slide 34](https://dev-to-uploads.s3.amazonaws.com/i/pzqzp5m00pivq4mum290.jpg)

Aquí un ejemplo de métricas de sistema que tomamos en nuestras VMs.

![Slide 35](https://dev-to-uploads.s3.amazonaws.com/i/90n5t9irsiqzzn2gap3j.jpg)

Tracing es otra herramienta muy útil que permite, no solo analizar y responder preguntas sobre una aplicación en particular, sino también responder preguntas que tienen que ver con la interacción de un conjunto de aplicaciones a lo largo de un flujo que recorre una request.

Una traza es un conjunto de eventos individuales que se desencadenan a través de un evento padre (en general una request). Lo interesante es que **se puede visualizar en una sola imagen la causalidad de los eventos** que están relacionados con una traza en particular. Algunas preguntas interesantes que permite responder, son:

* Cuál es el camino que recorre una request?
* Dónde está el cuello de botella, que ralentiza toda la ejecución?
* Cuanto tiempo se va en el lag de la red?
* Qué ocurre en cada servicio, para una request en particular?

Esta *slide* está tomada de [una charla sobre tracing distribuido](https://slides.com/diegoparra/monitoring-microservices/) que dimos hace unos años, les dejamos el link a la presentación.

![Slide 36](https://dev-to-uploads.s3.amazonaws.com/i/k1z88o88bwekfziflo1v.jpg)

Este es un ejemplo de una traza distribuida entre 2 aplicaciones. Se puede visualizar fácilmente el momento que ocupó cada aplicación, y una serie de detalles interesantes en cada *span*, como *headers*, *tiempos*, *status code*, etc.

![Slide 37](https://dev-to-uploads.s3.amazonaws.com/i/vhogt0b6aw7eszhguos3.jpg)

**En resumen:**

* Usemos [The Four Golden Signal] y [USE Method] para monitorear nuestros servicios.
* Instrumentemos nuestros servicios tan pronto como sea posible.
* Combinemos *profiling*, *logs* y *trazas*, como herramientas auxiliares para hacer *troubleshooting*.
* **Iterar**. Esto es un proceso iterativo. Empecemos de a poco, como dijimos, manteniendo la simpleza, y evolucionemos iterativamente nuestro sistema de monitoring.

Después de desarrollar todos estos temas algunas de las preguntas abiertas, y otras no tanto, que se nos ocurren son:

![Slide 42](https://dev-to-uploads.s3.amazonaws.com/i/0kldvns9ejhz8gn9dzpy.jpg)

Algunas de las preguntas anteriores nos lleva a una línea de pensamiento donde la *controlabilidad es el fin de la observabilidad*, y en un sistema que se autocontrola a partir de su dinamismo y donde no está solo en el universo sino que se comunica enviando y recibiendo señales que influencian a otros, y que con el tiempo ayudan a inferir el estado de los demás y el de uno mismo.

Si seguimos la idea de la *controlabilidad* caemos en la *Teoría del Control* que hace 2000 años atrás fue usada por los egipcios en un reloj de agua (*Clepsidra*), o un poco más acá cerca, en la segunda guerra mundial se desarrollaban armas que se apoyaban en esta idea como por ejemplo los cañones antiaéreos.

![Slide 46](https://dev-to-uploads.s3.amazonaws.com/i/jzmso4gnvyarq8gy3gea.jpg)

Se usa de manera intensiva en:
* Control de Procesos.
* Electrónica.
* Industria Aeroespacial.
* Automatización de manufactura.

![Slide 47](https://dev-to-uploads.s3.amazonaws.com/i/gffkcmafd6j0va6oflts.jpg)

El principio básico es comparar de manera continua la salida actual del sistema con el valor de referencia, y aplicar cambios a la entrada del sistema para contrarrestar cualquier desviación que exista entre la salida y el valor de referencia.

Si pensamos en código, dentro de un `while(true)` tenemos el estado actual y el deseado, e intentamos en todo momento que se llegue al valor deseado aplicando correcciones con el feedback loop.

```
while(true) {
    currentState = getCurrentState()
    desiredState = getDesiredState()
    makeConform(currentState, desiredState)
}
```

Algunos ejemplos conocidos donde se utiliza son:

* Control de velocidad de un auto.
* Cooler del CPU donde la métrica que trackeamos es la temperatura y lo que ajustamos es el voltaje aplicado al cooler.
* `Kubernetes` y el autoscaling utiliza un `PID` (Proportional, Integral, Derivative) Loop con algunos checks y algún que otro artilugio.
* `Control plane` de *Amazon*.

![Slide 44](https://dev-to-uploads.s3.amazonaws.com/i/lpkr0nsqhixekh4ib4es.jpg)

**Gracias!!**

[Monitoring Production Methodologically]: https://slides.com/diegoparra/monitoring-production-methodologically/
[The Four Golden Signal]: https://landing.google.com/sre/sre-book/chapters/monitoring-distributed-systems/#xref_monitoring_golden-signals
[USE Method]: http://www.brendangregg.com/usemethod.html
[Brendan Gregg]: http://brendangregg.com/