Verteiltes Tracing in System.Net-Bibliotheken
Verteilte Ablaufverfolgung ist eine Diagnosetechnik, mit der Ingenieure Fehler und Leistungsprobleme in Anwendungen lokalisieren können, insbesondere bei solchen, die auf mehrere Computer oder Prozesse verteilt sind. Mit dieser Technik werden Anforderungen in einer Anwendung nachverfolgt, indem die von verschiedenen Komponenten geleistete Arbeit miteinander in Beziehung gesetzt und von anderer Arbeit, die die Anwendung möglicherweise für gleichzeitig eingehende Anforderungen ausführt, getrennt wird. Eine Anforderung an einen typischen Webdienst kann z. B. zuerst von einem Lastenausgleich empfangen und dann an einen Webserverprozess weitergeleitet werden, der dann mehrere Abfragen an eine Datenbank sendet. Die verteilte Ablaufverfolgung ermöglicht Entwicklern zu unterscheiden, ob eine dieser Schritte fehlgeschlagen ist und wie lange jeder Schritt ausgeführt wurde. Es kann auch Nachrichten protokollieren, die von jedem Schritt während seiner Ausführung erstellt wurden.
Das Tracing-System in .NET ist für die Zusammenarbeit mit OpenTelemetry (OTel) konzipiert und verwendet OTel für den Export der Daten an Überwachungssysteme. Die Ablaufverfolgung in .NET wird mithilfe der System.Diagnostics-APIs implementiert, wobei eine Arbeitseinheit durch die Klasse System.Diagnostics.Activity dargestellt wird, die einem OTel--Spanentspricht. OpenTelemetry definiert ein branchenweites Standardbenennungsschema für Spans (Aktivitäten) zusammen mit ihren Attributen (Tags), die als semantische Konventionen bekannt sind. Die .NET-Telemetrie verwendet nach Möglichkeit vorhandene semantische Konventionen.
Anmerkung
Die Begriffe Span und Aktivität sind in diesem Artikel synonym. Im Kontext von .NET-Code verweisen sie auf eine System.Diagnostics.Activity Instanz. Verwechseln Sie den OTel-Span nicht mit System.Span<T>.
Tipp
Eine umfassende Liste aller integrierten Aktivitäten zusammen mit ihren Tags/Attributen finden Sie unter Integrierten Aktivitäten in .NET.
Instrumentierung
Um Traces auszugeben, werden die System.Net-Bibliotheken mit integrierten ActivitySource-Quellen instrumentiert, die Activity-Objekte erstellen, um die ausgeführte Arbeit zu verfolgen. Aktivitäten werden nur erstellt, wenn Listener die ActivitySourceabonniert haben.
Die integrierte Instrumentierung wurde mit .NET-Versionen weiterentwickelt.
- In .NET 8 und früheren Versionen ist die Instrumentation auf die Erstellung einer leeren HTTP-Clientanforderungsaktivitätbeschränkt. Dies bedeutet, dass Benutzer sich auf die
OpenTelemetry.Instrumentation.Http
-Bibliothek verlassen müssen, um die Aktivität mit den erforderlichen Informationen (z. B. Tags) zu versehen, die notwendig sind, um nützliche Spuren auszugeben. - .NET 9 hat die Instrumentierung erweitert, indem sie den Namen, den Status, Ausnahmeinformationen und die wichtigsten Tags gemäß den OTel--HTTP-Clientsemantikkonventionen für die Aktivität einer HTTP-Clientanforderung ausgeben. Dies bedeutet, dass unter .NET 9+ die
OpenTelemetry.Instrumentation.Http
Abhängigkeit weggelassen werden kann, außer wenn fortgeschrittene Funktionen wie Anreicherung erforderlich sind. - Mit .NET 9 wurde auch experimentelles Verbindungs-Tracing eingeführt, das neue Aktivitäten in den
System.Net
Bibliotheken zur Unterstützung der Diagnose von Verbindungsproblemen hinzufügt.
Sammeln Sie die System.Net-Ablaufverfolgungen
Auf der niedrigsten Ebene wird das Sammeln von Traces über die AddActivityListener-Methode unterstützt, die ActivityListener-Objekte mit benutzerdefinierter Logik registriert.
Als Anwendungsentwickler würden Sie sich jedoch wahrscheinlich lieber auf das umfangreiche Ökosystem verlassen, das auf den Features basiert, die vom OpenTelemetry .NET SDK bereitgestellt werden, um Ablaufverfolgungen zu sammeln, zu exportieren und zu überwachen.
- Um ein grundlegendes Verständnis für die Erfassung von Traces mit OTel zu gewinnen, sehen Sie sich unseren Leitfaden zum Sammeln von Traces mithilfe von OpenTelemetryan.
- Für die Sammlung und Überwachung von Traces zur Produktionszeit können Sie OpenTelemetry mit Prometheus, Grafana und Jaeger oder mit Azure Monitor und Application Insights verwenden. Diese Tools sind jedoch recht komplex und können während der Entwicklungszeit unangenehm sein.
- Für das Sammeln und Überwachen von Traces zur Entwicklungszeit empfehlen wir .NET Aspire, das eine einfache, aber erweiterbare Möglichkeit bietet, das verteilte Tracing in Ihrer Anwendung zu starten und Probleme lokal zu diagnostizieren.
- Es ist auch möglich, das Aspire Service Defaults-Projekt ohne die Aspire Orchestrierung wiederzuverwenden. Dies ist eine praktische Möglichkeit, die OpenTelemetry-Ablaufverfolgung und Metriken in Ihren ASP.NET Projekten einzuführen und zu konfigurieren.
Sammeln von Traces mit .NET Aspire
Eine einfache Möglichkeit zum Sammeln von Traces und Metriken in ASP.NET-Anwendungen ist die Verwendung von .NET Aspire. .NET Aspire ist eine Reihe von Erweiterungen für .NET, um das Erstellen und Arbeiten mit verteilten Anwendungen zu vereinfachen. Einer der Vorteile der Verwendung von .NET Aspire besteht darin, dass Telemetrie integriert ist, indem die OpenTelemetry-Bibliotheken für .NET verwendet werden.
Die Standardprojektvorlagen für .NET Aspire enthalten ein ServiceDefaults
Projekt. Jeder Dienst in der .NET Aspire-Lösung weist einen Verweis auf das Projekt "Service Defaults" auf. Die Dienste verwenden sie zum Einrichten und Konfigurieren von OTel.
Die Projektvorlage "Dienststandard" enthält die OTel-SDK-, ASP.NET-, HttpClient- und Runtime Instrumentation-Pakete. Diese Instrumentierungskomponenten sind in der datei Extensions.cs konfiguriert. Zur Unterstützung der Telemetrievisualisierung im Aspire Dashboard enthält das Dienststandardprojekt standardmäßig auch den OTLP-Exporter.
Das Aspire Dashboard wurde entwickelt, um Telemetriebeobachtungen in den lokalen Debugzyklus zu bringen, wodurch Entwickler sicherstellen können, dass die Anwendungen Telemetrie erzeugen. Die Telemetrievisualisierung hilft auch, diese Anwendungen lokal zu diagnostizieren. Die Möglichkeit, die Aufrufe zwischen Diensten zu beobachten, ist zum Debugzeitpunkt so nützlich wie in der Produktion. Das Dashboard von .NET Aspire wird automatisch gestartet, wenn Sie F5 das AppHost
-Projekt von Visual Studio oder dotnet run
das AppHost
-Projekt von der Kommandozeile aus aufrufen.
Weitere Informationen zu .NET Aspire finden Sie unter:
Dienstprojekt mit Standardeinstellungen ohne .NET Aspire Orchestration wiederverwenden
Das Projekt Aspire Service Defaults bietet eine einfache Möglichkeit, OTel für ASP.NET-Projekte zu konfigurieren, auch wenn Sie den Rest von .NET Aspire wie z. B. den AppHost für die Orchestrierung nicht verwenden. Das Dienststandardprojekt ist als Projektvorlage über Visual Studio oder dotnet new
verfügbar. Er konfiguriert OTel und richtet den OTLP-Exporter ein. Anschließend können Sie die OTel-Umgebungsvariablen verwenden, um den OTLP-Endpunkt zum Senden von Telemetrie zu konfigurieren und die Ressourceneigenschaften für die Anwendung bereitzustellen.
Die Schritte zur Verwendung ServiceDefaults außerhalb von .NET Aspire sind:
Fügen Sie das ServiceDefaults-Projekt mit Neues Projekt hinzufügen in Visual Studio zur Lösung hinzu, oder verwenden Sie
dotnet new
:dotnet new aspire-servicedefaults --output ServiceDefaults
Verweisen Sie auf das ServiceDefaults- Projekt aus Ihrer ASP.NET Anwendung. Wählen Sie in Visual Studio Hinzufügen>Projektreferenz und wählen Sie das ServiceDefaults-Projekt"
Rufen Sie die OpenTelemetry-Setupfunktion
ConfigureOpenTelemetry()
als Teil der Initialisierung des Anwendungs-Generators auf.var builder = WebApplication.CreateBuilder(args) builder.ConfigureOpenTelemetry(); // Extension method from ServiceDefaults. var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.Run();
Eine vollständige exemplarische Vorgehensweise finden Sie unter Beispiel: Verwenden von OpenTelemetry mit OTLP und dem eigenständigen Aspire Dashboard.
Experimentelles Verbindungs-Tracing
Bei der Problembehandlung von HttpClient
-Problemen oder Engpässen kann es wichtig sein, zu erkennen, wo Zeit aufgewendet wird, wenn HTTP-Anfragen gesendet werden. Häufig tritt das Problem während der HTTP-Verbindungseinrichtung auf, was in der Regel auf die DNS-Abfrage, die TCP-Verbindung und den TLS-Handshake zurückzuführen ist.
.NET 9 hat eine experimentelle Verbindungsablaufverfolgung eingeführt, die eine HTTP connection setup
-Spanne mit drei untergeordneten Spannen für die DNS-, TCP- und TLS-Phasen des Verbindungsaufbaus hinzufügt. Der HTTP-Teil der Verbindungsablaufverfolgung wird innerhalb SocketsHttpHandlerimplementiert, was bedeutet, dass das Aktivitätsmodell das zugrunde liegende Verbindungspoolingverhalten respektieren muss.
Anmerkung
In SocketsHttpHandlerverfügen Verbindungen und Anforderungen über unabhängige Lebenszyklus. Eine gepoolte Verbindung kann über einen langen Zeitraum bestehen und viele Anforderungen bearbeiten. Wenn eine Anforderung gestellt wird, wenn keine Verbindung sofort im Verbindungspool verfügbar ist, wird die Anforderung einer Anforderungswarteschlange hinzugefügt, um auf eine verfügbare Verbindung zu warten. Es gibt keine direkte Beziehung zwischen Warteanforderungen und Verbindungen. Der Verbindungsprozess wurde möglicherweise gestartet, wenn eine andere Verbindung zur Verwendung verfügbar wurde, in diesem Fall wird die freigegebene Verbindung verwendet. Infolgedessen wird der HTTP connection setup
-Span nicht als untergeordneter Span des HTTP client request
-Spans modelliert, sondern es werden Link-Spans verwendet.
.NET 9 hat die folgenden Abschnitte eingeführt, um das Sammeln detaillierter Verbindungsinformationen zu ermöglichen:
Name | ActivitySource | Beschreibung |
---|---|---|
HTTP wait_for_connection |
Experimental.System.Net.Http.Connections |
Ein untergeordneter Span des HTTP client request -Spans, der das Zeitintervall darstellt, in dem die Anfrage auf eine verfügbare Verbindung in der Warteschlange wartet. |
HTTP connection_setup |
Experimental.System.Net.Http.Connections |
Stellt die Einrichtung der HTTP-Verbindung dar. Ein separater Trace Root Span mit seinem eigenen TraceId . HTTP client request -Spans können Links zu HTTP connection_setup enthalten. |
DNS lookup |
Experimental.System.Net.NameResolution |
Von der Dns-Klasse durchgeführte DNS-Suche. |
socket connect |
Experimental.System.Net.Sockets |
Aufbau einer Socket-Verbindung. |
TLS handshake |
Experimental.System.Net.Security |
TLS-Client- oder Server-Handshake, der von SslStreamausgeführt wird. |
Anmerkung
Die entsprechenden ActivitySource
-Namen beginnen mit dem Präfix Experimental
, da diese Spans in zukünftigen Versionen geändert werden könnten, wenn wir mehr darüber erfahren, wie gut sie in der Produktion funktionieren.
Diese Spans sind zu ausführlich für den 24x7-Einsatz in Produktionsszenarien mit hohem Workload – sie sind zu laut und dieses Maß an Instrumentierung ist normalerweise nicht erforderlich. Wenn Sie jedoch versuchen, Verbindungsprobleme zu diagnostizieren oder ein tieferes Verständnis darüber zu erhalten, wie sich die Netzwerk- und Verbindungslatenz auf Ihre Dienste auswirkt, bieten sie Einblicke, die auf andere Wege schwer zu erfassen sind.
Wenn die Experimental.System.Net.Http.Connections
ActivitySource aktiviert ist, enthält der HTTP client request
-Span einen Link zum HTTP connection_setup
-Span, der der Verbindung entspricht, die die Anfrage bedient. Da eine HTTP-Verbindung sehr langlebig sein kann, kann dies zu vielen Links zum Span der Verbindung von jeder der Aktivitäten der Anfrage führen. Einige APM-Überwachungstools gehen aggressiv über Links zwischen Spans, um ihre Ansichten aufzubauen, und so kann die Einbeziehung dieses Spans zu Problemen führen, wenn die Tools nicht für eine große Anzahl von Links ausgelegt sind.
Das folgende Diagramm veranschaulicht das Verhalten der Spannen und deren Beziehung:
Exemplarische Vorgehensweise: Verwendung des Experimentellen Verbindungs-Tracings in .NET 9
Diese exemplarische Vorgehensweise verwendet eine .NET 9 Aspire Starter App, um das Tracing von Verbindungen zu demonstrieren, aber es sollte einfach sein, es auch mit anderen Überwachungstools festzulegen. Der wichtigste Schritt besteht darin, die ActivitySources zu aktivieren.
Erstellen Sie eine .NET Aspire 9 Starter App mithilfe von
dotnet new
:dotnet new aspire-starter-9 --output ConnectionTracingDemo
Oder in Visual Studio:
Öffnen Sie
Extensions.cs
imServiceDefaults
-Projekt und bearbeiten Sie die MethodeConfigureOpenTelemetry
, indem Sie die ActivitySources für die Verbindung im Callback der Tracing-Konfiguration hinzufügen:.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.*"); });
Starten Sie die Lösung. Dies sollte das .NET Aspire Dashboardöffnen.
Navigieren Sie zur Seite Wetter der
webfrontend
App, um eineHttpClient
Anfrage in Richtungapiservice
zu generieren.Kehren Sie zum Dashboard zurück und navigieren Sie zur Seite Traces. Öffnen Sie das
webfrontend: GET /weather
-Tracing.
Wenn HTTP-Anforderungen mit aktivierter Verbindungsinstrumentation vorgenommen werden, sollten die folgenden Änderungen an der Clientanforderungsspanne angezeigt werden:
- Wenn eine Verbindung hergestellt werden muss oder die App auf eine Verbindung aus dem Verbindungspool wartet, wird eine zusätzliche
HTTP wait_for_connection
Spanne angezeigt, die die Verzögerung für das Warten auf eine Verbindung darstellt. Dies hilft, Verzögerungen zwischen derHttpClient
Anforderung im Code und beim Start der Verarbeitung der Anforderung zu verstehen. In der vorherigen Abbildung:- Die ausgewählte Spanne ist die HttpClient-Anforderung.
- Die folgende Spanne stellt die Zeit dar, zu der die Anforderung auf das Herstellen einer Verbindung wartet.
- Die letzte Spanne in Gelb stammt vom Ziel, das die Anforderung verarbeitet.
- Die HttpClient-Spanne enthält einen Link zur
HTTP connection_setup
Spanne, die die Aktivität zum Erstellen der http-Verbindung darstellt, die von der Anforderung verwendet wird.
Wie bereits erwähnt, ist der HTTP connection_setup
-Span ein separater Span mit eigenem TraceId
, da seine Lebensdauer unabhängig von jeder einzelnen Client-Anfrage ist. Dieser Span hat normalerweise untergeordnete Spans DNS lookup
, (TCP) socket connect
und TLS client handshake
.
Anreicherung
In einigen Fällen ist es notwendig, die bestehende System.Net
-Funktionalität des Tracings zu erweitern. Dies bedeutet in der Regel, dass zusätzliche Tags/Attribute in die integrierten Aktivitäten eingefügt werden. Dies wird Anreicherung genannt.
API zur Anreicherung in der OpenTelemetry-Instrumentierungsbibliothek
Um der HTTP-Clientanforderungsaktivität zusätzliche Tags/Attribute hinzuzufügen, besteht der einfachste Ansatz darin, die HttpClient
Anreicherungs-APIs der OpenTelemetry HttpClient- und HttpWebRequest-Instrumentationsbibliothek zu verwenden. Dies erfordert das Eingeben einer Abhängigkeit vom OpenTelemetry.Instrumentation.Http
-Paket.
Manuelle Anreicherung
Es ist möglich, die Anreicherung der HTTP client request
Aktivität manuell zu implementieren. Hierfür müssen Sie im Code, der im Bereich der Anforderungsaktivität ausgeführt wird, auf Activity.Current zugreifen, bevor die Aktivität abgeschlossen ist. Dazu implementieren Sie ein IObserver<DiagnosticListener>
und abonnieren es bei AllListeners, um Callbacks zu erhalten, wenn eine Networking-Aktivität stattfindet. Auf diese Weise ist die OpenTelemetry HttpClient und HttpWebRequest Instrumentierungsbibliothek implementiert. Ein Codebeispiel finden Sie im Abonnementcode in DiagnosticSourceSubscriber.cs
und der zugrunde liegenden Implementierung in HttpHandlerDiagnosticListener.cs, an die die Benachrichtigungen delegiert werden.
Benötigen Sie mehr Tracing?
Wenn Sie Vorschläge für andere nützliche Informationen haben, die über Tracing aufgedeckt werden könnten, erstellen Sie ein dotnet/runtime issue.