Cómo manejar registros en microservicios

El registro es una de las partes más importantes de los sistemas de software. Ya sea que haya comenzado a trabajar en una nueva pieza de software o que su sistema se esté ejecutando en un entorno de producción a gran escala, siempre se encontrará buscando ayuda en los archivos de registro.

Debido a esto, los registros son lo primero que buscan los desarrolladores cuando algo sale mal o algo no funciona como se esperaba.

Registrar la información correcta de la manera correcta hace que la vida de un desarrollador sea mucho más fácil. Y para mejorar en el registro, necesita saber qué y cómo registrar.

En este artículo, echaremos un vistazo a algunas de las etiquetas básicas de registro que pueden ayudarlo a aprovechar al máximo sus registros.

Qué registrar y cómo funciona el registro

Comencemos con un ejemplo de un sistema de comercio electrónico y echemos un vistazo al inicio de sesión en su Servicio de gestión de pedidos (OMS).

Suponga que el pedido de un cliente falla debido a un error del Servicio de administración de inventario (IMS), un servicio posterior que OMS usa para verificar el inventario disponible.

Supongamos que OMS ya ha aceptado un pedido. Pero durante el paso de verificación final, IMS devuelve el siguiente error porque el producto ya no está disponible en el inventario.

404 Product Not Available

Qué registrar

Normalmente, registraría el error de esta manera:

log.error(“Exception in fetching product information - {}”, ex.getResponseBodyAsString())

Esto generará un registro en el siguiente formato:

[2020-09-27T18:54:41,500+0530]-[ERROR]-[InventoryValidator]-[13] Exception in fetching product information - Product Not Available

Bueno, no hay mucha información disponible en esta declaración de registro, ¿verdad? Un registro como este no sirve de mucho porque carece de información contextual sobre el error.

¿Podemos agregar más información a este registro para que sea más relevante para la depuración? ¿Qué tal agregar el Id. Del pedido y el Id. Del producto?

log.error("Exception in processing Order #{} for Product #{} due to exception - {}", orderId, productId, ex.getResponseBodyAsString())

Esto generará un registro en el siguiente formato:

[2020-09-27T18:54:41,500+0530]-[ERROR]-[InventoryValidator]-[13] Exception in processing Order #182726 for Product #21 due to exception - Product Not Available

¡Ahora esto tiene mucho sentido! Al observar los registros, podemos comprender que se produjo un error al procesar el pedido n.º 182726 porque el producto n.º 21 no estaba disponible.

Cómo iniciar sesión

Si bien el registro anterior tiene mucho sentido para los humanos, puede que no sea el mejor formato para las máquinas. Veamos un ejemplo para entender por qué.

Suponga que hay algún problema en la disponibilidad de un determinado producto (por ejemplo, el producto n. ° 21) debido a que todos los pedidos que contienen ese producto están fallando. Se le ha asignado la tarea de encontrar todos los pedidos fallidos de este producto.

Felizmente hace un greppara el Producto # 21 en sus registros y espera con entusiasmo los resultados. Cuando se completa la búsqueda, obtiene algo como esto

[2020-09-27T18:54:41,500+0530]-[ERROR]-[InventoryValidator]-[13] Exception in processing Order #182726 for Product #21 due to exception - Product Not Available [2020-09-27T18:53:29,500+0530]-[ERROR]-[InventoryValidator]-[13] Exception in processing Order #972526 for Product #217 due to exception - Product Not Available [2020-09-27T18:52:34,500+0530]-[ERROR]-[InventoryValidator]-[13] Exception in processing Order #46675754 for Product #21 due to exception - Product Not Available [2020-09-27T18:52:13,500+0530]-[ERROR]-[InventoryValidator]-[13] Exception in processing Order #332254 for Product #2109 due to exception - Product Not Available

No es exactamente lo que esperabas, ¿verdad? Entonces, ¿cómo puedes mejorar esto? La tala estructurada al rescate.

¿Qué es el registro estructurado?

El registro estructurado resuelve estos problemas comunes y permite que las herramientas de análisis de registros proporcionen capacidades adicionales. Los registros escritos en un formato estructurado son más amigables con la máquina, lo que significa que una máquina puede analizarlos fácilmente.

Esto puede resultar útil en los siguientes escenarios:

  • Los desarrolladores pueden buscar registros y correlacionar eventos, lo cual es invaluable tanto durante el desarrollo como para solucionar problemas de producción.
  • Los equipos comerciales pueden analizar estos registros y realizar análisis sobre ciertos campos (por ejemplo, recuento de productos únicos por día) extrayendo y resumiendo estos campos.
  • Puede crear paneles (tanto comerciales como técnicos) analizando los registros y realizando agregados sobre los campos relevantes.

Usemos nuestra declaración de registro anterior y hagamos un pequeño cambio para estructurarlo.

log.error("Exception in processing OrderId={} for ProductId={} due to Error={}", orderId, productId, ex.getResponseBodyAsString())

Esto generará un registro en el siguiente formato:

[2020-09-27T18:54:41,500+0530]-[ERROR]-[InventoryValidator]-[13] Exception in processing OrderId=182726 for ProductId=21 due to Error=Product Not Available

Ahora, la máquina puede analizar fácilmente este mensaje de registro utilizando "=" como delimitador para extraer los campos OrderId, ProductIdy Error. Ahora podemos hacer una búsqueda exacta ProductId=21para realizar nuestra tarea.

Esto también nos permite realizar analíticas más avanzadas en los registros, como preparar un informe de todos los pedidos que fallaron con tales errores.

Si usa un sistema de administración de registros como Splunk, la consulta Error=”Product Not Available” | stats count by ProductIdahora puede producir el siguiente resultado:

+-----------+-------+ | ProductId | count | +-----------+-------+ | 21 | 5 | | 27 | 12 | +-----------+-------+

También podríamos usar un diseño JSON para imprimir nuestros registros en formato JSON:

{ "timestamp":"2020-09-27T18:54:41,500+0530" "level":"ERROR" "class":"InventoryValidator" "line":"13" "OrderId":"182726" "ProductId":"21" "Error":"Product Not Available" }

Es importante comprender el enfoque detrás del registro estructurado. No existe un estándar fijo y se puede hacer de muchas formas diferentes.

Conclusión

En este artículo, vimos las trampas de la tala no estructurada y los beneficios y ventajas que ofrece la tala estructurada.

Los sistemas de gestión de registros como Splunk se benefician enormemente de un mensaje de registro bien estructurado y pueden ofrecer una búsqueda y análisis sencillos de los eventos de registro.

The biggest challenge however, when it comes to structured logging, is establishing a standard set of fields for your software. This can be achieved by following a custom logging model or centralised logging which ensures that all developers use the same fields in their log messages.

Thank you for staying with me so far. Hope you liked the article. You can connect with me on LinkedIn where I regularly discuss technology and life. Also take a look at some of my other articles. Happy reading. ?