¿Cómo implementar Open Telemetry en C# .NET?

¿Cómo implementar Open Telemetry en C# .NET?

En esta entrada veremos cómo podemos instrumentar Open Telemetry en nuestras aplicaciones o servicios desarrollados en C# .NET.

Open Telemetry y su proactiva comunidad nos ofrece a los desarrolladores de C# .NET una serie de librerías para poder instrumentar, generar telemetría, fácilmente nuestros procesos.

Para entender lo que se va a hacer en los siguientes ejemplos es necesario conocer previamente qué es Open Telemetry y sus conceptos básicos. Te invito, si no has tenido ocasión de aprender sobre Open Telemetry, a visitar mi anterior entrada Introducción a OpenTelemetry.

A la hora de configurar el proveedor de trazas, métricas o logs nos encontramos con 3 funcionalidades distintas. Instrumentaciones (Source), Procesadores y Exportadores.

  • Instrumentaciones (Instrumentations): Activa la telemetría de trazas para las librerías / funcionalidades descritas en el método de Instrumentación.
  • Procesadores (Processors): Transforman la telemetría antes de ser exportada hacia fuera de la aplicación.
  • Exportadores (Exporters): Para indicar dónde queremos que se envíe nuestra telemetría.

Antes de empezar a instrumentar nuestro servicio deberemos escribir la siguiente instrucción en cada uno de los hosts (en primera línea de Program.cs) para poder usar canal GRPC de HTTP2 sin TLS para que el host pueda comunicarse con el componente de OTEL Collector a través del puerto GRPC.

1
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

Y por último añadir paquete NuGet OpenTelemetry a nuestro csproj.

Ya estamos ready para continuar con la implementación de la telemetría.

¿Cómo instrumentar con Open Telemetry las trazas en .NET?

Ejemplo de código de una implementación básica de OpenTelemetry en la vertical de telemetría de trazas y explicación de la misma.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var assemblyName = typeof(Program).Assembly.GetName();
services.AddOpenTelemetryTracing(builder =>
{
    builder.SetResourceBuilder(ResourceBuilder.CreateDefault()
        .AddService(serviceName: assemblyName.Name,
            serviceVersion: assemblyName.Version!.ToString()));
 
    builder
        .AddAspNetCoreInstrumentation()
        .AddHttpClientInstrumentation(options =>
        {
            options.SetHttpFlavor = true;
            options.RecordException = true;
        })
        #if DEBUG
        .AddConsoleExporter()
        #endif
        .AddOtlpExporter(options => 
            options.Endpoint = new Uri("http://localhost:4317"));
});

.AddOpenTelemetryTracing registra el proveedor de trazas de Open Telemetry y nos provee de una sobrecarga en la que podremos configurar el builder del mismo.

.SetResourceBuilder establece el nombre que tendrá el servicio en todo su envío de telemetría de trazas. En el ejemplo se crea el resource por defecto y se le añade la información del servicio con el nombre y la versión del assembly. La versión es importante porque cuando queramos analizar flujos en nuestro proveedor podremos identificar en cuáles versiones de la aplicación se ha reproducido ese error.

Instrumentaciones automáticas de trazas con OpenTelemetry

Cliente de Http
Para añadir instrumentación automática de llamadas http de nuestro servicio. Añadir paquete NuGet OpenTelemetry.Instrumentation.Http a nuestro csproj. El código fuente y su documentación lo encontrarás en el siguiente repo: https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Instrumentation.Http.

AspNetCore
Para añadir instrumentación automática de AspNetCore, como por ejemplo llamadas a la API, a nuestro servicio. Uso habitual en APIs. Añadir paquete NuGet OpenTelemetry.Instrumentation.AspNetCore a nuestro csproj. El código fuente y su documentación lo encontrarás en el siguiente repo: https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Instrumentation.AspNetCore.

¡Quiero más instrumentaciones automáticas!
Podemos encontrar muchas más instrumentaciones en los repo oficiales https://github.com/open-telemetry/opentelemetry-dotnet y https://github.com/open-telemetry/opentelemetry-dotnet-contrib al igual que en diferentes contribuciones que hacen proveedores de productos o la comunidad.

Exportadores de trazas con OpenTelemetry

Consola
Exporta las trazas a la consola.
Añadir paquete NuGet OpenTelemetry.Exporter.Console a nuestro csproj.
La recomendación es usar éste exportador únicamente en debug. A nivel de código el ejemplo está en los extractos de ejemplo y a nivel de nuget sería tal que así:

1
2
3
<ItemGroup Condition="'$(Configuration)'=='DEBUG'">
    <PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.3.0" /* Versión actual en el momento de escribir esta entrada */ />
</ItemGroup>

El código fuente y su documentación lo encontrarás en el siguiente repo: https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Exporter.Console.

OTLP (Open Telemetry Protocol)
Exporta las trazas a cualquier endpoint que acepte el protocolo OTLP, por ejemplo OTEL Collector, NewRelic o Aspecto.
Añadir paquete NuGet OpenTelemetry.Exporter.OpenTelemetryProtocol a nuestro csproj.
El código fuente y su documentación lo encontrarás en el siguiente repo: https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.

¡Quiero más exportadores!
Podemos encontrar muchos más exportadores en los repo oficiales https://github.com/open-telemetry/opentelemetry-dotnet y https://github.com/open-telemetry/opentelemetry-dotnet-contrib al igual que en diferentes contribuciones que hacen proveedores de productos o la comunidad.

¿Cómo instrumentar con Open Telemetry las métricas en .NET?

Ejemplo de código de una implementación básica de OpenTelemetry en la vertical de telemetría de métricas y explicación de la misma.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var assemblyName = typeof(HostServiceCollectionExtensions).Assembly.GetName();
 
services.AddOpenTelemetryMetrics(builder =>
{
    builder.SetResourceBuilder(ResourceBuilder.CreateDefault()
        .AddService(serviceName: assemblyName.Name,
            serviceVersion: assemblyName.Version!.ToString()));

    builder
        .AddAspNetCoreInstrumentation()
        .AddHttpClientInstrumentation()
        #if DEBUG
        .AddConsoleExporter()
        #endif
        .AddOtlpExporter(options => 
            options.Endpoint = new Uri("http://localhost:4317"));
});

.AddOpenTelemetryMetrics registra el proveedor de métricas de Open Telemetry y nos provee de una sobrecarga en la que podremos configurar el builder del mismo.

.SetResourceBuilder establece el nombre que tendrá el servicio en todo su envío de telemetría de métricas. En el ejemplo se crea el resource por defecto y se le añade la información del servicio con el nombre y la versión del assembly. La versión es importante porque cuando queramos analizar métricas en nuestro proveedor podremos identificar en cuáles versiones de la aplicación se han reproducido determinadas métricas.

Instrumentaciones automáticas de métricas con OpenTelemetry

Cliente de Http
Para añadir instrumentación automática de llamadas http de nuestro servicio. Añadir paquete NuGet OpenTelemetry.Instrumentation.Http a nuestro csproj. El código fuente y su documentación lo encontrarás en el siguiente repo: https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Instrumentation.Http.

AspNetCore
Para añadir instrumentación automática de AspNetCore, como por ejemplo llamadas a la API, a nuestro servicio. Uso habitual en APIs. Añadir paquete NuGet OpenTelemetry.Instrumentation.AspNetCore a nuestro csproj. El código fuente y su documentación lo encontrarás en el siguiente repo: https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Instrumentation.AspNetCore.

¡Quiero más instrumentaciones automáticas!
Podemos encontrar muchas más instrumentaciones en los repositorios oficiales https://github.com/open-telemetry/opentelemetry-dotnet y https://github.com/open-telemetry/opentelemetry-dotnet-contrib al igual que en diferentes contribuciones que hacen proveedores de productos o la comunidad.

Exportadores de métricas con OpenTelemetry

Consola
Exporta las métricas a la consola.
Añadir paquete NuGet OpenTelemetry.Exporter.Console a nuestro csproj.
La recomendación es usar éste exportador únicamente en debug. A nivel de código el ejemplo está en los extractos de ejemplo y a nivel de nuget sería tal que así:

1
2
3
<ItemGroup Condition="'$(Configuration)'=='DEBUG'">
    <PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.3.0" /* Versión actual en el momento de escribir esta entrada */ />
</ItemGroup>

El código fuente y su documentación lo encontrarás en el siguiente repo: https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Exporter.Console.

OTLP (Open Telemetry Protocol)
Exporta las trazas a cualquier endpoint que acepte el protocolo OTLP, por ejemplo OTEL Collector, NewRelic o Aspecto.
Añadir paquete NuGet OpenTelemetry.Exporter.OpenTelemetryProtocol a nuestro csproj.
El código fuente y su documentación lo encontrarás en el siguiente repo: https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.

¡Quiero más exportadores!
Podemos encontrar muchos más exportadores en los repositorios oficiales https://github.com/open-telemetry/opentelemetry-dotnet y https://github.com/open-telemetry/opentelemetry-dotnet-contrib al igual que en diferentes contribuciones que hacen proveedores de productos o la comunidad.

¿Cómo instrumentar con Open Telemetry los logs en .NET?

Ejemplo de código de una implementación básica de OpenTelemetry en la vertical de telemetría de logs y explicación de la misma.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var assemblyName = typeof(Program).Assembly.GetName();
 
loggingBuilder.AddOpenTelemetry(options =>
{
    options.SetResourceBuilder(ResourceBuilder.CreateDefault()
        .AddService(serviceName: assemblyName.Name,
            serviceVersion: assemblyName.Version!.ToString()));

    options.IncludeFormattedMessage = true;
    options.IncludeScopes = true;

    options
        #if DEBUG
        .AddConsoleExporter()
        #endif
        .AddOtlpExporter(opts =>
            opts.Endpoint = new Uri("http://localhost:4317"));
});

.AddOpenTelemetry registra el proveedor de logs de Open Telemetry como uno de los proveedor de ILogger y nos provee de una sobrecarga en la que podremos configurar el builder del mismo. Al estar registrado como proveedor de ILogger todo log que codifiquemos en nuestra aplicación ya será tratado y exportado por el proveedor configurado de OpenTelemetry.

.SetResourceBuilder establece el nombre que tendrá el servicio en todo su envío de telemetría de logs. En el ejemplo se crea el resource por defecto y se le añade la información del servicio con el nombre y la versión del assembly. La versión es importante porque cuando queramos analizar logs en nuestro proveedor podremos identificar en cuáles versiones de la aplicación se han producido determinados.

Exportadores de logs con OpenTelemetry

Consola
Exporta los logs a la consola.
Añadir paquete NuGet OpenTelemetry.Exporter.Console a nuestro csproj.
La recomendación es usar éste exportador únicamente en debug. A nivel de código el ejemplo está en los extractos de ejemplo y a nivel de nuget sería tal que así:

1
2
3
<ItemGroup Condition="'$(Configuration)'=='DEBUG'">
    <PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.3.0" /* Versión actual en el momento de escribir esta entrada */ />
</ItemGroup>

El código fuente y su documentación lo encontrarás en el siguiente repo: https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Exporter.Console.

OTLP (Open Telemetry Protocol)
Exporta las trazas a cualquier endpoint que acepte el protocolo OTLP, por ejemplo OTEL Collector, NewRelic o Aspecto.
Añadir paquete NuGet OpenTelemetry.Exporter. OpenTelemetryProtocol.Logs a nuestro csproj.
El código fuente y su documentación lo encontrarás en el siguiente repo: https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs.

¡Quiero más exportadores!
Podemos encontrar muchos más exportadores en los repositorios oficiales https://github.com/open-telemetry/opentelemetry-dotnet y https://github.com/open-telemetry/opentelemetry-dotnet-contrib al igual que en diferentes contribuciones que hacen proveedores de productos o la comunidad.

comentarios provistos por Disqus