Shromáždění distribuovaného trasování

Tento článek se vztahuje na: ✔️ .NET Core 2.1 a novější verze ✔️ .NET Framework 4.5 a novější verze

Instrumentovaný kód může vytvářet Activity objekty jako součást distribuovaného trasování, ale informace v těchto objektech je potřeba shromáždit do centralizovaného úložiště, aby bylo možné později zkontrolovat celé trasování. V tomto kurzu shromáždíte distribuovanou telemetrii trasování různými způsoby, aby byla v případě potřeby k dispozici k diagnostice problémů s aplikací. Pokud potřebujete přidat novou instrumentaci , projděte si kurz instrumentace.

Shromažďování trasování pomocí OpenTelemetry

OpenTelemetry je open source projekt s neutrálním dodavatelem podporovaný cloudovou architekturou Foundation , jehož cílem je standardizovat generování a shromažďování telemetrických dat pro software nativní pro cloud. V těchto příkladech shromáždíte a zobrazíte distribuované informace o trasování v konzole nástroje . Informace o tom, jak nakonfigurovat OpenTelemetry tak, aby odesílala informace jinam, najdete v úvodní příručce k OpenTelemetry.

příklad ASP.NET

Požadavky

Vytvoření ukázkové aplikace

Nejprve vytvořte novou ASP.NET webovou aplikaci, která se použije jako ukázková aplikace.

dotnet new webapp

Tato aplikace zobrazí webovou stránku, ale při procházení webové stránky se zatím neshromažďují žádné distribuované informace o trasování.

Konfigurace kolekce

Pokud chcete použít OpenTelemetry, musíte přidat odkazy na několik balíčků NuGet.

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

Poznámka

V době psaní tohoto článku byl build 1.4.0 Release Candidate 1 nejnovější dostupnou verzí OpenTelemetry. Jakmile bude k dispozici finální verze, použijte ji místo toho.

Dále upravte zdrojový kód v souboru Program.cs tak, aby vypadal takto:

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();

Spusťte aplikaci a pomocí webového prohlížeče přejděte na webovou stránku, která je hostovaná. Teď, když jste povolili distribuované trasování OpenTelemetry, by se měly zobrazit informace o webových požadavcích prohlížeče vytištěné do konzoly:

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

Veškerá konfigurace OpenTelemetry probíhá v nových zdrojových řádcích, které začínají na builder.Services.AddOpenTelemetry(). Dříve .WithTracing(...) jste povolili distribuované trasování. AddAspNetCoreInstrumentation()Povolili opentelemetry ke shromažďování všech distribuovaných trasovacích aktivit, které jsou vytvářeny webovým serverem ASP.NET Core, a AddConsoleExporter() dává opentelemetry pokyn, aby tyto informace odeslala do konzoly. V případě méně triviální aplikace můžete přidat další knihovny instrumentace, které také shromáždí trasování databázových dotazů nebo odchozích požadavků HTTP. Také byste nahradili vývozce konzoly vývozcem pro Jaeger, Zipken nebo jinou monitorovací službu, kterou jste se rozhodli použít.

Příklad konzolové aplikace

Požadavky

Vytvoření ukázkové aplikace

Před shromažďováním telemetrie distribuovaného trasování je potřeba ji vytvořit. Tato instrumentace je často v knihovnách, ale pro zjednodušení vytvoříte malou aplikaci, která má ukázkovou instrumentaci pomocí StartActivity. V tomto okamžiku nedošlo k žádné kolekci a Funkce StartActivity() nemá žádný vedlejší účinek a vrátí hodnotu null. Další podrobnosti najdete v kurzu instrumentace .

dotnet new console

Aplikace, které cílí na .NET 5 a novější, už mají zahrnutá potřebná distribuovaná trasovací rozhraní API. Pro aplikace, které cílí na starší verze .NET, přidejte balíček NuGet System.Diagnostics.DiagnosticSource verze 5 nebo vyšší.

dotnet add package System.Diagnostics.DiagnosticSource

Nahraďte obsah vygenerovaného souboru Program.cs tímto ukázkovým zdrojem:

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);
            }
        }
    }
}

Spuštění aplikace ještě neshromažďuje žádná data trasování:

> dotnet run
Example work done

Konfigurace kolekce

Přidejte balíček NuGet OpenTelemetry.Exporter.Console .

dotnet add package OpenTelemetry.Exporter.Console

Aktualizujte program.cs dalšími direktivami OpenTelemetry using :

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

Aktualizujte Main() a vytvořte OpenTelemetry TracerProvider:

        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");
        }

Aplikace teď shromažďuje informace o distribuovaném trasování a zobrazuje je v konzole:

> 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
zdroje

V ukázkovém kódu jste vyvolali AddSource("Sample.DistributedTracing") , aby OpenTelemetry zachytávala aktivity vytvořené activitysourcem, které už byly v kódu:

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

Telemetrii z libovolného Zdroje aktivit je možné zachytit voláním AddSource() s názvem zdroje.

Vývozci

Vývozce konzoly je užitečný pro rychlé příklady nebo místní vývoj, ale v produkčním nasazení budete pravděpodobně chtít odesílat trasování do centralizovaného úložiště. OpenTelemetry podporuje různé cíle využívající různé vývozce. Další informace o konfiguraci OpenTelemetry najdete v úvodní příručce k OpenTelemetry.

Shromažďování trasování pomocí Application Insights

Distribuovaná telemetrie trasování se automaticky zaznamenává po konfiguraci sady Application Insights SDK pro aplikace ASP.NET nebo ASP.NET Core nebo povolením instrumentace bez kódu.

Další informace najdete v dokumentaci k distribuovanému trasování Application Insights.

Poznámka

V současné době Application Insights podporuje pouze shromažďování konkrétních dobře známých instrumentací aktivit a ignoruje nové aktivity přidané uživatelem. Application Insights nabízí TrackDependency jako rozhraní API specifické pro dodavatele pro přidávání vlastních distribuovaných trasovacích informací.

Shromažďování trasování pomocí vlastní logiky

Vývojáři mohou pro data trasování aktivit vytvářet vlastní přizpůsobenou logiku shromažďování. Tento příklad shromažďuje telemetrii pomocí System.Diagnostics.ActivityListener rozhraní API poskytovaného rozhraním .NET a vytiskne ji do konzoly.

Požadavky

Vytvoření ukázkové aplikace

Nejprve vytvoříte ukázkovou aplikaci, která má určitou distribuovanou instrumentaci trasování, ale neshromažďují se žádná data trasování.

dotnet new console

Aplikace, které cílí na .NET 5 a novější, už mají zahrnutá potřebná distribuovaná trasovací rozhraní API. Pro aplikace, které cílí na starší verze .NET, přidejte balíček NuGet System.Diagnostics.DiagnosticSource verze 5 nebo vyšší.

dotnet add package System.Diagnostics.DiagnosticSource

Nahraďte obsah vygenerovaného souboru Program.cs tímto ukázkovým zdrojem:

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);
            }
        }
    }
}

Spuštění aplikace ještě neshromažďuje žádná data trasování:

> dotnet run
Example work done

Přidání kódu pro shromáždění trasování

Aktualizujte Main() pomocí tohoto kódu:

        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");
        }

Výstup teď zahrnuje protokolování:

> 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

Nastavení DefaultIdFormat a je volitelné, ForceDefaultIdFormat ale pomáhá zajistit, aby ukázka vytvářela podobný výstup v různých verzích modulu runtime .NET. .NET 5 používá ve výchozím nastavení formát ID W3C TraceContext, ale starší verze rozhraní .NET ve výchozím nastavení používají Hierarchical formát ID. Další informace najdete v tématu ID aktivit.

System.Diagnostics.ActivityListener se používá k příjmu zpětných volání během životnosti aktivity.

  • ShouldListenTo - Každá aktivita je přidružena k ActivitySource, který funguje jako její obor názvů a producent. Toto zpětné volání je vyvoláno jednou pro každý Zdroj aktivity v procesu. Pokud chcete provést vzorkování nebo dostávat oznámení o událostech spuštění/zastavení pro aktivity vytvořené tímto zdrojem, vraťte hodnotu true.
  • Sample – Ve výchozím nastavení StartActivity nevytvoří objekt Activity, pokud některý ActivityListener neuvádí, že by měl být vzorkován. AllDataAndRecorded Vrácení označuje, že aktivita by měla být vytvořená, IsAllDataRequested měla by být nastavena na hodnotu true a ActivityTraceFlags bude mít Recorded nastavený příznak. IsAllDataRequested může instrumentovaný kód sledovat jako nápovědu, že naslouchací proces chce zajistit, aby byly vyplněny pomocné informace o aktivitě, jako jsou značky a události. Příznak Recorded je kódovaný v ID W3C TraceContext a je nápovědou pro jiné procesy zapojené do distribuovaného trasování, že by se toto trasování mělo vzorkovat.
  • ActivityStarted a ActivityStopped jsou volána při spuštění a zastavení aktivity. Tato zpětná volání poskytují příležitost zaznamenat relevantní informace o aktivitě nebo ji potenciálně upravit. Když aktivita právě začala, může být většina dat stále neúplná a budou vyplněna před ukončením aktivity.

Jakmile se vytvoří ActivityListener a vyplní se zpětná volání, volání ActivitySource.AddActivityListener(ActivityListener) zahájí volání zpětného volání. Voláním ActivityListener.Dispose() zastavíte tok zpětných volání. Mějte na paměti, že v kódu s více vlákny můžou být oznámení o zpětném volání přijímána, když Dispose() je spuštěná nebo dokonce krátce poté, co se vrátila.