Aprende cómo instrumentar aplicaciones Node y de cliente utilizando OpenTelemetry y herramientas de observabilidad de código abierto populares como Prometheus y Grafana.
Introducción a la Observabilidad de Código Abierto
Video Summary and Transcription
La observabilidad es una herramienta crucial para los ingenieros para enviar sitios web confiables y tener una buena experiencia de desarrollo. Las métricas, los registros y las trazas son tipos de datos fundamentales para lograr la observabilidad. OpenTelemetry es un estándar de código abierto para datos de observabilidad, y la instrumentación se puede realizar de forma manual o automática. La recopilación y el transporte de datos pueden ser gestionados por paquetes construidos por la comunidad de OpenTelemetry, y el ejecutor en funcionamiento puede agregar beneficios de seguridad. Grafana se utiliza para la visualización de datos, y permite analizar el rendimiento web, excepciones y trazas. Las trazas capturan las interacciones de los usuarios y proporcionan información sobre el comportamiento de los usuarios y la aparición de errores. Aprovechar estas herramientas permite obtener información sobre varias partes del sistema y mejorar los objetivos de ingeniería.
1. The Story of StrongBad Inc.
Hablemos de la historia ficticia pero no del todo irreal de StrongBad Inc., una joven empresa de software. Strong Bad Inc. es una plataforma de consejos por correo electrónico donde las personas pueden ir en línea y hacer preguntas que Strong Bad responderá. En su primer día, después de configurar su entorno de desarrollo, Homestar Runner estaba súper emocionado de tomar su primer ticket y agregar etiquetas e inputs al formulario de envío de correo electrónico. Encontraron una solución y pudieron enviarla a producción y ¡hooray, el sitio web volvió a funcionar! Como ingenieros, queremos lanzar sitios web confiables, solucionar problemas rápidamente y con confianza, y tener una buena experiencia de desarrollo. La observabilidad es una herramienta en nuestra caja de herramientas para ayudar a lograr esos objetivos.
Strong Bad Inc. es una plataforma de consejos por correo electrónico donde las personas pueden ir en línea y hacer preguntas que Strong Bad responderá. Por ejemplo, ¿puedes dibujar un dragón o te gusta la música techno? Strong Bad es un buen desarrollador, pero quería un poco de ayuda adicional en la oficina, así que trajo a su amigo Homestar Runner para ayudar con algunas tareas de desarrollo.
En su primer día, después de configurar su entorno de desarrollo, Homestar Runner estaba súper emocionado de tomar su primer ticket y agregar etiquetas e inputs al formulario de envío de correo electrónico. Todo estaba genial, abrió su primer PR, fue aprobado y todos estaban extasiados cuando se fusionó en producción. Estaba tan emocionado de contribuir con código en su primer día. Solo para descubrir después de regresar del almuerzo que el sitio web había sido desactivado. No tenían idea de qué estaba pasando, así que fueron a atención al cliente para ver qué estaba sucediendo y, de hecho, confirmaron que el sistema estaba caído. Después de un par de horas de depuración estresante, encontraron una solución y pudieron enviarla a producción y ¡hooray, el sitio web volvió a funcionar! Pero se quedaron preguntándose qué causó el error. Incluso después de depurar, no estaban seguros al 100% cuál era la causa raíz. Incluso con la solución, no tenían mucha confianza en lo que estaba sucediendo y cómo podrían evitarlo en el futuro.
Entonces Homestar se preguntaba a sí mismo, debe haber una mejor manera. Como ingenieros, tenemos los mismos objetivos. Queremos lanzar sitios web confiables. Cuando tenemos problemas, queremos depurarlos rápidamente y con confianza, comprendiendo la causa raíz de lo que está sucediendo. Queremos sitios web de alto rendimiento y queremos comprender los problemas de rendimiento que están ocurriendo para poder mejorarlos. En última instancia, queremos sitios confiables y de alto rendimiento para tener una experiencia de usuario positiva. Para que las personas puedan ir a nuestros sitios web y lograr con éxito lo que vinieron a hacer. También queremos tener una buena experiencia de desarrollo. Debería ser lo menos doloroso posible. Escribir, lanzar y mantener código. Creo que una de las cosas más frustrantes como desarrollador es tratar de reproducir un error realmente, realmente difícil de reproducir donde no tienes pistas, no tienes idea de por dónde empezar. Y te quedas, ya sabes, vagando sin rumbo a través de tus registros, a través de cualquier tipo de migajas de pan que tengas para comenzar. Entonces, la observabilidad es una herramienta en nuestra caja de herramientas a la que podemos recurrir para ayudar a lograr algunos de esos objetivos. Este concepto proviene de la teoría del control. Y una definición formal sería tener la capacidad de inferir el estado de un sistema interno en función de sus salidas. Entonces, cuando pensamos en nuestras aplicaciones front-end que se ejecutan en dispositivos de usuarios finales, son como una
2. Tipos de Datos de Observabilidad
Podemos obtener información sobre cómo se están ejecutando nuestras aplicaciones en producción utilizando la observabilidad. Las métricas, los registros y las trazas son tipos de datos fundamentales que ayudan a lograr la observabilidad. Las métricas proporcionan tipos de datos agregados, pero las trazas y los registros son importantes para obtener información más detallada. Las trazas ofrecen una descripción detallada del flujo de solicitudes entre límites de servicio, mientras que los registros proporcionan un flujo lineal de eventos. Tener todos estos tipos de datos y correlacionarlos es crucial para lograr la observabilidad.
3. Exemplares, OpenTelemetry e Instrumentación
Un flujo útil es pasar de una métrica de alto nivel a una traza con ejemplares. OpenTelemetry es un estándar de código abierto para datos de observabilidad. Tiene una especificación e implementaciones específicas del lenguaje. La instrumentación se realiza manualmente o automáticamente.
Y así, un flujo muy útil es pasar de una métrica que es una vista agregada de alto nivel a una traza que contribuyó a esa métrica. Eso es una característica llamada ejemplares, que puede ser realmente útil, ya sabes. Estás viendo tu panel de carga de página y ves que hay un pico a las 2 p.m., y puedes hacer clic en un ejemplar en ese punto y ver que es un ejemplo de una carga de página que contribuyó a esa métrica. Y luego, tal vez obtengas más información cuando estás viendo el ejemplo específico en lugar de una visión general agregada. Así que veamos cómo Homestar Runner podría aplicar estos conceptos en su aplicación. Al mirar la aplicación de demostración, tienen un frontend de React, un backend de Node y trabajan con una base de datos de Postgres. Una vez que tienes tu aplicación, necesitas alguna forma de recopilar los datos de telemetría, y ahí es donde entra en juego algo como OpenTelemetry. Juega el papel de instrumentación donde recopilas los diferentes datos en los que estás interesado. A partir de ahí, necesitas enviarlo a algún lugar para almacenarlo a largo plazo. Aquí es donde entran en juego herramientas de código abierto como Tempo, Loki y Mamir. Almacenan trazas, registros y métricas, respectivamente, y tienen otras herramientas con ellas, como Queryers, que te permiten buscar los datos en los que estás interesado. A partir de ahí, una capa de visualización es útil para poder reunir y correlacionar todos esos datos en un solo lugar. Así que profundicemos en OpenTelemetry.
OpenTelemetry es un estándar de código abierto para datos de observabilidad. Tiene una especificación que define cosas como qué es una traza, qué es un registro, qué es una métrica, en qué formatos vienen, cómo se usan, así como convenciones semánticas. ¿Qué datos se recopilarán siempre? ¿Bajo qué nombres aparecerán? A partir de ahí, hay implementaciones específicas del lenguaje de la especificación como APIs y SDKs. Por ejemplo, para JavaScript, eso significa que hay paquetes de NPM que nosotros, como usuarios finales, como desarrolladores, podemos descargar y usar en nuestras aplicaciones para recopilar métricas, registros y trazas. A partir de ahí, hay otros componentes como exportadores, que se encargan de enviar los datos de nuestras aplicaciones que hemos recopilado a cualquier backend que estemos usando para almacenarlos, y el recolector. Veamos un ejemplo de instrumentación.
Este pequeño fragmento de código es cómo configurarías las métricas en una aplicación de notas. En la línea dos, estás importando el proveedor de medidores del paquete base de métricas del SDK de OpenTelemetry. En la línea cinco, lo instancias para obtener un medidor, este tipo de objeto de alto nivel que puedes usar para crear métricas. En las líneas 10 y 15, vemos un ejemplo de eso. En la línea 10, creamos un instrumento, que se utilizará para recopilar un solo punto de datos. En este caso, es el número de transacciones. En la línea 15, tienes métodos muy simples con los instrumentos que estás creando, como add, donde puedes incrementar una métrica que tienes en un número específico, o puedes registrar un ejemplo específico. Este es un ejemplo de instrumentación manual. Donde vas a lo largo de tu código base, recopilas estos puntos de datos cuando ocurre un evento, incrementas un valor, o agregas una traza o escribes un registro usando tu registrador, etc. Haces esto manualmente en toda tu aplicación, lo cual es un poco de trabajo, pero te da un alto nivel de control sobre los datos que estás recopilando. En contraste con la instrumentación manual,
4. Recopilación y transporte de datos
Estos son paquetes creados por la comunidad de OpenTelemetry que recopilan datos automáticamente. Registrar una instrumentación es sencillo. Ejemplos para el frontend incluyen la carga del documento y la interacción del usuario. Los eventos clave a rastrear son la carga de la página, eventos de navegación, acciones significativas del usuario, errores y descarga de la página. Recopilar atributos como datos de la aplicación, capacidades y metadatos de la aplicación puede proporcionar información valiosa. Los procesadores y exportadores se encargan de la recopilación y el transporte de datos, con opciones para enviar datos a Tempo, Loki o Mimir. El recolector puede actuar como un componente intermedio con fines de seguridad.
5. Recopilación de datos y seguridad
Tener el recolector en funcionamiento puede agregar beneficios de seguridad al verificar los orígenes permitidos, realizar limitación de velocidad y almacenar secretos. Esto es especialmente relevante para aplicaciones de frontend.
6. Data Source, Visualization, and Examples
Tenemos una fuente de datos y una capa de visualización utilizando Grafana. En Grafana, puedes configurar fuentes de datos, escribir consultas y personalizar paneles para visualizar tus datos. Los ejemplos incluyen rendimiento web, excepciones y trazas. Puedes marcar despliegues en los gráficos para analizar su impacto en el rendimiento web. Las excepciones se pueden segmentar y analizar según atributos como URL o navegadores. Kufana permite vincular fuentes de datos para ver el flujo exacto de solicitudes y correlaciones. Las trazas muestran el recorrido de la solicitud y los atributos recopilados, incluidos los detalles de la consulta y los efectos de error. Los spans muestran cómo interactúan diferentes partes de la solicitud.
Otro panel que sería especialmente relevante es el de excepciones. Sabes, ver los mensajes en bruto que estás recibiendo, sabemos que tenemos 12 excepciones en el último período de tiempo relacionadas con helmet, esperando una cadena como hijo de title, sabes, tenemos algún error en alguna página. Y luego podemos segmentar y analizar esos datos de diferentes formas según los atributos que recopilamos anteriormente. Por ejemplo, si recopilamos la URL en la que se producen las excepciones, entonces podemos tener este panel adicional que muestra las principales URL por cantidad de excepciones. Entonces, vemos ahí, okay, la página de la función, algo está sucediendo, deberíamos echarle un vistazo a eso. O ver las excepciones por navegador, por ejemplo. Estos son solo ejemplos de diferentes formas en las que puedes dividir y consultar tus datos según los atributos que estás recopilando. Tal vez quieras ver las excepciones por feature flag para ver si un cierto feature flag está causando muchos errores. Y este panel brinda una visión general de alto nivel, pero algo realmente interesante que puedes hacer en Kufana es vincular estas diferentes fuentes de datos. Entonces ves estos errores, y tal vez quieras hacer clic y ver un ejemplo de eso. Y eso se vincularía a una traza donde ocurrió ese error. Y luego puedes ver la solicitud exacta desde el frontend hasta el backend hasta la base de datos que causó ese error. Y ahí es donde esa correlación se vuelve realmente, realmente importante. Entonces, este es un ejemplo de cómo utilizar paneles con métricas y registros para brindar una visión general del rendimiento web y las excepciones. Veamos un par de ejemplos de trazas. Este primer ejemplo es una traza bastante tradicional que muestra una solicitud que va desde un frontend a una API hasta la base de datos, y podemos ver los tipos de datos que estamos recopilando sobre ella como atributos. Tenemos, por ejemplo, la declaración, la consulta exacta que se estaba ejecutando y qué parámetros se pasaron. Si ocurre un error, esa sería información muy útil para saber qué consulta exacta se ejecutó que causó ese error y qué efectos tuvo aguas arriba. También obtenemos una vista interesante de cómo interactúan las diferentes secciones de las solicitudes, que se llaman spans, entre sí. Por ejemplo, la duración total de esta solicitud POST, según lo que ve el frontend, es de 27 milisegundos, de los cuales 16 milisegundos ocurrieron en la API.
7. Observability Data Insights
Podemos obtener información sobre la duración de las consultas individuales y recopilar datos para trabajar con ellos. Las trazas capturan las interacciones del usuario, incluidos los eventos de navegación y los datos asociados a ellos. Los datos específicos del frontend, como los ID de sesión, proporcionan información valiosa sobre el comportamiento del usuario y la aparición de errores. Examinar las representaciones de los componentes nos permite analizar los tiempos de montaje y renderizado, identificar renderizados innecesarios y comprender el rendimiento de la aplicación. El seguimiento de los pipelines de CI/CD es otro caso de uso interesante. Al aprovechar estas herramientas, podemos obtener información sobre diversas partes de nuestro sistema, mejorar los objetivos de ingeniería y aumentar la confianza en la corrección de errores y la optimización del rendimiento.
Y luego podemos ver la duración de estas consultas individuales. Tal vez veamos que una consulta tarda mucho más de lo esperado, y eso nos proporciona algunos datos con los que podemos trabajar.
A continuación, se muestra un ejemplo de una interacción del usuario capturada como una traza. Se trata de un evento de navegación a una nueva página, que tardó un milisegundo. Y podemos ver algunos datos que recopilamos con eso, como el agente de usuario y la ruta X que utilizaron para navegar. Un dato realmente interesante y específico del frontend es el ID de sesión. A diferencia de un backend, donde normalmente se tiene un ciclo de vida de solicitud y respuesta muy claro, en el frontend, la sesión de un usuario, su interacción con un sitio web, no está tan claramente definida. Puede tener una duración muy larga. Puede ser de minutos, horas o incluso abarcar varios días, dependiendo de la aplicación y de cómo se defina. Crear ID de sesión y adjuntarlos a tus datos de telemetría puede brindarte mucha información sobre cómo se comportan los usuarios, a qué páginas van, con qué características interactúan, si hay errores que se producen a lo largo de una sesión. Por lo tanto, especialmente para aplicaciones frontend, tener ese ID de sesión es realmente, realmente importante.
Y finalmente, este es un ejemplo muy interesante de trazas para analizar las representaciones de los componentes. Aquí, nos conectamos a los eventos del ciclo de vida de un componente de clase de React y observamos cosas como el montaje y el renderizado del componente. Así vemos cuánto tiempo tarda un componente en montarse, cuánto tiempo tarda en renderizarse, si tiene renderizados innecesarios. En este caso, vemos que el segundo renderizado tarda 500 milisegundos, lo cual es mucho más largo que los demás. Y eso es información interesante que podemos analizar para comprender cómo se desempeñan nuestras aplicaciones. Por cierto, un uso realmente interesante de las trazas sería rastrear un pipeline de CI/CD. Las aplicaciones de esto pueden ser muy amplias y depende de nosotros, como desarrolladores, ser creativos y utilizar estas herramientas fundamentales para obtener información sobre diferentes partes de nuestro sistema, ya sean nuestras aplicaciones frontend, nuestros pipelines de CI/CD o nuestros servicios backend, etc. Y al utilizar todo esto, espero que Runner y StrongBoud comprendan mucho mejor su aplicación y tengan mucha más confianza a la hora de solucionar errores y problemas de rendimiento. Muchas gracias por escuchar. Espero que hayas aprendido algo y que puedas aplicar algunas de estas cosas a tus aplicaciones para obtener una mejor comprensión de cómo funcionan en producción. Gracias.