Freigeben über


Nachverfolgen von .NET-Anwendungen mit PerfCollect

Dieser Artikel bezieht sich auf: ✔️ .NET Core 2.1 SDK und höhere Versionen

Wenn unter Linux Leistungsprobleme auftreten, kann das Erfassen einer Ablaufverfolgung mit perfcollect verwendet werden, um detaillierte Informationen darüber zu sammeln, was zum Zeitpunkt des Leistungsproblems auf dem Computer passiert ist.

perfcollect ist ein Bash-Skript, das Linux Trace Toolkit: next generation (LTTng) verwendet, um Ereignisse zu sammeln, die aus der Runtime oder einer beliebigen EventSource geschrieben wurden, sowie perf , um CPU-Stichproben des Zielprozesses zu sammeln.

Vorbereiten des Computers

Führen Sie die folgenden Schritte aus, um Ihren Computer für das Erfassen einer Leistungsablaufverfolgung mit perfcollectvorzubereiten.

Hinweis

Wenn Sie aus einem Container erfassen, muss Ihr Container über die entsprechenden Funktionen verfügen. Die minimal erforderlichen Funktionen sind PERFMON und .SYS_PTRACE Wenn die Erfassung mit dem minimalen Satz fehlschlägt, fügen Sie dem Container die SYS_ADMIN Funktion hinzu. Weitere Informationen zum Ablaufen von Anwendungen in Containern mithilfe von PerfCollect finden Sie unter Erfassen von Diagnosen in Containern.

  1. Laden Sie perfcollect herunter.

    curl -OL https://aka.ms/perfcollect
    
  2. Machen Sie das Skript ausführbar.

    chmod +x perfcollect
    
  3. Installieren der Voraussetzungen für die Ablaufverfolgung – dies sind die eigentlichen Ablaufverfolgungsbibliotheken.

    sudo ./perfcollect install
    

    Dadurch werden die folgenden Voraussetzungen auf Ihrem Computer installiert:

    1. perf: das Subsystem für Linux-Leistungsereignisse und die zugehörige Sammlungs-/Betrachteranwendung im Benutzermodus. perf ist Teil des Linux-Kernel-Quellcodes, wird aber normalerweise nicht standardmäßig installiert.
    2. LTTng: Wird zum Erfassen von Ereignisdaten verwendet, die zur Laufzeit von CoreCLR ausgegeben werden. Diese Daten werden dann verwendet, um das Verhalten verschiedener Laufzeitkomponenten wie GC, JIT und Thread-Pool zu analysieren.

Neuere Versionen von .NET Core und dem Linux-Perf-Tool unterstützen die automatische Auflösung von Methodennamen für Frameworkcode.

Zum Auflösen von Methodennamen von systemeigenen Laufzeit-DLLs (z. B. libcoreclr.so) perfcollect werden Symbole für diese aufgelöst, wenn die Daten konvertiert werden, jedoch nur, wenn die Symbole für diese Binärdateien vorhanden sind. Weitere Informationen finden Sie im Abschnitt Abrufen von Symbolen für die native Runtime .

Erfassen einer Ablaufverfolgung

  1. Es stehen zwei Shells zur Verfügung: eine zum Steuern der Ablaufverfolgung, die als [Trace] bezeichnet wird, und eine zum Ausführen der Anwendung, die als [App] bezeichnet wird.

  2. [Spur] Starten Sie die Sammlung.

    sudo ./perfcollect collect sampleTrace
    

    Erwartete Ausgabe:

    Collection started.  Press CTRL+C to stop.
    

    Hinweis

    LTTng hatte zwischen den Versionen 2.12 und 2.13 einen Breaking Change. Die .NET-Runtime unterstützt derzeit Version 2.12. Wenn Ihre Linux-Distribution 2.13 oder höher übernommen hat, empfehlen wir, den LTTng-Teil der perfcollect-Funktionalität zu deaktivieren. Fügen Sie dazu die Option '-nolttng' in die perfcollect-Befehlszeile ein und setzen Sie in Schritt 3 die Umgebungsvariable DOTNET_EnableEventLog nicht.

  3. [App] Richten Sie die Anwendungsshell mit den folgenden Umgebungsvariablen ein: Dies ermöglicht die Ablaufverfolgungskonfiguration von CoreCLR.

  4. [App] Richten Sie die Anwendungsshell mit den folgenden Umgebungsvariablen ein: Dies ermöglicht die Ablaufverfolgungskonfiguration von CoreCLR.

    export DOTNET_PerfMapEnabled=1
    export DOTNET_EnableEventLog=1
    

    Hinweis

    Beim Ausführen der App mit .NET 7 müssen Sie zusätzlich zu den vorherigen Umgebungsvariablen auch DOTNET_EnableWriteXorExecute=0 festlegen. Beispiel:

    export DOTNET_EnableWriteXorExecute=0
    

    Hinweis

    .NET 6 standardisiert das Präfix DOTNET_ anstelle von COMPlus_ für Umgebungsvariablen, die das .NET-Laufzeitverhalten konfigurieren. Das Präfix COMPlus_ funktioniert jedoch weiterhin. Wenn Sie eine frühere Version der .NET-Laufzeit verwenden, sollten Sie weiterhin das präfix COMPlus_ für Umgebungsvariablen verwenden.

  5. [App] Führen Sie die App aus – lassen Sie sie so lange laufen, wie Sie möchten, um das Leistungsproblem zu erfassen. Die genaue Länge kann so kurz sein, wie Sie es benötigen, solange sie das Zeitfenster, in dem das zu untersuchende Leistungsproblem auftritt, ausreichend erfasst.

    dotnet run
    
  6. [Spur] Sammlung beenden – drücken Sie Strg+C.

    ^C
    ...STOPPED.
        Starting post-processing. This may take some time.
        Generating native image symbol files
    ...SKIPPED
    Saving native symbols
    ...FINISHED
    Exporting perf.data file
    ...FINISHED
    Compressing trace files
    ...FINISHED
    Cleaning up artifacts
    ...FINISHED
        Trace saved to sampleTrace.trace.zip
    

    Die komprimierte Trace-Datei wird nun im aktuellen Arbeitsverzeichnis gespeichert.

Anzeigen einer Ablaufverfolgung

Es gibt eine Reihe von Optionen zum Anzeigen der erfassten Ablaufverfolgung. Ablaufverfolgungen werden am besten mit PerfView unter Windows angezeigt, können aber auch direkt unter Linux mit PerfCollect sich selbst oder TraceCompassangezeigt werden.

Verwenden von PerfCollect zum Anzeigen der Ablaufverfolgungsdatei

Sie können perfcollect selbst verwenden, um die von Ihnen erfasste Ablaufverfolgung anzuzeigen. Verwenden Sie dazu den folgenden Befehl:

./perfcollect view sampleTrace.trace.zip

Standardmäßig wird die CPU-Ablaufverfolgung der Anwendung mit perf.

Um sich die Ereignisse anzusehen, die über LTTnggesammelt wurden, können Sie das Flag -viewer lttng einschieben, um die einzelnen Ereignisse zu sehen:

./perfcollect view sampleTrace.trace.zip -viewer lttng

Dadurch wird der Viewer verwendet babeltrace , um die Ereignisnutzlast zu drucken:

# [01:02:18.189217659] (+0.020132603) ubuntu-xenial DotNETRuntime:ExceptionThrown_V1: { cpu_id = 0 }, { ExceptionType = "System.Exception", ExceptionMessage = "An exception happened", ExceptionEIP = 139875671834775, ExceptionHRESULT = 2148734208, ExceptionFlags = 16, ClrInstanceID = 0 }
# [01:02:18.189250227] (+0.020165171) ubuntu-xenial DotNETRuntime:ExceptionCatchStart: { cpu_id = 0 }, { EntryEIP = 139873639728404, MethodID = 139873626968120, MethodName = "void [helloworld] helloworld.Program::Main(string[])", ClrInstanceID = 0 }

Verwenden Sie PerfView, um die Ablaufverfolgungsdatei zu öffnen

Um eine aggregierte Ansicht sowohl des CPU-Beispiels als auch der Ereignisse anzuzeigen, können Sie dies auf einem Windows-Computer verwenden PerfView .

  1. Kopieren Sie die trace.zip Datei von Linux auf einen Windows-Computer.

  2. Laden Sie PerfView von https://aka.ms/perfviewherunter.

  3. Führen Sie PerfView.exe aus

    PerfView.exe <path to trace.zip file>
    

PerfView zeigt die Liste der Ansichten an, die basierend auf den in der Ablaufverfolgungsdatei enthaltenen Daten unterstützt werden.

  • Wählen Sie für CPU-Untersuchungen die Option CPU-Stacks aus.
  • Um detaillierte GC-Informationen zu erhalten, wählen Sie GCStats.
  • Wählen Sie für JIT-Informationen pro Prozess/Modul/Methode JITStats aus.
  • Wenn es keine Ansicht für die benötigten Informationen gibt, können Sie versuchen, in der Ansicht der unformatierten Ereignisse nach den Ereignissen zu suchen. Wählen Sie Events (Ereignisse) aus.

Weitere Informationen zum Interpretieren von Ansichten in PerfView finden Sie unter Hilfe-Links in der Ansicht selbst oder wählen Sie im Hauptfenster von PerfView Hilfe-Benutzerhandbuch> aus.

Hinweis

Ereignisse, die über System.Diagnostics.Tracing.EventSource die API geschrieben wurden (einschließlich der Ereignisse aus Framework), werden nicht unter ihrem Anbieternamen angezeigt. Stattdessen werden sie als EventSourceEvent Ereignisse unter Microsoft-Windows-DotNETRuntime provider geschrieben, und ihre Nutzlasten werden JSON-serialisiert.

Hinweis

Wenn Sie Frames in Methodennamen und Aufruflisten beobachten [unknown] /memfd:doublemapper , legen Sie diese fest DOTNET_EnableWriteXorExecute=0 , bevor Sie die App ausführen, die Sie mit perfcollect verfolgen.

Verwenden von TraceCompass zum Öffnen der Trace-Datei

Eclipse TraceCompass ist eine weitere Option, mit der Sie die Ablaufverfolgungen anzeigen können. TraceCompass funktioniert auch auf Linux-Computern, sodass Sie Ihre Ablaufverfolgung nicht auf einen Windows-Computer verschieben müssen. TraceCompass Um die Ablaufverfolgungsdatei zu öffnen, müssen Sie die Datei entpacken.

unzip myTrace.trace.zip

perfcollectspeichert den gesammelten LTTng-Trace in einem CTF-Dateiformat in einem Unterverzeichnis in .lttngTrace Konkret befindet sich die CTF-Datei in einem Verzeichnis, das wie lttngTrace/auto-20201025-101230\ust\uid\1000\64-bit\folgt aussieht: .

Sie können die CTF-Ablaufverfolgungsdatei öffnen TraceCompass , indem Sie die Datei auswählen File -> Open Trace und auswählen metadata .

Weitere Informationen finden Sie in der DokumentationTraceCompass.

Abrufen von Symbolen für die native Laufzeit

Meistens interessieren Sie sich für Ihren eigenen Code, der perfcollect standardmäßig aufgelöst wird. Manchmal ist es nützlich zu sehen, was in den .NET-DLLs vor sich geht (worum es im letzten Abschnitt ging), aber manchmal ist es interessant, was in den systemeigenen Laufzeit-DLLs (in der Regel libcoreclr.so) vor sich geht. perfcollect löst die Symbole für diese auf, wenn es seine Daten konvertiert, aber nur, wenn die Symbole für diese nativen DLLs vorhanden sind (und sich neben der Bibliothek befinden, für die sie bestimmt sind).

Es gibt einen globalen Befehl namens dotnet-symbol , der dies tut. So verwenden Sie dotnet-symbol zum Abrufen nativer Laufzeitsymbole:

  1. Installieren dotnet-symbol:

    dotnet tool install -g dotnet-symbol
    
  2. Laden Sie die Symbole herunter. Wenn Ihre installierte Version der .NET Core-Runtime 2.1.0 ist, lautet der Befehl hierfür:

    mkdir mySymbols
    dotnet symbol --symbols --output mySymbols  /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.0/lib*.so
    
  3. Kopieren Sie die Symbole an die richtige Stelle.

    sudo cp mySymbols/* /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.0
    

    Wenn dies nicht möglich ist, weil Sie keinen Schreibzugriff auf das entsprechende Verzeichnis haben, können perf buildid-cache Sie die Symbole hinzufügen.

Danach sollten Sie symbolische Namen für die systemeigenen DLLs erhalten, wenn Sie perfcollect.

Sammeln in einem Docker-Container

Weitere Informationen zur Verwendung perfcollect in Containerumgebungen finden Sie unter Sammeln von Diagnosen in Containern.

Erfahren Sie mehr über die Erfassungsoptionen

Sie können die folgenden optionalen Flags perfcollect angeben, um Ihren Diagnoseanforderungen besser gerecht zu werden.

Sammeln für eine bestimmte Dauer

Wenn Sie eine Ablaufverfolgung für eine bestimmte Dauer erfassen möchten, können Sie die Option verwenden -collectsec , gefolgt von einer Zahl, die die Gesamtzahl der Sekunden angibt, für die eine Ablaufverfolgung erfasst werden soll.

Sammeln von Threadtime-Ablaufverfolgungen

Mit der Angabe -threadtime von perfcollect können Sie Daten zur CPU-Auslastung pro Thread erfassen. Auf diese Weise können Sie analysieren, wo jeder Thread seine CPU-Zeit verbracht hat.

Sammeln von Ablaufverfolgungen für die Leistung des verwalteten Arbeitsspeichers und des Garbage Collectors

Mit den folgenden Optionen können Sie die GC-Ereignisse speziell aus der Laufzeit erfassen.

  • perfcollect collect -gccollectonly

Erfassen Sie nur einen minimalen Satz von GC Collection-Ereignissen. Dies ist das am wenigsten ausführliche GC-Ereigniserfassungsprofil mit den geringsten Auswirkungen auf die Leistung der Ziel-App. Dieser Befehl entspricht dem PerfView.exe /GCCollectOnly collect Befehl in PerfView.

  • perfcollect collect -gconly

Erfassen Sie ausführlichere GC-Sammlungsereignisse mit JIT-, Loader- und Exception-Ereignissen. Dies erfordert ausführlichere Ereignisse (z. B. die Zuordnungsinformationen und GC-Join-Informationen) und wirkt sich stärker auf die Leistung der Ziel-App aus als -gccollectonly die Option. Dieser Befehl entspricht dem PerfView.exe /GCOnly collect Befehl in PerfView.

  • perfcollect collect -gcwithheap

Sammeln Sie die ausführlichsten GC-Sammlungsereignisse, die auch das Überleben und die Bewegungen des Heaps verfolgen. Dies ermöglicht eine detaillierte Analyse des GC-Verhaltens, verursacht jedoch hohe Performance-Kosten, da jeder GC mehr als doppelt so lange dauern kann. Es wird empfohlen, dass Sie die Auswirkungen der Verwendung dieser Ablaufverfolgungsoption auf die Leistung bei der Ablaufverfolgung in Produktionsumgebungen verstehen.