Observabilidad de .NET con OpenTelemetry

Cuando ejecute una aplicación, querrá saber su rendimiento y detectar posibles problemas antes de que se agraven. Puede hacerlo emitiendo datos de telemetría como registros o métricas de la aplicación y, a continuación, supervisando y analizando esos datos.

¿Qué es la observabilidad?

La observabilidad en el contexto de un sistema distribuido es la capacidad de supervisar y analizar la telemetría sobre el estado de cada componente, para poder observar los cambios en el rendimiento y diagnosticar por qué se producen esos cambios. A diferencia de la depuración, que es invasiva y puede afectar a la operación de la aplicación, la observabilidad pretende ser transparente a la operación principal y tener un impacto en el rendimiento lo suficientemente reducido como para que pueda utilizarse de forma continua.

La observabilidad se realiza normalmente mediante una combinación de:

  • Registros, que registran operaciones individuales, como una solicitud entrante, un error en un componente específico o un pedido que se realiza.
  • Métricas, que miden contadores y medidores, como el número de solicitudes completadas, solicitudes activas, widgets que se han vendido; o un histograma de la latencia de solicitud.
  • Seguimiento distribuido, que realiza un seguimiento de las solicitudes y actividades entre componentes de un sistema distribuido para que pueda ver dónde se invierte el tiempo y realizar un seguimiento de errores específicos.

Juntos, los registros, las métricas y el seguimiento distribuido se conocen a veces como los tres pilares de observabilidad.

Cada pilar puede incluir datos de telemetría de:

  • El entorno de ejecución de .NET, como el recolector de elementos no utilizados o el compilador JIT.
  • Bibliotecas, como las de Kestrel (el servidor web de ASP.NET) y HttpClient.
  • Telemetría específica de la aplicación generada por tu código.

Enfoques de observabilidad en .NET

Hay varias maneras diferentes de lograr la observabilidad en las aplicaciones de .NET:

  • Explícitamente en el código, consultando y utilizando una biblioteca como OpenTelemetry. Si tiene acceso al código fuente y puede recompilar la aplicación, este es el mecanismo más eficaz y configurable.
  • Fuera de proceso mediante EventPipe. Las herramientas como dotnet-monitor pueden escuchar registros y métricas y, a continuación, procesarlos sin afectar al código.
  • Usando un gancho de inicio, se pueden inyectar ensamblados en el proceso que luego pueden recolectar instrumentación. Un ejemplo de este enfoque es la Instrumentación automática de OpenTelemetry .NET.

¿Qué es OpenTelemetry?

OpenTelemetry (OTel) es un estándar multiplataforma abierto para recopilar y emitir datos de telemetría. OpenTelemetry incluye:

  • API para bibliotecas que se pueden utilizar para registrar datos de telemetría mientras se ejecuta el código.
  • APIs que los desarrolladores de aplicaciones utilizan para configurar qué parte de los datos registrados se enviarán a través de la red, a dónde se enviarán y cómo pueden filtrarse, almacenarse en búfer, enriquecerse y transformarse.
  • Las convenciones semánticas proporcionan orientación sobre la denominación y el contenido de los datos telemétricos. Es importante que las aplicaciones que producen datos telemétricos y las herramientas que reciben los datos se pongan de acuerdo sobre lo que significan los distintos tipos de datos y qué clase de datos son útiles para que las herramientas puedan proporcionar un análisis eficaz.
  • Una interfaz para exportadores. Los exportadores son complementos que permiten transmitir datos de telemetría en formatos específicos a diferentes back-end de telemetría.
  • El protocolo de conexión OTLP es una opción de protocolo de red neutral del proveedor para transmitir datos de telemetría. Algunas herramientas y proveedores admiten este protocolo además de los protocolos propietarios preexistentes que pueden tener.

El uso de OTel permite el uso de una amplia variedad de sistemas APM, incluidos sistemas de código abierto como Prometheus y Grafana, Azure Monitor: producto de APM de Microsoft en Azure o de muchos proveedores de APM que se asocian con OpenTelemetry.

Hay implementaciones de OpenTelemetry para la mayoría de lenguajes y plataformas, incluido .NET.

Implementación de .NET de OpenTelemetry

La implementación de OpenTelemetry de .NET es un poco diferente de otras plataformas, ya que .NET proporciona las API de registro, métricas y actividad en el marco. Eso significa que OTel no necesita proporcionar API para que las utilicen los autores de bibliotecas. La implementación de OTel de .NET usa estas API de plataforma para la instrumentación:

 Arquitectura OTel de .NET

Donde OTel entra en juego es que recoge telemetría de esas API y otras fuentes (a través de bibliotecas de instrumentación) y luego las exporta a un sistema de monitorización del rendimiento de las aplicaciones (APM) para su almacenamiento y análisis. La ventaja que OTel aporta como estándar del sector es un mecanismo común para la recopilación, los esquemas comunes y la semántica de los datos de telemetría, y una API para cómo se pueden integrar las API con OTel. El uso de OTel significa que las aplicaciones no necesitan usar API o estructuras de datos específicas de APM; funcionan con el estándar OTel. Los APM pueden implementar un componente exportador específico de APM o usar OTLP, que es un nuevo estándar de transmisión para exportar datos de telemetría a los sistemas APM.

Paquetes de OpenTelemetry

OpenTelemetry en .NET se implementa como una serie de paquetes NuGet que forman un par de categorías:

  • API principal
  • Instrumentación: estos paquetes recopilan instrumentación del tiempo de ejecución y de las bibliotecas comunes.
  • Exportadores: estos se interrelacionan con sistemas APM como Prometheus, Jaeger y OTLP.

La siguiente tabla describe los principales paquetes.

Nombre del paquete Descripción
OpenTelemetry Biblioteca principal que proporciona la funcionalidad principal de OTEL
OpenTelemetry.Instrumentation.AspNetCore Instrumentación para ASP.NET Core y Kestrel
OpenTelemetry.Instrumentation.GrpcNetClient Instrumentación para el cliente gRPC para realizar un seguimiento de las llamadas gRPC salientes
OpenTelemetry.Instrumentation.Http Instrumentación para HttpClient y HttpWebRequest para el seguimiento de las llamadas HTTP salientes
OpenTelemetry.Instrumentation.SqlClient Instrumentación para SqlClient utilizada para rastrear las operaciones de la base de datos
OpenTelemetry.Exporter.Console Exportador de la consola, que se usa normalmente para diagnosticar qué telemetría se está exportando
OpenTelemetry.Exporter.OpenTelemetryProtocol Exportador que usa el protocolo OTLP
OpenTelemetry.Exporter.Prometheus.AspNetCore Exportador de Prometheus implementado a través de un endpoint de ASP.NET Core
OpenTelemetry.Exporter.Zipkin Exportador para el seguimiento de Zipkin

Ejemplos

Este tema continúa con un par de tutoriales de ejemplo para usar OpenTelemetry en .NET:

OpenTelemetry en Aspire

Aspire es un conjunto de extensiones para .NET que facilita la creación y el manejo de aplicaciones distribuidas. Una de las ventajas de usar Aspire es que la telemetría está integrada, mediante las bibliotecas de OpenTelemetry para .NET. Las plantillas de proyecto predeterminadas para Aspire contienen un ServiceDefaults proyecto, en el cual se incluye la configuración y ajuste de OTel. Cada servicio en una solución Aspire referencia e inicializa el proyecto Service Defaults.

La plantilla de proyecto de Service Defaults incluye el SDK de OTel, ASP.NET, HttpClient y los paquetes de instrumentación en tiempo de ejecución, que se configuran en el archivo Extensions.cs. Para exportar la telemetría, Aspire incluye el exportador de OTLP de forma predeterminada para que pueda proporcionar visualización de telemetría mediante el Aspire panel.

El Aspire panel está diseñado para llevar la observación de telemetría al ciclo de depuración local, lo que permite a los desarrolladores no solo asegurarse de que las aplicaciones producen telemetría, sino que también usan esa telemetría para diagnosticar esas aplicaciones localmente. La posibilidad de observar las llamadas entre servicios resulta ser tan útil en tiempo de depuración como en producción. El panel de Aspire se inicia automáticamente al presionar F5 en el AppHost proyecto desde Visual Studio o en el dotnet runAppHost proyecto.

Aspire Panel

Para obtener más detalles sobre Aspire, consulte:

Reutilización del proyecto de valores predeterminados del servicio sin Aspire orquestación

Probablemente la manera más fácil de configurar OTel para proyectos de ASP.NET es usar el proyecto Aspire Service Defaults, incluso si no usa el resto de Aspire como AppHost para orquestación. El proyecto Service Defaults está disponible como plantilla de proyecto a través de Visual Studio o dotnet new. Configura OTel y establece el exportador de OTLP. A continuación, puede usar las variables de entorno de OTel para configurar el punto de conexión de OTLP para enviar telemetría y proporcionar las propiedades de recursos para la aplicación.

Los pasos para usar ServiceDefaults fuera Aspire son:

  • Agregue el proyecto ServiceDefaults a la solución mediante Agregar nuevo proyecto en Visual Studio o use dotnet new aspire-servicedefaults --output ServiceDefaults.
  • Haga referencia al proyecto ServiceDefaults desde la aplicación de ASP.NET. En Visual Studio, use Agregar>referencia de proyecto y seleccione el proyecto ServiceDefaults .
  • Llame a su función de configuración openTelemetry como parte de la inicialización del generador de aplicaciones.
var builder = WebApplication.CreateBuilder(args);
builder.ConfigureOpenTelemetry();

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Los valores predeterminados del servicio pueden configurar la siguiente funcionalidad adicional, si es necesario, a través de AddServiceDefaults() o de las funciones específicas.

  • Comprobaciones de estado con puntos de conexión /health y /alive.
  • Detección de servicios, que será una operación nula sin el resto de Aspire.
  • Configuración de la resiliencia para HttpClient, que reintenta las solicitudes en caso de fallos.