Exemple : Utilisez OpenTelemetry avec OTLP et le tableau de bord Aspire autonome
Ceci est l’un d’une série d’exemples illustrant l’observabilité .NET avec OpenTelemetry.
En plus de faire partie intégrante de .NET Aspire, le tableau de bord Aspire est disponible en tant que conteneur docker autonome, qui fournit un point de terminaison OTLP auquel la télémétrie peut être envoyée, et il visualisera les journaux, les métriques et les traces. L’utilisation du tableau de bord de cette manière n’a aucune dépendance avec .NET Aspire, il visualisera la télémétrie de toute application qui lui envoie de la télémétrie via OTLP. Il fonctionne aussi bien pour les applications écrites en Java, GoLang, Python, etc. à condition qu’elles puissent envoyer leur télémétrie à un point de terminaison OTLP.
L’utilisation du tableau de bord Aspire nécessite moins de configuration et d’étapes d’installation que l’utilisation de solutions Open Source telles que Prometheus, Grafana et Jaeger, mais contrairement à ces outils, le tableau de bord Aspire est destiné à être un outil de visualisation pour développeurs, et non pour la surveillance en production.
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é (Otel.Example
).
// Custom metrics for the application
var greeterMeter = new Meter("OTel.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("OTel.Example");
3. Créer un point de terminaison d’API
Insérez ce qui suit entre builder.Build();
et app.Run()
app.MapGet("/", SendGreeting);
Insérez la fonction suivante en bas du fichier :
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!";
}
Remarque
La définition du point de terminaison n’utilise rien de 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.OpenTelemetryProtocol" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0" />
</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
Insérez le code suivant avant builder.Build();
:
// Setup logging to be exported via OpenTelemetry
builder.Logging.AddOpenTelemetry(logging =>
{
logging.IncludeFormattedMessage = true;
logging.IncludeScopes = true;
});
var otel = builder.Services.AddOpenTelemetry();
// Add Metrics for ASP.NET Core and our custom metrics and export via OTLP
otel.WithMetrics(metrics =>
{
// Metrics provider from OpenTelemetry
metrics.AddAspNetCoreInstrumentation();
//Our custom metrics
metrics.AddMeter(greeterMeter.Name);
// Metrics provides by ASP.NET Core in .NET 8
metrics.AddMeter("Microsoft.AspNetCore.Hosting");
metrics.AddMeter("Microsoft.AspNetCore.Server.Kestrel");
});
// Add Tracing for ASP.NET Core and our custom ActivitySource and export via OTLP
otel.WithTracing(tracing =>
{
tracing.AddAspNetCoreInstrumentation();
tracing.AddHttpClientInstrumentation();
tracing.AddSource(greeterActivitySource.Name);
});
// Export OpenTelemetry data via OTLP, using env vars for the configuration
var OtlpEndpoint = builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"];
if (OtlpEndpoint != null)
{
otel.UseOtlpExporter();
}
Ce code configure OpenTelemetry avec les différentes sources de télémétrie :
- Il ajoute un fournisseur OTel à ILogger pour collecter les enregistrements de journaux.
- Il configure les métriques, en enregistrant les fournisseurs d’instrumentation et les Meters pour ASP.NET ainsi que notre Meter personnalisé.
- Il configure la traçabilité, en enregistrant les fournisseurs d’instrumentation et notre ActivitySource personnalisé.
Il enregistre ensuite l’exportateur OTLP en utilisant des variables d’environnement pour sa configuration.
6. Configurer les variables d’environnement OTLP
L’exportateur OTLP peut être configuré via des API dans le code, mais il est plus courant de le configurer via des variables d’environnement. Ajoutez ce qui suit à AppSettings.Development.json
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4317",
"OTEL_SERVICE_NAME": "OTLP-Example"
Vous pouvez ajouter des variables d’environnement supplémentaires pour l’exportateur OTLP .NET ou des variables OTel courantes telles que OTEL_RESOURCE_ATTRIBUTES
pour définir les attributs de ressource.
Remarque
Un piège courant est de confondre AppSettings.json et AppSettings.Development.json ; si ce dernier est présent, il sera utilisé lorsque vous appuierez sur F5 depuis Visual Studio et tous les paramètres de AppSettings.json seront ignorés.
7. Démarrer le conteneur Aspire Dashboard
Utilisez docker pour télécharger et exécuter le conteneur du tableau de bord.
docker run --rm -it `
-p 18888:18888 `
-p 4317:18889 `
--name aspire-dashboard `
mcr.microsoft.com/dotnet/aspire-dashboard:latest
Les données affichées dans le tableau de bord peuvent être sensibles. Par défaut, le tableau de bord est sécurisé avec une authentification qui nécessite un jeton pour se connecter. Le jeton est affiché dans le résultat de sortie lors de l’exécution du conteneur.
[]
Copiez l’URL affichée, et remplacez 0.0.0.0
par localhost
, par exemple http://localhost:18888/login?t=123456780abcdef123456780
, et ouvrez-la dans votre navigateur, ou vous pouvez également coller la clé après /login?t=
lorsque la boîte de dialogue de connexion s’affiche. Le jeton changera à chaque fois que vous démarrez le conteneur.
8. 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.
8.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
etstderr
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.
- Utilisation de fournisseurs de journalisation pour OTel tels que OTLP. La section journalisation dans le code de l’étape 5 ajoute le fournisseur OTel.
Les journaux sont affichés dans le tableau de bord sous forme de journaux structurés - toutes les propriétés que vous définissez dans le message de journal sont extraites comme champs dans l’enregistrement de journal.
8.2 Affichage des métriques
Le tableau de bord Aspire affiche les métriques sur une base par ressource (une ressource étant la façon OTel de parler des sources de télémétrie, telles qu’un processus). Lorsqu’une ressource est sélectionnée, le tableau de bord énumérera chaque métrique qui a été envoyée à son point de terminaison OTLP par la ressource. La liste des métriques est dynamique, et sera mise à jour à mesure que de nouvelles métriques sont reçues.
L’affichage des métriques dépendra du type de métrique utilisé :
- Les compteurs seront affichés directement.
- Les histogrammes qui suivent une valeur par requête, telle qu’une durée ou les octets envoyés par requête, sont regroupés dans une série de compartiments. Le tableau de bord tracera les centiles P50, P90 et P99. Les résultats des histogrammes peuvent inclure des exemplaires, qui sont des points de données individuels avec l’ID de trace/span pour cette requête. Ils seront affichés sous forme de points sur le graphique. En sélectionner un vous dirigera vers la trace correspondante afin que vous puissiez voir ce qui a causé cette valeur. Cela est utile pour diagnostiquer les valeurs aberrantes.
- Les métriques peuvent inclure des dimensions, qui sont des paires clé/valeur associées à des valeurs individuelles. Les valeurs sont agrégées par dimension. En utilisant les listes déroulantes dans l’affichage, vous pouvez filtrer les résultats pour examiner des dimensions spécifiques, par exemple seulement les requêtes
GET
, ou celles pour un itinéraire URL spécifique dans ASP.NET.
8.3 Affichage de la traçabilité
La vue de suivi affiche une liste de traces : chaque trace est un ensemble d’activités qui partagent le même traceId. Le travail est suivi avec des spans qui représentent une unité de travail. Le traitement d’une requête ASP.NET créera un span. Faire une requête HttpClient sera un span. En suivant le parent de l’étendue, une hiérarchie d’étendues peut être visualisées. En collectant des spans de chaque ressource (processus), nous suivons le travail qui se produit à travers une série de services. Les requêtes HTTP ont un en-tête qui est utilisé pour transmettre le traceId et le parent spanId au service suivant. Chaque ressource doit collecter la télémétrie et l’envoyer au même collecteur. Il agrégera ensuite et présentera une hiérarchie des spans.
Le tableau de bord affichera une liste de traces avec des informations récapitulatives. Chaque fois que des spans avec un nouveau traceId sont détectés, ils obtiendront une ligne dans le tableau. Cliquer sur afficher montrera tous les spans dans la trace.
Sélectionner un span affichera ses détails, y compris toutes les propriétés sur le span, telles que l’étiquette greeting
que nous avons définie à l’étape 3.