Udostępnij za pośrednictwem


Zbieranie rozproszonego śledzenia

Ten artykuł dotyczy: ✔️ .NET Core 2.1 i nowsze wersje ✔️ .NET Framework 4.5 i nowszych wersjach

Instrumentowany kod może tworzyć Activity obiekty w ramach śledzenia rozproszonego, ale informacje w tych obiektach należy zebrać w scentralizowanym magazynie, aby można było później przejrzeć cały ślad. W tym samouczku zbierzesz rozproszone dane telemetryczne śledzenia na różne sposoby, aby umożliwić diagnozowanie problemów z aplikacjami w razie potrzeby. Zapoznaj się z samouczkiem instrumentacji , jeśli musisz dodać nową instrumentację.

Zbieranie śladów przy użyciu biblioteki OpenTelemetry

OpenTelemetry to neutralny dla dostawcy projekt typu open source obsługiwany przez Natywną Fundację Przetwarzania w chmurze, który ma na celu standaryzację generowania i zbierania danych telemetrycznych dla oprogramowania natywnego dla chmury. W tych przykładach zbierzesz i wyświetlisz rozproszone informacje o śledzeniu w konsoli programu . Aby dowiedzieć się, jak skonfigurować usługę OpenTelemetry w celu wysyłania informacji w innym miejscu, zobacz przewodnik wprowadzenie do usługi OpenTelemetry.

przykład ASP.NET

Wymagania wstępne

Tworzenie przykładowej aplikacji

Najpierw utwórz nową aplikację internetową ASP.NET, która będzie używana jako aplikacja demonstracyjna.

dotnet new webapp

Ta aplikacja wyświetla stronę internetową, ale nie są jeszcze zbierane żadne rozproszone informacje śledzenia, jeśli przeglądamy stronę internetową.

Konfigurowanie kolekcji

Aby użyć biblioteki OpenTelemetry, należy dodać odwołania do kilku pakietów 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

Uwaga

W momencie pisania pisania kompilacja Release Candidate 1.4.0 była najnowszą dostępną wersją biblioteki OpenTelemetry. Gdy wersja ostateczna będzie dostępna, użyj jej zamiast tego.

Następnie zmodyfikuj kod źródłowy w pliku Program.cs , tak aby wyglądał następująco:

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

Uruchom aplikację i użyj przeglądarki internetowej, aby przejść do hostowanej strony internetowej. Po włączeniu śledzenia rozproszonego OpenTelemetry powinny zostać wyświetlone informacje o żądaniach sieci Web przeglądarki wydrukowanych w konsoli:

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

Cała konfiguracja openTelemetry jest wykonywana w nowych wierszach źródłowych rozpoczynających się od builder.Services.AddOpenTelemetry(). Użyto .WithTracing(...) do włączenia śledzenia rozproszonego. AddAspNetCoreInstrumentation()włączono funkcję OpenTelemetry w celu zbierania wszystkich rozproszonych działań śledzenia generowanych przez serwer sieci Web ASP.NET Core i AddConsoleExporter() instruuje usługę OpenTelemetry, aby wysyłała te informacje do konsoli. W przypadku mniej banalnej aplikacji można dodać więcej bibliotek instrumentacji, aby również zbierać śledzenie zapytań bazy danych lub wychodzących żądań HTTP. Możesz również zastąpić eksportera konsoli eksporterem jaeger, Zipken lub inną usługą monitorowania, która została wybrana do użycia.

Przykład aplikacji konsolowej

Wymagania wstępne

Tworzenie przykładowej aplikacji

Zanim będzie można zebrać jakiekolwiek rozproszone dane telemetryczne śledzenia, należy je utworzyć. Często ta instrumentacja znajduje się w bibliotekach, ale dla uproszczenia utworzysz małą aplikację z przykładową instrumentacją przy użyciu polecenia StartActivity. W tym momencie żadna kolekcja nie została wykonana, a funkcja StartActivity() nie ma efektu ubocznego i zwraca wartość null. Aby uzyskać więcej informacji, zobacz samouczek instrumentacji .

dotnet new console

Aplikacje przeznaczone dla platformy .NET 5 i nowszych mają już dołączone niezbędne interfejsy API śledzenia rozproszonego. W przypadku aplikacji przeznaczonych dla starszych wersji platformy .NET dodaj pakiet NuGet System.Diagnostics.DiagnosticSource w wersji 5 lub nowszej.

dotnet add package System.Diagnostics.DiagnosticSource

Zastąp zawartość wygenerowanego pliku Program.cs następującym przykładowym źródłem:

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

Uruchomienie aplikacji nie zbiera jeszcze żadnych danych śledzenia:

> dotnet run
Example work done

Konfigurowanie kolekcji

Dodaj pakiet NuGet OpenTelemetry.Exporter.Console .

dotnet add package OpenTelemetry.Exporter.Console

Zaktualizuj plik Program.cs przy użyciu dodatkowych dyrektyw OpenTelemetry using :

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

Zaktualizuj Main() element , aby utworzyć element TracerProvider openTelemetry:

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

Teraz aplikacja zbiera informacje o śledzeniu rozproszonym i wyświetla je w konsoli:

> 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
Źródła

W przykładowym kodzie wywołano AddSource("Sample.DistributedTracing") metodę , aby funkcja OpenTelemetry przechwyciła działania utworzone przez element ActivitySource, który był już obecny w kodzie:

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

Dane telemetryczne z dowolnego źródła działania można przechwycić przez wywołanie AddSource() metody przy użyciu nazwy źródła.

Eksporterów

Eksporter konsoli jest pomocny w przypadku szybkich przykładów lub programowania lokalnego, ale w ramach wdrożenia produkcyjnego prawdopodobnie zechcesz wysłać ślady do scentralizowanego magazynu. Usługa OpenTelemetry obsługuje różne miejsca docelowe przy użyciu różnych eksporterów. Aby uzyskać więcej informacji na temat konfigurowania usługi OpenTelemetry, zobacz przewodnik Wprowadzenie do usługi OpenTelemetry.

Zbieranie śladów przy użyciu usługi Application Insights

Rozproszone dane telemetryczne śledzenia są automatycznie przechwytywane po skonfigurowaniu zestawu SDK usługi Application Insights dla aplikacji ASP.NET lub ASP.NET Core albo przez włączenie instrumentacji bez kodu.

Aby uzyskać więcej informacji, zobacz dokumentację dotyczącą śledzenia rozproszonego usługi Application Insights.

Uwaga

Obecnie usługa Application Insights obsługuje tylko zbieranie określonych dobrze znanych instrumentacji działań i ignoruje nowe działania dodane przez użytkownika. Usługa Application Insights oferuje funkcję TrackDependency jako interfejs API specyficzny dla dostawcy do dodawania niestandardowych informacji śledzenia rozproszonego.

Zbieranie śladów przy użyciu logiki niestandardowej

Deweloperzy mogą tworzyć własną niestandardową logikę zbierania danych śledzenia aktywności. W tym przykładzie dane telemetryczne są zbierane przy użyciu interfejsu API dostarczonego System.Diagnostics.ActivityListener przez platformę .NET i wyświetla je w konsoli.

Wymagania wstępne

Tworzenie przykładowej aplikacji

Najpierw utworzysz przykładową aplikację z rozproszoną instrumentacją śledzenia, ale nie są zbierane żadne dane śledzenia.

dotnet new console

Aplikacje przeznaczone dla platformy .NET 5 i nowszych mają już dołączone niezbędne interfejsy API śledzenia rozproszonego. W przypadku aplikacji przeznaczonych dla starszych wersji platformy .NET dodaj pakiet NuGet System.Diagnostics.DiagnosticSource w wersji 5 lub nowszej.

dotnet add package System.Diagnostics.DiagnosticSource

Zastąp zawartość wygenerowanego pliku Program.cs następującym przykładowym źródłem:

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

Uruchomienie aplikacji nie zbiera jeszcze żadnych danych śledzenia:

> dotnet run
Example work done

Dodawanie kodu do zbierania śladów

Zaktualizuj main() przy użyciu tego kodu:

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

Dane wyjściowe obejmują teraz rejestrowanie:

> 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

Ustawienie DefaultIdFormat i ForceDefaultIdFormat jest opcjonalne, ale pomaga zapewnić, że przykład generuje podobne dane wyjściowe w różnych wersjach środowiska uruchomieniowego platformy .NET. Platforma .NET 5 domyślnie używa formatu identyfikatora TraceContext W3C, ale wcześniejsze wersje platformy .NET domyślnie używają Hierarchical formatu identyfikatora. Aby uzyskać więcej informacji, zobacz Identyfikatory działań.

System.Diagnostics.ActivityListener służy do odbierania wywołań zwrotnych w okresie istnienia działania.

  • ShouldListenTo — Każde działanie jest skojarzone z elementem ActivitySource, który działa jako przestrzeń nazw i producent. To wywołanie zwrotne jest wywoływane raz dla każdego elementu ActivitySource w procesie. Zwróć wartość true, jeśli chcesz wykonać próbkowanie lub otrzymasz powiadomienie o zdarzeniach uruchamiania/zatrzymywania dla działań generowanych przez to źródło.
  • Sample - Domyślnie StartActivity nie tworzy obiektu Działania, chyba że niektóre element ActivityListener wskazuje, że powinien być próbkowany. Zwracanie AllDataAndRecorded wskazuje, że działanie powinno zostać utworzone, IsAllDataRequested powinno mieć wartość true i ActivityTraceFlags będzie mieć ustawioną flagę Recorded . Element IsAllDataRequested może być obserwowany przez instrumentowany kod jako wskazówkę, że odbiornik chce upewnić się, że pomocnicze informacje o aktywności, takie jak tagi i zdarzenia, są wypełniane. Flaga Recorded jest kodowana w identyfikatorze TraceContext W3C i jest wskazówką dla innych procesów zaangażowanych w ślad rozproszony, że ten ślad powinien być próbkowany.
  • ActivityStarted i ActivityStopped są wywoływane, gdy działanie jest uruchamiane i zatrzymywane odpowiednio. Te wywołania zwrotne umożliwiają zarejestrowanie odpowiednich informacji o działaniu lub potencjalnie modyfikacji. Po rozpoczęciu działania większość danych może być nadal niekompletna i zostanie wypełniona przed zatrzymanym działaniem.

Po utworzeniu elementu ActivityListener i wypełnieniu wywołań zwrotnych wywoływanie ActivitySource.AddActivityListener(ActivityListener) inicjuje wywołanie zwrotne. Wywołaj metodę ActivityListener.Dispose() , aby zatrzymać przepływ wywołań zwrotnych. Należy pamiętać, że w kodzie wielowątkowym powiadomienia zwrotne w toku mogą być odbierane podczas Dispose() działania lub nawet wkrótce po jego zwróceniu.