Foto de cottonbro studio.

En esta entrada del blog es donde se encuentra la referencia a observabilidad: Monitorización moderna de aplicaciones.

Y aquí es donde hablo de conceptos básicos enfocado todo a OpenTelemetry.

Mi problema

Las arquitecturas de microservicios me han permitido construir y lanzar software más rápido y con mayor independencia. No es como en las arquitecturas monolíticas con servicios que están muy unidos. Cuando divido la aplicación en un conjunto más pequeño de servicios, aumenta la cantidad de componentes que se intercomunican en mi arquitectura. La verdad que hacer el seguimiento a una solicitud de principio a fin es bien difícil.

A medida que mi sistema distribuido crece, se vuelve cada vez más complicado ver cómo mis propios servicios dependen o afectan a otros servicios, sobre todo después de una nueva implementación o durante un problema, donde la rapidez y la precisión son cruciales. Entonces, ¿cómo puedo observar el sistema en su conjunto?

¿Qué es OpenTelemetry?

Los patrones/soluciones de trazabilidad distribuido resuelven este problema y muchos otros de rendimiento, porque pueden rastrear las solicitudes a través de cada servicio y proporcionar la información de principio a fin de cada solicitud. Esto se logra correlacionando todos los servicios mediante la inserción de un CorrelationId o TraceId único para cada solicitud. Este identificador se puede utilizar para observar el sistema. En general, el objetivo de OpenTelemetry es crear un modelo común y enviar datos de telemetría a cualquier plataforma de monitoreo.

Existen varias herramientas de observabilidad disponibles que van desde herramientas de código abierto: Jaeger, Zipkin, etc. a propietarias como Azure Application Insight, AWS CloudWath, etc.

Pero antes de entrar a ver que es OpenTelemetry, un poco de historia:

OpenTracing proporcionaba una API neutral para el proveedor para enviar datos de telemetría a un backend de observabilidad; pero, dependía de los desarrolladores para implementar bibliotecas para cumplir con las especificaciones del proveedor.

OpenCensus proporcionaba un conjunto de bibliotecas específicas para cada lenguaje que los desarrolladores podían utilizar para instrumentar su código y enviarlo a cualquiera de los backends compatibles.

Con el objetivo de tener un único estándar, OpenCensus y OpenTracing se fusionaron para formar OpenTelemetry (OTel, abreviado) para, en teoría, proporcionar lo mejor de ambas herramientas y algo más.

Como más o menos podeis leer en  sendos aununcios de https://opencensus.io/ y en https://opentracing.io/

Conceptos

Para observar correctamente un sistema, es necesario agregar bibliotecas y código que permitan emitir información en forma de trazas, métricas y registros. Adenñas debes entender bien los siguientes conceptos:

Un registro (log) es un mensaje con marca de tiempo emitido por los servicios u otros componentes. Sin embargo, los registros por sí solos no son muy útiles para rastrear la ejecución del código, ya que a menudo carecen de información contextual.

Por otro lado, una tramo (span) representa una unidad de trabajo u operación. Rastrea las operaciones específicas que realiza una solicitud y ofrece una visión de lo que sucede durante ese tiempo.

El contexto del tramo (span context) es una parte del tramo que se utiliza para correlacionar trazas entre sí y asociarlos con la traza en general.

Un atributo (attribute) es un metadato en forma de clave-valor que se utiliza para anotar un tramo y proporcionar información sobre la operación que se está rastreando.

Las trazas distribuidas (distributed traces) nos brinda una visión general de lo que sucede cuando se realiza una solicitud en una aplicación. Permite rastrear solicitudes en múltiples servicios y componentes, lo cual proporciona una visibilidad completa del flujo de solicitudes a través de la aplicación.

La propagación de contexto (context propagation) es el mecanismo que mueve el contexto de la traza entre servicios y procesos, ensamblando una traza distribuida. Esto se logra serializando y deserializando el contexto de la traza, proporcionando la información relevante para la traza.

El muestreo (sampling) es una técnica utilizada para reducir el volumen de datos de telemetría recopilados. OpenTelemetry admite el muestreo, lo cual puede ayudar a reducir la sobrecarga y mejorar el rendimiento.

Trabajando con colectores (collector)

Para recopilar y procesar los datos de telemetría, podemos utilizar el colector de OpenTelemetry. Tenemos dos opciones de implementación: el agente, que se ejecuta junto con la aplicación o en el mismo host, y el gateway, que se ejecuta como un servicio independiente.

El colector consta de varios componentes, como receptores, procesadores, exportadores y extensiones, que se utilizan para acceder, procesar y enviar los datos de telemetría a uno o más destinos de almacenamiento.

Para recopilar métricas, las aplicaciones deben exponer sus métricas en formato Prometheus o OpenMetrics a través de HTTP. También existen exportadores que exponen las métricas en el formato adecuado para aquellas aplicaciones que no pueden hacerlo directamente.

Si queremos ver los datos de traza, podemos utilizar el exportador de Jaeger, mientras que para los datos de métricas podemos utilizar el exportador de Prometheus. Es importante configurar adecuadamente cada componente según los datos que deseamos observar.

Debemos prestar atención a configurar el colector de OpenTelemetry, definir los receptores, procesadores y exportadores en el archivo de configuración, y utilizar herramientas de terceros como Jaeger, Prometheus y Grafana para visualizar los datos de trazas y métricas.

 

Ejemplos prácticos