Śledzenie rozproszone w bibliotekach System.Net
rozproszone śledzenie to technika diagnostyczna, która ułatwia inżynierom lokalizowanie błędów i problemów z wydajnością w aplikacjach, zwłaszcza tych, które są rozproszone na wielu maszynach lub procesach. Ta technika śledzi żądania za pośrednictwem aplikacji, korelując razem pracę wykonywaną przez różne składniki i oddzielając ją od innych zadań, które aplikacja może wykonywać dla żądań współbieżnych. Na przykład żądanie do typowej usługi internetowej może zostać najpierw odebrane przez moduł równoważenia obciążenia, a następnie przekazane do procesu serwera internetowego, co powoduje wysłanie kilku zapytań do bazy danych. Śledzenie rozproszone umożliwia inżynierom rozróżnienie, czy którykolwiek z tych kroków zakończył się niepowodzeniem i jak długo wykonano każdy krok. Może również rejestrować komunikaty generowane przez każdy krok podczas jego działania.
System śledzenia na platformie .NET jest przeznaczony do pracy z usługą OpenTelemetry (OTel) i używa protokołu OTel do eksportowania danych do systemów monitorowania. Śledzenie na platformie .NET jest implementowane za pomocą interfejsów API System.Diagnostics, gdzie jednostka pracy jest reprezentowana przez klasę System.Diagnostics.Activity, która odpowiada OTel. OpenTelemetry definiuje standardowy schemat nazewnictwa dla zakresów (działań) wraz z ich atrybutami (tagami), znanymi jako konwencje semantyczne. Telemetria platformy .NET używa istniejących konwencji semantycznych wszędzie tam, gdzie to możliwe.
Notatka
Terminy obejmują i działania są synonimami w tym artykule. W kontekście kodu platformy .NET odwołują się one do wystąpienia System.Diagnostics.Activity. Nie należy mylić zakresu OTel z System.Span<T>.
Napiwek
Aby uzyskać kompleksową listę wszystkich wbudowanych działań wraz z tagami/atrybutami, zobacz Wbudowane działania na platformie .NET.
Instrumentacja
Aby emitować ślady, biblioteki System.Net są instrumentowane z wbudowanymi źródłami ActivitySource, które tworzą obiekty Activity do śledzenia wykonanej pracy. Działania są tworzone tylko wtedy, gdy nasłuchiwacze subskrybują ActivitySource.
Wbudowana instrumentacja ewoluowała wraz z wersjami platformy .NET.
- Na platformie .NET 8 i starszych instrumentacja jest ograniczona do tworzenia pustego działania żądania klienta HTTP . Oznacza to, że użytkownicy muszą polegać na bibliotece
OpenTelemetry.Instrumentation.Http
w celu wypełnienia działania informacjami (na przykład tagami) potrzebnymi do emitowania przydatnych śladów. - Platforma .NET 9 rozszerzyła instrumentację, emitując nazwę, stan, informacje o wyjątku i najważniejsze tagi zgodnie z konwencjami semantycznymi klienta HTTP OTel w działaniu żądania klienta HTTP. Oznacza to, że w programie .NET 9 lub nowszym zależność
OpenTelemetry.Instrumentation.Http
można pominąć, chyba że są wymagane bardziej zaawansowane funkcje, takie jak wzbogacanie. - Platforma .NET 9 wprowadziła również eksperymentalne śledzenie połączeń, dodając nowe działania w bibliotekach
System.Net
w celu ułatwienia diagnozowania problemów z połączeniami.
Zbieraj ślady System.Net
W najniższym poziomiekolekcja śledzenia jest obsługiwana za pośrednictwem metody AddActivityListener, która rejestruje obiekty ActivityListener zawierające logikę zdefiniowaną przez użytkownika.
Jednak jako deweloper aplikacji wolałbyś polegać na bogatym ekosystemie, który opiera się na funkcjach dostarczanych przez OpenTelemetry .NET SDK w celu zbierania, eksportowania i monitorowania danych śledzenia.
- Aby uzyskać podstawową wiedzę na temat zbierania śladów za pomocą biblioteki OTel, zapoznaj się z naszym przewodnikiem dotyczącym zbierania śladów przy użyciu biblioteki OpenTelemetry.
- W przypadku zbierania i monitorowania w czasie produkcyjnym można używać biblioteki OpenTelemetry z Prometheus, Grafana i Jaeger lub Azure Monitor i Application Insights. Jednak te narzędzia są dość złożone i mogą być niewygodne do użycia w czasie programowania.
- W przypadku zbierania i monitorowania śledzenia w czasie programowania zalecamy użycie .NET Aspire, który zapewnia prosty, ale rozszerzalny sposób na rozpoczęcie rozproszonego śledzenia w aplikacji i diagnozowanie problemów lokalnie.
- Można również ponownie użyć projektu aspirującego domyślnie usługi bez orkiestracji Aspire. Jest to przydatny sposób wprowadzenia i skonfigurowania śledzenia i metryk OpenTelemetry w projektach ASP.NET.
Zbieranie śladów za pomocą platformy .NET Aspire
Prostym sposobem zbierania śladów i metryk w aplikacjach ASP.NET jest użycie .NET Aspire. .NET Aspire to zestaw rozszerzeń platformy .NET, który ułatwia tworzenie i pracę z aplikacjami rozproszonymi. Jedną z zalet korzystania z platformy .NET Aspire jest wbudowana telemetria przy użyciu bibliotek OpenTelemetry dla platformy .NET.
Domyślne szablony projektów dla platformy .NET Aspire zawierają projekt ServiceDefaults
. Każda usługa w rozwiązaniu .NET Aspire ma odwołanie do projektu Service Defaults. Usługi używają tego do ustawiania i konfigurowania OTel.
Szablon projektu Service Defaults zawiera pakiety OTel SDK, ASP.NET, HttpClient i Runtime Instrumentation. Te składniki instrumentacji są konfigurowane w pliku Extensions.cs. Aby obsługiwać wizualizację telemetrii w Aspire Dashboard, projekt Service Defaults zawiera również eksportera OTLP jako domyślną opcję.
Aspire Dashboard jest zaprojektowany do umożliwienia obserwacji danych telemetrycznych w lokalnym cyklu debugowania, aby deweloperzy mogli zapewnić, że aplikacje generują dane telemetryczne. Wizualizacja telemetrii pomaga również diagnozować te aplikacje lokalnie. Możliwość obserwowania wywołań między usługami jest tak przydatna w czasie debugowania, jak w środowisku produkcyjnym. Panel .NET Aspire uruchamia się automatycznie, gdy F5 projekt AppHost
z programu Visual Studio lub dotnet run
projekt AppHost
z wiersza poleceń.
Aspire
Aby uzyskać więcej informacji na temat platformy .NET Aspire, zobacz:
Ponowne użycie projektu Domyślne Ustawienia Usługi bez orkiestracji .NET Aspire
Projekt Aspire Service Defaults zapewnia łatwy sposób konfigurowania OTel dla projektów ASP.NET, nawet jeśli nie korzystasz z reszty .NET Aspire, takich jak AppHost do celów orkiestracji. Projekt Ustawienia domyślne usługi jest dostępny jako szablon projektu za pośrednictwem programu Visual Studio lub dotnet new
. Konfiguruje OTel i ustawia eksportera OTLP. Następnie możesz użyć zmiennych środowiskowych OTel, aby skonfigurować punkt końcowy OTLP do wysyłania danych telemetrycznych i podać właściwości zasobu dla aplikacji.
Kroki używania ServiceDefaults poza platformą .NET Aspire są następujące:
Dodaj projekt ServiceDefaults do rozwiązania przy użyciu polecenia Dodaj nowy projekt w programie Visual Studio lub użyj
dotnet new
:dotnet new aspire-servicedefaults --output ServiceDefaults
Odwołaj się do projektu ServiceDefaults z aplikacji ASP.NET. W programie Visual Studio wybierz pozycję Dodaj>Dokumentacja projektu i wybierz projekt ServiceDefaults"
Wywołaj funkcję instalacji OpenTelemetry
ConfigureOpenTelemetry()
w ramach inicjowania konstruktora aplikacji.var builder = WebApplication.CreateBuilder(args) builder.ConfigureOpenTelemetry(); // Extension method from ServiceDefaults. var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.Run();
Aby zapoznać się z pełnym przewodnikiem, zobacz Przykład: Używanie biblioteki OpenTelemetry z funkcją OTLP i autonomicznym pulpitem nawigacyjnym Aspirator.
Eksperymentalne śledzenie połączeń
Podczas rozwiązywania problemów lub wąskich gardeł HttpClient
, może być kluczowe sprawdzenie, na co jest poświęcany czas podczas wysyłania żądań HTTP. Często problem występuje podczas ustanawiania połączenia HTTP, który zazwyczaj dzieli się na wyszukiwanie DNS, połączenie TCP i uzgadnianie protokołu TLS.
Platforma .NET 9 wprowadziła eksperymentalne śledzenie połączeń, dodając obszar HTTP connection setup
z trzema obszarami podrzędnymi reprezentującymi fazy ustanowienia połączenia: DNS, TCP i TLS. Część HTTP śledzenia połączeń jest implementowana w SocketsHttpHandler, co oznacza, że model aktywności musi dostosować się do zasad działania zarządzania pulą połączeń.
Notatka
W SocketsHttpHandlerpołączenia i żądania mają niezależne cykle życia. Połączenie w puli może istnieć przez długi czas i obsługiwać wiele żądań. Jeśli podczas tworzenia żądania nie ma połączenia natychmiast dostępnego w puli połączeń, żądanie jest dodawane do kolejki żądań w celu oczekiwania na dostępne połączenie. Nie ma bezpośredniej relacji między żądaniami oczekiwania i połączeniami. Proces połączenia mógł zostać uruchomiony, gdy inne połączenie stało się dostępne do użycia, w tym przypadku jest używane bezpłatne połączenie. W związku z tym zakres HTTP connection setup
nie jest modelowany jako element podrzędny zakresu HTTP client request
; zamiast tego używane są połączenia zakresów.
Platforma .NET 9 wprowadziła następujące zakresy umożliwiające zbieranie szczegółowych informacji o połączeniu:
Nazwa | ActivitySource | Opis |
---|---|---|
HTTP wait_for_connection |
Experimental.System.Net.Http.Connections |
Zakres podrzędny HTTP client request , który reprezentuje przedział czasu, przez który żądanie oczekuje na dostępne połączenie w kolejce żądań. |
HTTP connection_setup |
Experimental.System.Net.Http.Connections |
Reprezentuje utworzenie połączenia HTTP. Oddzielny główny zakres śledzenia z własnym TraceId .
HTTP client request zakresy mogą zawierać linki do HTTP connection_setup . |
DNS lookup |
Experimental.System.Net.NameResolution |
Wyszukiwanie DNS wykonywane przez klasę Dns. |
socket connect |
Experimental.System.Net.Sockets |
Utworzenie połączenia Socket. |
TLS handshake |
Experimental.System.Net.Security |
Proces inicjacji połączenia TLS klienta lub serwera wykonywany przez SslStream. |
Notatka
Odpowiednie nazwy ActivitySource
zaczynają się od prefiksu Experimental
, ponieważ te zakresy mogą zostać zmienione w przyszłych wersjach, ponieważ dowiemy się więcej o tym, jak dobrze działają w środowisku produkcyjnym.
Te zakresy są zbyt pełne do użycia 24x7 w scenariuszach produkcyjnych z dużymi obciążeniami — są hałaśliwe i ten poziom instrumentacji nie jest zwykle potrzebny. Jeśli jednak próbujesz zdiagnozować problemy z połączeniem lub lepiej zrozumieć, w jaki sposób opóźnienie sieci i połączenia ma wpływ na usługi, zapewniają szczegółowe informacje, które trudno zebrać w inny sposób.
Po włączeniu Experimental.System.Net.Http.Connections
ActivitySource zakres HTTP client request
zawiera link do zakresu HTTP connection_setup
, który odpowiada połączeniu obsługującemu żądanie. Ponieważ połączenie HTTP może być długotrwałe, może to spowodować wiele linków do zakresu połączenia z każdego działania żądania. Niektóre narzędzia do monitorowania APM agresywnie prowadzą linki między zakresami w celu zbudowania ich widoków, a więc uwzględnienie tego zakresu może powodować problemy, gdy narzędzia nie zostały zaprojektowane tak, aby uwzględniały dużą liczbę łączy.
Na poniższym diagramie przedstawiono zachowanie zakresów i ich relacji:
Przewodnik: używanie eksperymentalnego śledzenia połączeń na platformie .NET 9
W tym przewodniku użyto aplikacji .NET 9 Aspire Starter App do demonstracji śledzenia połączeń, ale łatwo go skonfigurujesz przy użyciu innych narzędzi do monitorowania. Kluczowym krokiem jest włączenie usługi ActivitySources.
Utwórz aplikację startową .NET Aspire 9 przy użyciu
dotnet new
:dotnet new aspire-starter-9 --output ConnectionTracingDemo
Lub w programie Visual Studio:
Otwórz
Extensions.cs
w projekcieServiceDefaults
i zmodyfikuj metodęConfigureOpenTelemetry
dodając element ActivitySources dla połączenia w wywołaniu zwrotnym konfiguracji śledzenia:.WithTracing(tracing => { tracing.AddAspNetCoreInstrumentation() // Instead of using .AddHttpClientInstrumentation() // .NET 9 allows to add the ActivitySources directly. .AddSource("System.Net.Http") // Add the experimental connection tracking ActivitySources using a wildcard. .AddSource("Experimental.System.Net.*"); });
Uruchom rozwiązanie. To powinno otworzyć pulpit nawigacyjny Aspire platformy .NET .
Przejdź do strony Pogoda w aplikacji
webfrontend
, aby wygenerować żądanieHttpClient
doapiservice
.Wróć do pulpitu nawigacyjnego i przejdź do strony Traces. Otwórz ślad
webfrontend: GET /weather
.
Gdy żądania HTTP są wykonywane z włączoną instrumentacją połączenia, powinieneś zauważyć następujące zmiany w obszarach zapytań klienta:
- Jeśli należy ustanowić połączenie lub jeśli aplikacja czeka na połączenie z puli połączeń, zostanie wyświetlony dodatkowy
HTTP wait_for_connection
zakres, co oznacza czas oczekiwania na nawiązanie połączenia. Pomaga to zrozumieć opóźnienia między żądaniemHttpClient
wykonanym w kodzie, a terminem rzeczywistego uruchomienia przetwarzania żądania. Na poprzedniej ilustracji:- Wybrany zakres to żądanie HttpClient.
- Poniższy zakres reprezentuje czas, przez który żądanie oczekuje na nawiązanie połączenia.
- Ostatni zakres na żółto pochodzi z miejsca docelowego przetwarzania żądania.
- Zakres HttpClient będzie miał link do zakresu
HTTP connection_setup
, który reprezentuje działanie w celu utworzenia połączenia HTTP używanego przez żądanie.
Jak wspomniano wcześniej, obszar HTTP connection_setup
jest odrębnym segmentem z własnymi TraceId
, ponieważ jego czas życia jest niezależny od każdego pojedynczego żądania klienta. Ten zakres ma zazwyczaj zakresy podrzędne DNS lookup
, (TCP) socket connect
i TLS client handshake
.
Wzbogacenie
W niektórych przypadkach konieczne jest rozszerzenie istniejącej funkcjonalności śledzenia System.Net
. Zazwyczaj oznacza to wstrzykiwanie dodatkowych tagów/atrybutów do wbudowanych działań. Nazywa się to wzbogacaniem.
API do wzbogacania w bibliotece instrumentacji OpenTelemetry
Aby dodać dodatkowe tagi/atrybuty do aktywności związanej z żądaniem klienta HTTP, najprostszym sposobem jest użycie API do wzbogacania HttpClient
z biblioteki instrumentacji HttpClient i HttpWebRequest. Wymaga to polegania na pakiecie OpenTelemetry.Instrumentation.Http
.
Ręczne wzbogacanie
Można ręcznie zaimplementować wzbogacanie działania HTTP client request
. W tym celu należy uzyskać dostęp do Activity.Current w kodzie uruchamianym w kontekście aktywności żądania, zanim aktywność się zakończy. Można to zrobić, implementując IObserver<DiagnosticListener>
i subskrybując ją do AllListeners, aby uzyskać wywołania zwrotne, gdy występuje aktywność sieciowa. W rzeczywistości jest to sposób implementacji bibliotek i instrumentacji OpenTelemetry HttpClient i HttpWebRequest. Aby zapoznać się z przykładem kodu, zobacz kod subskrypcji w DiagnosticSourceSubscriber.cs
i podstawową implementację w HttpHandlerDiagnosticListener.cs, do którego są delegowane powiadomienia.
Potrzebujesz więcej śledzenia?
Jeśli masz sugestie dotyczące innych przydatnych informacji, które można uwidocznić za pośrednictwem śledzenia, utwórz zgłoszenie w dotnet/runtime.