Observabilité .NET avec OpenTelemetry

Lorsque vous exécutez une application, vous voulez connaître les performances de l’application et détecter les problèmes éventuels avant qu’ils ne prennent de l’ampleur. Vous pouvez le faire en émettant des données télémétriques telles que des journaux ou des métriques à partir de votre application, puis en surveillant et en analysant ces données.

Qu’est-ce que l’observabilité ?

L’observabilité dans le contexte d’un système distribué est la possibilité de surveiller et d’analyser la télémétrie sur l’état de chaque composant, d’être en mesure d’observer les variations des performances et de diagnostiquer la raison pour laquelle celles-ci se produisent. Contrairement au débogage, qui est envahissant et peut affecter le fonctionnement de l’application, l’observabilité est destinée à être transparente pour l’opération principale et à avoir un impact sur les performances suffisamment faible pour pouvoir être utilisée en continu.

L’observabilité est généralement effectuée à l’aide d’une combinaison des éléments suivants :

  • Des journaux, qui enregistrent des opérations individuelles, telles qu’une requête entrante, une défaillance dans un composant spécifique ou une commande passée.
  • Des métriques, qui mesurent des compteurs et des jauges tels que le nombre de requêtes terminées, les requêtes actives, les widgets vendus ou un histogramme de la latence de requête.
  • Un suivi distribué, qui effectue le suivi des requêtes et des activités entre les composants d’un système distribué afin de voir où le temps est passé et de suivre des défaillances spécifiques.

Ensemble, les journaux, les métriques et le traçage distribué constituent les trois piliers de l'observabilité.

Il est possible que chaque pilier inclue des données de télémétrie des éléments suivants :

  • Le runtime .NET, tel que le récupérateur de mémoire ou le compilateur JIT.
  • Des bibliothèques, telles que Kestrel (le serveur web ASP.NET) et HttpClient.
  • Une télémétrie spécifique à l’application émise par votre code.

Approches d’observabilité dans .NET

Il existe plusieurs façons d’atteindre l’observabilité dans des applications .NET :

  • Explicitement dans le code, en référençant et en utilisant une bibliothèque comme OpenTelemetry. Si vous avez accès au code source et que vous pouvez régénérer l’application, il s’agit du mécanisme le plus puissant et le plus configurable.
  • Out-of-process (hors processus) en utilisant EventPipe. *Des outils tels que dotnet-monitor peuvent écouter des journaux et des métriques, puis les traiter sans affecter de code.
  • En tirant parti d’un crochet de démarrage, des assemblys peuvent être injectés dans le processus qui peut ensuite collecter une instrumentation. L’Instrumentation automatique dans .NET OpenTelemetry est un exemple de cette approche.

Qu’est-ce qu’OpenTelemetry ?

OpenTelemetry (OTel) est une norme ouverte multiplateforme destinée à la collecte et l’émission de données de télémétrie. OpenTelemetry comprend :

  • Des API pour des bibliothèques à utiliser pour enregistrer des données de télémétrie pendant l’exécution du code.
  • Des API que les développeurs d’applications utilisent pour configurer la partie des données enregistrées qui sera envoyée sur le réseau, l’emplacement vers lequel elle est envoyée et la manière dont elle peut être filtrée, mise en mémoire tampon, enrichie et transformée.
  • Les conventions sémantiques fournissent des conseils sur l’attribution de noms et le contenu des données de télémétrie. Il est important que les applications qui produisent des données de télémétrie et les outils recevant celles-ci s’entendent sur la définition des différents types de données et les types de données utiles afin que les outils puissent fournir une analyse efficace.
  • Interface pour des exporters. Les exporters sont des plug-ins qui permettent de transmettre des données de télémétrie dans des formats spécifiques à différents back-ends de télémétrie.
  • La couche physique OTLP est une option de protocole réseau indépendant du fournisseur pour transmettre des données de télémétrie. Certains outils et fournisseurs prennent en charge ce protocole, outre les protocoles propriétaires préexistants qu’ils peuvent avoir.

L’utilisation d’OTel permet d’utiliser un large éventail de systèmes de monitoring des performances (APM), notamment des systèmes open source tels que Prometheus et Grafana, Azure Monitor, le produit APM de Microsoft dans Azure, ou de nombreux fournisseurs APM partenaires d’OpenTelemetry.

Il existe des implémentations OpenTelemetry pour la plupart des langages et plateformes, notamment .NET.

Implémentation de .NET d’OpenTelemetry

L’implémentation de .NET OpenTelemetry est légèrement différente des autres plateformes, car .NET fournit une journalisation, des métriques et des API d’activité dans l’infrastructure. Cela signifie qu’OTel n’a pas besoin de fournir des API que des créateurs de bibliothèque doivent utiliser. L’implémentation de .NET d’OTel utilise ces API de plateforme pour l’instrumentation :

.NET OTel architecture

OTel joue un rôle dans la collecte de télémétrie à partir de ces API et d’autres sources (via des bibliothèques d’instrumentation), puis l’exporte vers un système de monitoring des performances des applications (APM) pour le stockage et l’analyse. L’avantage qu’OTel apporte en tant que norme du secteur d’activité est un mécanisme commun aux collections, schémas et sémantiques courants pour des données de télémétrie et une API pour l’intégration des APM à OTel. L’utilisation d’OTel signifie que les applications n’ont pas besoin d’utiliser des API ou des structures de données spécifiques à APM, elles fonctionnent en fonction de la norme OTel. Les APM peuvent soit implémenter un composant exporter spécifique à APM, soit utiliser OTLP, qui est une nouvelle norme de couche physique pour exporter des données de télémétrie vers des systèmes APM.

Packages OpenTelemetry

L’infrastructure OpenTelemetry dans .NET est implémentée sous la forme d’une série de packages NuGet qui forment deux catégories :

  • API Core
  • Instrumentation : ces packages collectent une instrumentation à partir du runtime et des bibliothèques courantes.
  • Exporters : ces systèmes interagissent avec des systèmes APM tels que Prometheus, Jaeger et OTLP.

Le tableau ci-après décrit les principaux packages.

Nom du package Description
OpenTelemetry Bibliothèque principale qui fournit les principales fonctionnalités d’OTEL
OpenTelemetry.Instrumentation.AspNetCore Instrumentation pour ASP.NET Core et Kestrel
OpenTelemetry.Instrumentation.GrpcNetClient Instrumentation pour le client gRPC afin d’effectuer un suivi des appels gRPC sortants
OpenTelemetry.Instrumentation.Http Instrumentation pour HttpClient et HttpWebRequest afin de suivre des appels HTTP sortants
OpenTelemetry.Instrumentation.SqlClient Instrumentation utilisée pour SqlClient afin de tracer des opérations de base de données
OpenTelemetry.Exporter.Console Exporter pour la console, couramment utilisé pour diagnostiquer la télémétrie qui est exportée
OpenTelemetry.Exporter.OpenTelemetryProtocol Exporter utilisant le protocole OTLP
OpenTelemetry.Exporter.Prometheus.AspNetCore Exporter pour Prometheus implémenté en tirant parti d’un point de terminaison ASP.NET Core
OpenTelemetry.Exporter.Zipkin Exporter pour un suivi Zipkin

Exemple : utiliser Prometheus, Grafana et Jaeger

Cet exemple utilise Prometheus pour effectuer des collections de métriques, Grafana pour créer des tableaux de bord et Jaeger pour afficher des suivis distribués.

1. Créer le projet

Créez un projet d’API web simple en utilisant le modèle ASP.NET Core vide dans Visual Studio ou la commande CLI .NET suivante :

dotnet new web

2. Ajouter des métriques et des définitions d’activité

Le code suivant définit une nouvelle métrique (greetings.count) correspondant au nombre de fois où l’API a été appelée et une nouvelle source d’activité (OtPrGrYa.Example).

// Custom metrics for the application
var greeterMeter = new Meter("OtPrGrYa.Example", "1.0.0");
var countGreetings = greeterMeter.CreateCounter<int>("greetings.count", description: "Counts the number of greetings");

// Custom ActivitySource for the application
var greeterActivitySource = new ActivitySource("OtPrGrJa.Example");

3. Créer un point de terminaison d’API

app.MapGet("/", SendGreeting);
async Task<String> SendGreeting(ILogger<Program> logger)
{
    // Create a new Activity scoped to the method
    using var activity = greeterActivitySource.StartActivity("GreeterActivity");

    // Log a message
    logger.LogInformation("Sending greeting");

    // Increment the custom counter
    countGreetings.Add(1);

    // Add a tag to the Activity
    activity?.SetTag("greeting", "Hello World!");

    return "Hello World!";
}

Notes

La définition d’API n’utilise aucun élément spécifique à OpenTelemetry. Elle utilise les API .NET pour l’observabilité.

4. Référencer les packages OpenTelemetry

Utilisez le Gestionnaire de package NuGet ou la ligne de commande pour ajouter les packages NuGet suivants :

<ItemGroup>
   <PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.5.0" />
   <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.5.0" />
   <PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.5.0-rc.1" />
   <PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.5.0" />
   <PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.5.0-beta.1" />
   <PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.5.0-beta.1" />
</ItemGroup>

Notes

Utilisez les versions les plus récentes, car les API d’OTel sont en constante évolution.

5. Configurer OpenTelemetry avec les fournisseurs appropriés

var tracingOtlpEndpoint = builder.Configuration["OTLP_ENDPOINT_URL"];
var otel = builder.Services.AddOpenTelemetry();

// Configure OpenTelemetry Resources with the application name
otel.ConfigureResource(resource => resource
    .AddService(serviceName: builder.Environment.ApplicationName));

// Add Metrics for ASP.NET Core and our custom metrics and export to Prometheus
otel.WithMetrics(metrics => metrics
    // Metrics provider from OpenTelemetry
    .AddAspNetCoreInstrumentation()
    .AddMeter(greeterMeter.Name)
    // Metrics provides by ASP.NET Core in .NET 8
    .AddMeter("Microsoft.AspNetCore.Hosting")
    .AddMeter("Microsoft.AspNetCore.Server.Kestrel")
    .AddPrometheusExporter());

// Add Tracing for ASP.NET Core and our custom ActivitySource and export to Jaeger
otel.WithTracing(tracing =>
{
    tracing.AddAspNetCoreInstrumentation();
    tracing.AddHttpClientInstrumentation();
    tracing.AddSource(greeterActivitySource.Name);
    if (tracingOtlpEndpoint != null)
    {
        tracing.AddOtlpExporter(otlpOptions =>
         {
             otlpOptions.Endpoint = new Uri(tracingOtlpEndpoint);
         });
    }
    else
    {
        tracing.AddConsoleExporter();
    }
});

Ce code utilise l’instrumentation ASP.NET Core pour obtenir des métriques et des activités à partir d’ASP.NET Core. Il enregistre également les fournisseurs Metrics et ActivitySource pour les métriques et le suivi respectivement.

Le code utilise l’exporter Prometheus pour les métriques, qui utilise ASP.NET Core afin d’héberger le point de terminaison. Vous devez donc également ajouter :

// Configure the Prometheus scraping endpoint
app.MapPrometheusScrapingEndpoint();

6. Exécuter le projet

Exécutez le projet, puis accédez à l’API avec le navigateur ou curl.

curl -k http://localhost:7275

Chaque fois que vous demandez la page, elle incrémente le nombre de messages d’accueil effectués. Vous pouvez accéder au point de terminaison des métriques en utilisant la même URL de base, avec le chemin d’accès /metrics.

6.1 Sortie du journal

Les instructions de journalisation du code sont générées à l’aide de ILogger. Par défaut, le Fournisseur Console est activé afin que la sortie soit dirigée vers la console.

Il existe deux possibilités pour effectuer une sortie de journaux à partir de .NET :

  • Les sorties stdout et stderr sont redirigées vers des fichiers journaux par des systèmes de conteneur tels que Kubernetes.
  • À l’aide de bibliothèques de journalisation, incluant Serilog ou NLog, qui s’intègrent à ILogger.
  • À l’aide de fournisseurs de journalisation pour OTel, comme OTLP ou l’exporter Azure Monitor, comme illustré ci-dessous.

6.2 Accéder aux métriques

Vous pouvez accéder aux métriques en tirant parti du point de terminaison /metrics.

curl -k https://localhost:7275/
Hello World!

curl -k https://localhost:7275/metrics
# TYPE greetings_count counter
# HELP greetings_count Counts the number of greetings
greetings_count 1 1686894204856

# TYPE current_connections gauge
# HELP current_connections Number of connections that are currently active on the server.
current_connections{endpoint="127.0.0.1:7275"} 1 1686894204856
current_connections{endpoint="[::1]:7275"} 0 1686894204856
current_connections{endpoint="[::1]:5212"} 1 1686894204856
...

La sortie des métriques est une capture instantanée des métriques au moment où le point de terminaison est demandé. Les résultats sont fournis au format d’exposition Prometheus, lisible par l’utilisateur et mieux compris par Prometheus. Ce sujet est abordé dans la phase suivante.

6.3 Accéder au suivi

Si vous examinez la console du serveur, vous verrez la sortie de l’exporter de trace de console, qui génère les informations dans un format lisible par l’utilisateur. Elle doit afficher deux activités, l’une à partir de votre ActivitySource personnalisé et l’autre d’ASP.NET Core :

Activity.TraceId:            2e00dd5e258d33fe691b965607b91d18
Activity.SpanId:             3b7a891f55b97f1a
Activity.TraceFlags:         Recorded
Activity.ParentSpanId:       645071fd0011faac
Activity.ActivitySourceName: OtPrGrYa.Example
Activity.DisplayName:        GreeterActivity
Activity.Kind:               Internal
Activity.StartTime:          2023-06-16T04:50:26.7675469Z
Activity.Duration:           00:00:00.0023974
Activity.Tags:
    greeting: Hello World!
Resource associated with Activity:
    service.name: OTel-Prometheus-Grafana-Jaeger
    service.instance.id: e1afb619-bc32-48d8-b71f-ee196dc2a76a
    telemetry.sdk.name: opentelemetry
    telemetry.sdk.language: dotnet
    telemetry.sdk.version: 1.5.0

Activity.TraceId:            2e00dd5e258d33fe691b965607b91d18
Activity.SpanId:             645071fd0011faac
Activity.TraceFlags:         Recorded
Activity.ActivitySourceName: Microsoft.AspNetCore
Activity.DisplayName:        /
Activity.Kind:               Server
Activity.StartTime:          2023-06-16T04:50:26.7672615Z
Activity.Duration:           00:00:00.0121259
Activity.Tags:
    net.host.name: localhost
    net.host.port: 7275
    http.method: GET
    http.scheme: https
    http.target: /
    http.url: https://localhost:7275/
    http.flavor: 1.1
    http.user_agent: curl/8.0.1
    http.status_code: 200
Resource associated with Activity:
    service.name: OTel-Prometheus-Grafana-Jaeger
    service.instance.id: e1afb619-bc32-48d8-b71f-ee196dc2a76a
    telemetry.sdk.name: opentelemetry
    telemetry.sdk.language: dotnet
    telemetry.sdk.version: 1.5.0

La première est l’activité personnalisée interne que vous avez créée. La seconde est créée par ASP.NET pour la requête et inclut des balises pour les propriétés de requête HTTP. Vous verrez que les deux ont le même TraceId, qui identifie une seule transaction et dans un système distribué qui peut être utilisé pour mettre en corrélation les traces de chaque service impliqué dans une transaction. Les ID sont transmis sous forme d’en-têtes HTTP. ASP.NET Core attribue un TraceId si aucun n’est présent lorsqu’il reçoit une requête. HttpClient inclut les en-têtes par défaut sur des requêtes sortantes. Chaque activité a un SpanId, qui est la combinaison de TraceId et SpanId permettant d’identifier chaque activité de manière unique. L’activité Greeter est apparentée à l’activité HTTP via son ParentSpanId, qui mappe vers SpanId de l’activité HTTP.

Dans une phase ultérieure, vous allez alimenter ces données dans Jaeger pour visualiser les traces distribuées.

7. Collection de métriques avec Prometheus

Prometheus est un système de collection de métriques, d’agrégation et de base de données de série chronologique. Vous le configurez avec les points de terminaison de métrique pour chaque service pour qu’il récupère régulièrement les valeurs et les stocke dans sa base de données de série chronologique. Vous pouvez ensuite les analyser et les traiter en fonction des besoins.

Les données de métriques exposées au format Prometheus sont une capture instantanée dans le temps des métriques du processus. Chaque fois qu’une requête est envoyée au point de terminaison de métriques, elle signale les valeurs actuelles. Bien que les valeurs actuelles soient intéressantes, elles deviennent plus utiles que les valeurs historiques pour voir des tendances et détecter des valeurs inhabituelles. En règle générale, les services ont des pics d’utilisation en fonction de l’heure de la journée ou d’événements mondiaux, comme une période d’achats massifs lors du premier jour des soldes. En comparant les valeurs aux tendances historiques, vous pouvez détecter si elles sont inhabituelles ou si une métrique se détériore lentement au fil du temps.

Le processus ne stocke aucun historique de ces captures instantanées de métriques. L’ajout de cette fonctionnalité au processus peut consommer beaucoup de ressources. En outre, vous disposez généralement de plusieurs instances de chaque nœud dans un système distribué. Vous souhaitez donc pouvoir y collecter toutes les métriques, puis les agréger et les comparer avec leurs valeurs historiques.

7.1 Installation et configuration de Prometheus

Téléchargez Prometheus pour votre plateforme à partir de https://prometheus.io/download/ et extrayez le contenu du téléchargement.

Examinez la partie supérieure de la sortie de votre serveur en cours d’exécution afin d’obtenir le numéro de port du point de terminaison http. Par exemple :

info: Microsoft.Hosting.Lifetime[14]
      Now listening on: https://localhost:7275
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5212

Modifiez le fichier de configuration YAML Prometheus pour spécifier le port de votre point de terminaison de scraping HTTP et définissez un intervalle de scraping inférieur. Par exemple :

  scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: "prometheus"
    - scrape_interval: 1s # poll very quickly for a more responsive demo

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    scrape_interval: 1s # poll very quickly for a more responsive demo
    static_configs:
      - targets: ["localhost:5212"]

Démarrez Prometheus et recherchez dans la sortie le port sur lequel il s’exécute, en général 9090 :

>prometheus.exe
...
ts=2023-06-16T05:29:02.789Z caller=web.go:562 level=info component=web msg="Start listening for connections" address=0.0.0.0:9090

Ouvrez cette URL dans votre navigateur. Dans l’interface utilisateur Prometheus, vous devriez maintenant pouvoir interroger vos métriques. Utilisez le bouton mis en surbrillance dans l’image suivante pour ouvrir Metrics Explorer qui affiche toutes les métriques disponibles.

Prometheus Metrics Explorer

Sélectionnez la métrique greetings_count pour afficher un graphique des valeurs.

Graph of greetings_count

8. Utiliser Grafana pour créer un tableau de bord de métriques

Grafana est un produit de création de tableaux de bord qui peut créer des tableaux de bord et des alertes basés sur Prometheus ou d’autres sources de données.

Téléchargez et installez la version OSS de Grafana https://grafana.com/oss/grafana/ en suivant les instructions de votre plateforme. Une fois installée, la plateforme Grafana est généralement exécutée sur le port 3000. Ouvrez donc http://localhost:3000 dans votre navigateur. Vous devez vous connecter. Le nom d’utilisateur et le mot de passe par défaut sont tous deux admin.

Dans le menu « hamburger », choisissez Connexions, puis entrez le texte prometheus pour sélectionner votre type de point de terminaison. Sélectionnez Créer une source de données Prometheus pour ajouter une nouvelle source de données.

Grafana connection to prometheus

Vous devez définir les propriétés suivantes :

  • URL du serveur Prometheus : http://localhost:9090/ modifiant le port, le cas échéant

Sélectionnez Enregistrer et Tester pour vérifier la configuration.

Une fois que vous obtenez un message de réussite, vous pouvez configurer un tableau de bord. Cliquez sur le lien générer un tableau de bord affiché dans la fenêtre contextuelle du message de réussite.

Sélectionnez Ajouter une visualisation, puis choisissez la source de données Prometheus que vous venez d’ajouter comme source de données.

Le concepteur de panneau de tableau de bord doit s’afficher. Dans la moitié inférieure de l’écran, vous pouvez définir la requête.

Grafana query using greetings_count

Sélectionnez la métrique greetings_count, puis sélectionnez Exécuter des requêtes pour afficher les résultats.

Vous pouvez, avec Grafana, concevoir des tableaux de bord sophistiqués qui effectuent le suivi d’un nombre quelconque de métriques.

Chaque métrique dans .NET peut avoir des dimensions supplémentaires, qui sont des paires clé-valeur pouvant être utilisées pour partitionner les données. Les métriques ASP.NET présentent toutes un certain nombre de dimensions applicables au compteur. Par exemple, le compteur current-requests de Microsoft.AspNetCore.Hosting a les dimensions suivantes :

Attribut Type Description Exemples Présence
method string Méthode de requête HTTP. GET; POST; HEAD Toujours
scheme string Schéma d’URI identifiant le protocole utilisé. http; https Toujours
host string Nom du serveur HTTP local qui a reçu la requête. localhost Toujours
port int Port du serveur HTTP local qui a reçu la requête. 8080 Ajouté s’il ne s’agit pas de la valeur par défaut (80 pour http ou 443 pour https)

Les graphiques dans Grafana sont généralement partitionnés en fonction de chaque combinaison unique de dimensions. Les dimensions peuvent être utilisées dans les requêtes Grafana pour filtrer ou agréger les données. Par exemple, si vous représentez un graphique current_requests, vous verrez des valeurs partitionnée basées sur chaque combinaison de dimensions. Pour filtrer uniquement en fonction de l’hôte, ajoutez une opération de Sum et utilisez host en tant que valeur d’étiquette.

Grafana current_requests by host

9. Suivi distribué avec Jaeger

À l’Étape 6, vous avez vu que les informations de suivi distribué étaient exposées dans la console. Ces informations effectuent un suivi des unités de travail avec des activités. Certaines activités sont créées automatiquement par la plateforme, comme celle de ASP.NET pour représenter la gestion d’une requête. Les bibliothèques et le code d’application peuvent également créer des activités. L’exemple « greetings » a une activité Greeter. Les activités sont corrélées à l’aide des balises TraceId, SpanId et ParentId.

Chaque processus dans un système distribué génère son propre flux d’informations d’activité et, comme pour les métriques, vous avez besoin d’un système pour collecter, stocker et mettre en corrélation les activités afin de pouvoir visualiser le travail effectué pour chaque transaction. Jaeger est un projet open source permettant d’activer cette collection et cette visualisation.

Téléchargez la dernière archive de distribution binaire de Jaeger pour votre plateforme depuis https://www.jaegertracing.io/download/.

Extrayez ensuite le téléchargement vers un emplacement local facile d’accès. Exécutez le fichier exécutable jaeger-all-in-one(.exe) :

./jaeger-all-in-one --collector.otlp.enabled

Parcourez la sortie de la console pour rechercher le port où elle écoute le trafic OTLP via gRPC. Par exemple :

{"level":"info","ts":1686963686.3854616,"caller":"otlpreceiver@v0.78.2/otlp.go:83","msg":"Starting GRPC server","endpoint":"0.0.0.0:4317"}

Cette sortie vous indique qu’elle écoute sur 0.0.0.0:4317. Vous pouvez donc configurer ce port comme destination pour votre exporter OTLP.

Ouvrez le fichier AppSettings.json pour notre projet, puis ajoutez la ligne suivante, en modifiant le port le cas échéant.

"OTLP_ENDPOINT_URL" :  "http://localhost:4317/"

Redémarrez le processus d’accueil afin qu’il puisse récupérer la modification de propriété et commencer à diriger les informations de suivi vers Jaeger.

Vous devez maintenant être en mesure de voir l’interface utilisateur Jaeger à l’adresse http://localhost:16686/ à partir d’un navigateur web.

Jaeger query for traces

Pour afficher la liste de traces, sélectionnez OTel-Prometheus-grafana-Jaeger dans la liste déroulante Service. La sélection d’une trace doit afficher un diagramme de Gantt des activités dans le cadre de cette trace. Cliquez sur chacune des opérations pour afficher d’autres informations sur l’activité.

Jaeger Operation Details

Dans un système distribué, vous souhaitez envoyer des traces de tous les processus vers la même installation Jaeger afin qu’elle puisse mettre en corrélation les transactions dans le système.

Vous pouvez rendre votre application un peu plus intéressante en lui faisant passer des appels HTTP à elle-même.

  • Ajouter une fabrique HttpClient à l’application

    builder.Services.AddHttpClient();
    
  • Ajouter un nouveau point de terminaison pour effectuer des appels d’accueil imbriqués

    app.MapGet("/NestedGreeting", SendNestedGreeting);
    
  • Implémentez le point de terminaison afin qu’il effectue des appels HTTP qui peuvent également faire l’objet d’une trace. Dans ce cas, il se rappelle dans une boucle artificielle (applicable uniquement aux scénarios de démonstration).

    async Task SendNestedGreeting(int nestlevel, ILogger<Program> logger, HttpContext context, IHttpClientFactory clientFactory)
    {
        // Create a new Activity scoped to the method
        using var activity = greeterActivitySource.StartActivity("GreeterActivity");
    
        if (nestlevel <= 5)
        {
            // Log a message
            logger.LogInformation("Sending greeting, level {nestlevel}", nestlevel);
    
            // Increment the custom counter
            countGreetings.Add(1);
    
            // Add a tag to the Activity
            activity?.SetTag("nest-level", nestlevel);
    
            await context.Response.WriteAsync($"Nested Greeting, level: {nestlevel}\r\n");
    
            if (nestlevel > 0)
            {
                var request = context.Request;
                var url = new Uri($"{request.Scheme}://{request.Host}{request.Path}?nestlevel={nestlevel - 1}");
    
                // Makes an http call passing the activity information as http headers
                var nestedResult = await clientFactory.CreateClient().GetStringAsync(url);
                await context.Response.WriteAsync(nestedResult);
            }
        }
        else
        {
            // Log a message
            logger.LogError("Greeting nest level {nestlevel} too high", nestlevel);
            await context.Response.WriteAsync("Nest level too high, max is 5");
        }
    }
    

Il en résulte un graphique plus intéressant avec une forme pyramidale pour les requêtes, car chaque niveau attend la réponse de l’appel précédent.

Jaeger nested dependency results

Exemple : utilisation d’Azure Monitor et d’Application Insights

Dans l’exemple précédent, vous avez utilisé des applications open source distinctes pour les métriques et le suivi. Il existe de nombreux systèmes APM commerciaux disponibles que vous pouvez choisir. Dans Azure, le produit de monitoring des applications principal est Application Insights, qui fait partie d’Azure Monitor.

L’un des avantages d’un produit APM intégré est qu’il peut mettre en corrélation les différentes sources de données d’observabilité. Pour faciliter l’expérience ASP.NET avec Azure Monitor, un package wrapper est fourni qui effectue la majeure partie du travail de configuration d’OpenTelemetry.

Prenez le même projet à l’Étape 5 et remplacez les références NuGet par un seul package :

<ItemGroup>
  <PackageReference Include="Azure.Monitor.OpenTelemetry.AspNetCore" Version="1.0.0-beta.4" />
</ItemGroup>

Ensuite, remplacez le code d’initialisation OTel par :

var otel = builder.Services.AddOpenTelemetry();
otel.UseAzureMonitor();
otel.WithMetrics(metrics => metrics
    .AddMeter(greeterMeter.Name)
    .AddMeter("Microsoft.AspNetCore.Hosting")
    .AddMeter("Microsoft.AspNetCore.Server.Kestrel"));
otel.WithTracing(tracing =>
{
    tracing.AddSource(greeterActivitySource.Name);
});

UseAzureMonitor() est la magie qui ajoute les bibliothèques d’instrumentation et les exporters courants pour Application Insights. Il vous suffit d’ajouter vos noms de Meter et ActivitySource personnalisés à l’inscription.

Si vous n’êtes pas encore un client d’Azure, vous pouvez créer un compte gratuit à l’adresse https://azure.microsoft.com/free/. Connectez-vous au Portail Azure et sélectionnez une ressource Application Insights existante ou créez-en une avec https://ms.portal.azure.com/#create/Microsoft.AppInsights.

Application Insights identifie les instance à utiliser pour stocker et traiter des données via une clé d’instrumentation et une chaîne de connexion se trouvant en haut à droite de l’interface utilisateur du portail.

Connection String in Azure Portal

Si vous utilisez Azure App Service, cette chaîne de connexion est automatiquement transmise à l’application comme variable d’environnement. Pour d’autres services ou lors d’une exécution locale, vous devez la transmettre en utilisant la variable d’environnement APPLICATIONINSIGHTS_CONNECTION_STRING ou dans appsettings.json. Pour une exécution locale, il est plus facile d’ajouter la valeur à appsettings.json :

"AzureMonitor": {
    "ConnectionString": "InstrumentationKey=12345678-abcd-abcd-abcd-12345678..."
}

Notes

Remplacez la valeur par celle de votre instance.

Lorsque vous exécutez l’application, la télémétrie est envoyée à Application Insights. Vous devriez maintenant obtenir des journaux, des métriques et des traces distribuées pour votre application.

Journaux

App Insights logs view

Métriques

App Insights metrics view

Suivi distribué

App Insights transaction view