Delen via


Een gedistribueerde trace verzamelen

Dit artikel is van toepassing op: ✔️ .NET Core 2.1 en latere versies ✔️ .NET Framework 4.5 en latere versies

Met instrumentatiecode kunnen objecten worden gemaakt Activity als onderdeel van een gedistribueerde tracering, maar de informatie in deze objecten moet worden verzameld in een gecentraliseerde opslag, zodat de volledige tracering later kan worden gecontroleerd. In deze zelfstudie verzamelt u de gedistribueerde traceringstelemetrie op verschillende manieren, zodat deze beschikbaar is voor het diagnosticeren van toepassingsproblemen wanneer dat nodig is. Raadpleeg de zelfstudie over instrumentatie als u nieuwe instrumentatie moet toevoegen.

Traceringen verzamelen met OpenTelemetry

OpenTelemetry is een leverancierneutral opensource-project dat wordt ondersteund door de Cloud Native Computing Foundation . Het doel is het genereren en verzamelen van telemetriegegevens voor cloudeigen software te standaardiseren. In deze voorbeelden verzamelt en geeft u gedistribueerde traceringsgegevens weer op de console. Als u wilt weten hoe u OpenTelemetry configureert om informatie naar een andere locatie te verzenden, raadpleegt u de handleiding Aan de slag met OpenTelemetry.

ASP.NET voorbeeld

Vereisten

Een voorbeeldtoepassing maken

Maak eerst een nieuwe ASP.NET web-app om te gebruiken als de demotoepassing.

dotnet new webapp

Deze app geeft een webpagina weer, maar er worden nog geen gedistribueerde traceringsgegevens verzameld als we door de webpagina bladeren.

Verzameling configureren

Als u OpenTelemetry wilt gebruiken, moet u verwijzingen toevoegen aan verschillende NuGet-pakketten.

dotnet add package OpenTelemetry --version 1.4.0-rc1
dotnet add package OpenTelemetry.Exporter.Console --version 1.4.0-rc1
dotnet add package OpenTelemetry.Extensions.Hosting --version 1.4.0-rc1
dotnet add package OpenTelemetry.Instrumentation.AspNetCore --version 1.0.0-rc9.10

Notitie

Op het moment van schrijven was de versie 1.4.0 Release Candidate 1 de nieuwste versie van OpenTelemetry die beschikbaar was. Zodra er een definitieve versie beschikbaar is, gebruikt u die in plaats daarvan.

Wijzig vervolgens de broncode in Program.cs zodat deze er als volgt uitziet:

using OpenTelemetry;
using OpenTelemetry.Trace;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddOpenTelemetry()
    .WithTracing(builder =>
    {
        builder.AddAspNetCoreInstrumentation();
        builder.AddConsoleExporter();
    }).StartWithHost();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Voer de app uit en gebruik een webbrowser om naar de webpagina te bladeren die wordt gehost. Nu u gedistribueerde tracering met OpenTelemetry hebt ingeschakeld, ziet u informatie over de webaanvragen van de browser die naar de console worden afgedrukt:

Activity.TraceId:            9c4519ce65a667280daedb3808d376f0
Activity.SpanId:             727c6a8a6cff664f
Activity.TraceFlags:         Recorded
Activity.ActivitySourceName: Microsoft.AspNetCore
Activity.DisplayName:        /
Activity.Kind:               Server
Activity.StartTime:          2023-01-08T01:56:05.4529879Z
Activity.Duration:           00:00:00.1048255
Activity.Tags:
    net.host.name: localhost
    net.host.port: 5163
    http.method: GET
    http.scheme: http
    http.target: /
    http.url: http://localhost:5163/
    http.flavor: 1.1
    http.user_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.76
    http.status_code: 200
Resource associated with Activity:
    service.name: unknown_service:demo

Alle OpenTelemetry-configuratie vindt plaats in de nieuwe bronregels die beginnen met builder.Services.AddOpenTelemetry(). U hebt gebruikt .WithTracing(...) om gedistribueerde tracering in te schakelen. AddAspNetCoreInstrumentation()Schakelde OpenTelemetry in om alle gedistribueerde traceringsactiviteiten te verzamelen die worden geproduceerd door de ASP.NET Core webserver en AddConsoleExporter() geeft OpenTelemetry de opdracht om die informatie naar de console te verzenden. Voor een minder eenvoudige app kunt u meer instrumentatiebibliotheken toevoegen om ook tracering voor databasequery's of uitgaande HTTP-aanvragen te verzamelen. U vervangt ook de consoleexporteur door een exporteur voor Jaeger, Zipken of een andere bewakingsservice die u hebt gekozen.

Voorbeeld van console-app

Vereisten

Een voorbeeldtoepassing maken

Voordat gedistribueerde traceringstelemetrie kan worden verzameld, moet u deze produceren. Deze instrumentatie bevindt zich vaak in bibliotheken, maar voor het gemak maakt u een kleine app met een voorbeeld van instrumentatie met behulp van StartActivity. Op dit moment is er geen verzameling opgetreden en heeft StartActivity() geen neveneffect en wordt null geretourneerd. Zie de zelfstudie over instrumentatie voor meer informatie.

dotnet new console

Toepassingen die zijn gericht op .NET 5 en hoger, bevatten al de benodigde API's voor gedistribueerde tracering. Voor apps die zijn gericht op oudere .NET-versies, voegt u het NuGet-pakket System.Diagnostics.DiagnosticSource toe versie 5 of hoger.

dotnet add package System.Diagnostics.DiagnosticSource

Vervang de inhoud van het gegenereerde Program.cs door deze voorbeeldbron:

using System;
using System.Diagnostics;
using System.Threading.Tasks;

namespace Sample.DistributedTracing
{
    class Program
    {
        static ActivitySource s_source = new ActivitySource("Sample.DistributedTracing");

        static async Task Main(string[] args)
        {
            await DoSomeWork();
            Console.WriteLine("Example work done");
        }

        static async Task DoSomeWork()
        {
            using (Activity a = s_source.StartActivity("SomeWork"))
            {
                await StepOne();
                await StepTwo();
            }
        }

        static async Task StepOne()
        {
            using (Activity a = s_source.StartActivity("StepOne"))
            {
                await Task.Delay(500);
            }
        }

        static async Task StepTwo()
        {
            using (Activity a = s_source.StartActivity("StepTwo"))
            {
                await Task.Delay(1000);
            }
        }
    }
}

Als u de app uitvoert, worden er nog geen traceringsgegevens verzameld:

> dotnet run
Example work done

Verzameling configureren

Voeg het NuGet-pakket OpenTelemetry.Exporter.Console toe.

dotnet add package OpenTelemetry.Exporter.Console

Update Program.cs met aanvullende OpenTelemetry-instructies using :

using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
using System;
using System.Diagnostics;
using System.Threading.Tasks;

Werk Main() bij om de OpenTelemetry TracerProvider te maken:

        public static async Task Main()
        {
            using var tracerProvider = Sdk.CreateTracerProviderBuilder()
                .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MySample"))
                .AddSource("Sample.DistributedTracing")
                .AddConsoleExporter()
                .Build();

            await DoSomeWork();
            Console.WriteLine("Example work done");
        }

De app verzamelt nu gedistribueerde traceringsinformatie en geeft deze weer in de console:

> dotnet run
Activity.Id:          00-7759221f2c5599489d455b84fa0f90f4-6081a9b8041cd840-01
Activity.ParentId:    00-7759221f2c5599489d455b84fa0f90f4-9a52f72c08a9d447-01
Activity.DisplayName: StepOne
Activity.Kind:        Internal
Activity.StartTime:   2021-03-18T10:46:46.8649754Z
Activity.Duration:    00:00:00.5069226
Resource associated with Activity:
    service.name: MySample
    service.instance.id: 909a4624-3b2e-40e4-a86b-4a2c8003219e

Activity.Id:          00-7759221f2c5599489d455b84fa0f90f4-d2b283db91cf774c-01
Activity.ParentId:    00-7759221f2c5599489d455b84fa0f90f4-9a52f72c08a9d447-01
Activity.DisplayName: StepTwo
Activity.Kind:        Internal
Activity.StartTime:   2021-03-18T10:46:47.3838737Z
Activity.Duration:    00:00:01.0142278
Resource associated with Activity:
    service.name: MySample
    service.instance.id: 909a4624-3b2e-40e4-a86b-4a2c8003219e

Activity.Id:          00-7759221f2c5599489d455b84fa0f90f4-9a52f72c08a9d447-01
Activity.DisplayName: SomeWork
Activity.Kind:        Internal
Activity.StartTime:   2021-03-18T10:46:46.8634510Z
Activity.Duration:    00:00:01.5402045
Resource associated with Activity:
    service.name: MySample
    service.instance.id: 909a4624-3b2e-40e4-a86b-4a2c8003219e

Example work done
Bronnen

In de voorbeeldcode hebt u aangeroepen AddSource("Sample.DistributedTracing") zodat OpenTelemetry de activiteiten vastlegt die zijn geproduceerd door de ActivitySource die al aanwezig was in de code:

static ActivitySource s_source = new ActivitySource("Sample.DistributedTracing");

Telemetrie van elke ActivitySource kan worden vastgelegd door aan te roepen AddSource() met de naam van de bron.

Exporteurs

De consoleexporteur is handig voor snelle voorbeelden of lokale ontwikkeling, maar in een productie-implementatie wilt u waarschijnlijk traceringen verzenden naar een gecentraliseerde winkel. OpenTelemetry ondersteunt verschillende bestemmingen met behulp van verschillende exporteurs. Zie de handleiding Aan de slag met OpenTelemetry voor meer informatie over het configureren van OpenTelemetry.

Traceringen verzamelen met Behulp van Application Insights

Gedistribueerde traceringstelemetrie wordt automatisch vastgelegd na het configureren van de Application Insights SDK voor ASP.NET- of ASP.NET Core-apps, of door instrumentatie met code in te schakelen.

Zie de documentatie over gedistribueerde tracering van Application Insights voor meer informatie.

Notitie

Op dit moment biedt Application Insights alleen ondersteuning voor het verzamelen van specifieke, bekende activiteiten en worden nieuwe door de gebruiker toegevoegde activiteiten genegeerd. Application Insights biedt TrackDependency als een leverancierspecifieke API voor het toevoegen van aangepaste gedistribueerde traceringsgegevens.

Traceringen verzamelen met behulp van aangepaste logica

Ontwikkelaars kunnen hun eigen aangepaste verzamelingslogica maken voor activiteitstraceringsgegevens. In dit voorbeeld wordt de telemetrie verzameld met behulp van de System.Diagnostics.ActivityListener API van .NET en wordt deze afgedrukt naar de console.

Vereisten

Een voorbeeldtoepassing maken

Eerst maakt u een voorbeeldtoepassing met een gedistribueerde traceringsinstrumentatie, maar er worden geen traceringsgegevens verzameld.

dotnet new console

Toepassingen die zijn gericht op .NET 5 en hoger, bevatten al de benodigde API's voor gedistribueerde tracering. Voor apps die zijn gericht op oudere .NET-versies, voegt u het NuGet-pakket System.Diagnostics.DiagnosticSource toe versie 5 of hoger.

dotnet add package System.Diagnostics.DiagnosticSource

Vervang de inhoud van het gegenereerde Program.cs door deze voorbeeldbron:

using System;
using System.Diagnostics;
using System.Threading.Tasks;

namespace Sample.DistributedTracing
{
    class Program
    {
        static ActivitySource s_source = new ActivitySource("Sample.DistributedTracing");

        static async Task Main(string[] args)
        {
            await DoSomeWork();
            Console.WriteLine("Example work done");
        }

        static async Task DoSomeWork()
        {
            using (Activity a = s_source.StartActivity("SomeWork"))
            {
                await StepOne();
                await StepTwo();
            }
        }

        static async Task StepOne()
        {
            using (Activity a = s_source.StartActivity("StepOne"))
            {
                await Task.Delay(500);
            }
        }

        static async Task StepTwo()
        {
            using (Activity a = s_source.StartActivity("StepTwo"))
            {
                await Task.Delay(1000);
            }
        }
    }
}

Als u de app uitvoert, worden er nog geen traceringsgegevens verzameld:

> dotnet run
Example work done

Code toevoegen om de traceringen te verzamelen

Werk Main() bij met deze code:

        static async Task Main(string[] args)
        {
            Activity.DefaultIdFormat = ActivityIdFormat.W3C;
            Activity.ForceDefaultIdFormat = true;

            Console.WriteLine("         {0,-15} {1,-60} {2,-15}", "OperationName", "Id", "Duration");
            ActivitySource.AddActivityListener(new ActivityListener()
            {
                ShouldListenTo = (source) => true,
                Sample = (ref ActivityCreationOptions<ActivityContext> options) => ActivitySamplingResult.AllDataAndRecorded,
                ActivityStarted = activity => Console.WriteLine("Started: {0,-15} {1,-60}", activity.OperationName, activity.Id),
                ActivityStopped = activity => Console.WriteLine("Stopped: {0,-15} {1,-60} {2,-15}", activity.OperationName, activity.Id, activity.Duration)
            });

            await DoSomeWork();
            Console.WriteLine("Example work done");
        }

De uitvoer bevat nu logboekregistratie:

> dotnet run
         OperationName   Id                                                           Duration
Started: SomeWork        00-bdb5faffc2fc1548b6ba49a31c4a0ae0-c447fb302059784f-01
Started: StepOne         00-bdb5faffc2fc1548b6ba49a31c4a0ae0-a7c77a4e9a02dc4a-01
Stopped: StepOne         00-bdb5faffc2fc1548b6ba49a31c4a0ae0-a7c77a4e9a02dc4a-01      00:00:00.5093849
Started: StepTwo         00-bdb5faffc2fc1548b6ba49a31c4a0ae0-9210ad536cae9e4e-01
Stopped: StepTwo         00-bdb5faffc2fc1548b6ba49a31c4a0ae0-9210ad536cae9e4e-01      00:00:01.0111847
Stopped: SomeWork        00-bdb5faffc2fc1548b6ba49a31c4a0ae0-c447fb302059784f-01      00:00:01.5236391
Example work done

Instelling DefaultIdFormat en ForceDefaultIdFormat is optioneel, maar helpt ervoor te zorgen dat het voorbeeld vergelijkbare uitvoer produceert op verschillende .NET-runtimeversies. .NET 5 gebruikt standaard de W3C TraceContext ID-indeling, maar eerdere .NET-versies gebruiken Hierarchical standaard de id-indeling. Zie Activiteit-id's voor meer informatie.

System.Diagnostics.ActivityListener wordt gebruikt om callbacks te ontvangen tijdens de levensduur van een activiteit.

  • ShouldListenTo - Elke activiteit is gekoppeld aan een ActivitySource, die fungeert als de naamruimte en producent. Deze callback wordt eenmaal aangeroepen voor elke ActivitySource in het proces. Retourneer waar als u geïnteresseerd bent in het uitvoeren van steekproeven of als u een melding wilt ontvangen over start-/stopgebeurtenissen voor activiteiten die door deze bron worden geproduceerd.
  • Sample - Standaard StartActivity wordt geen Activity-object gemaakt, tenzij een ActivityListener aangeeft dat er een steekproef moet worden genomen. Retourneren AllDataAndRecorded geeft aan dat de activiteit moet worden gemaakt, IsAllDataRequested moet worden ingesteld op true en ActivityTraceFlags dat de Recorded vlag wordt ingesteld. IsAllDataRequested kan door de geïnstrueerde code worden waargenomen als een hint dat een listener ervoor wil zorgen dat aanvullende activiteitsgegevens, zoals tags en gebeurtenissen, worden ingevuld. De vlag Recorded is gecodeerd in de W3C TraceContext ID en is een hint naar andere processen die betrokken zijn bij de gedistribueerde tracering dat deze tracering moet worden bemonsterd.
  • ActivityStarted en ActivityStopped worden aangeroepen wanneer een activiteit respectievelijk wordt gestart en gestopt. Deze callbacks bieden de mogelijkheid om relevante informatie over de activiteit vast te leggen of mogelijk te wijzigen. Wanneer een activiteit net is gestart, zijn veel van de gegevens mogelijk nog steeds onvolledig en worden deze ingevuld voordat de activiteit stopt.

Zodra een ActivityListener is gemaakt en de callbacks zijn ingevuld, wordt het aanroepen ActivitySource.AddActivityListener(ActivityListener) van de callbacks gestart. Roep ActivityListener.Dispose() aan om de stroom van callbacks te stoppen. Houd er rekening mee dat in code met meerdere threads, callbackmeldingen die worden uitgevoerd, kunnen worden ontvangen terwijl Dispose() deze wordt uitgevoerd of zelfs kort nadat deze is geretourneerd.