Ablaufverfolgung von .NET-Anwendungen mit perfcollect

Dieser Artikel gilt für: ✔️ .NET Core 2.1 SDK und neuere Versionen

Wenn unter Linux Leistungsprobleme auftreten, können Sie mit perfcollect eine Ablaufverfolgung erfassen, um detaillierte Informationen zu den Vorgängen auf dem Computer zum Zeitpunkt des Leistungsproblems zu sammeln.

perfcollect ist ein Bash-Skript für das Linux Trace Toolkit: next generation (LTTng), um von der Runtime oder einer beliebigen EventSource geschriebene Ereignisse zu sammeln, sowie perf, um CPU-Stichproben des Zielprozesses zu sammeln.

Vorbereiten Ihres Computers

Führen Sie die folgenden Schritte durch, um Ihren Computer für das Erfassen einer Leistungsablaufverfolgung mit perfcollect vorzubereiten.

Hinweis

Wenn die Erfassung innerhalb eines Containers erfolgt, muss Ihr Container über die entsprechenden Fähigkeiten 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 Funktion SYS_ADMIN hinzu. Weitere Informationen zur Ablaufverfolgung von Anwendungen innerhalb von Containern mithilfe von perfcollect finden Sie unter Sammeln von Diagnosen in Containern.

  1. Laden Sie perfcollect herunter.

    curl -OL https://aka.ms/perfcollect
    
  2. Sorgen Sie dafür, dass das Skript ausführbar ist.

    chmod +x perfcollect
    
  3. Installieren Sie die für die Ablaufverfolgung erforderlichen Komponenten. Dabei handelt es sich um die eigentlichen Ablaufverfolgungsbibliotheken.

    sudo ./perfcollect install
    

    Auf diese Weise werden die folgenden erforderlichen Komponenten auf Ihrem Computer installiert:

    1. perf: Dies ist das Linux-Subsystem zu Leistungsereignissen und die begleitende Anwendung zur Benutzermodusanzeige/-sammlung. perf ist Teil der Linux-Kernelquelle, wird bei der Standardeinstellung normalerweise jedoch nicht 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 Runtimekomponenten wie GC, JIT und Threadpool zu analysieren.

Die neuesten Versionen von .NET Core und das Linux-Leistungstool unterstützen die automatische Auflösung von Methodennamen für Frameworkcode.

Zum Auflösen von Methodennamen nativer Runtime-DLLs (z. B. libcoreclr.so) löst perfcollect beim Konvertieren von Daten Symbole für diese auf. Allerdings trifft dies nur zu, 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. Sie benötigen zwei Shells: eine zum Steuern der Ablaufverfolgung, als [Trace] bezeichnet, und eine zum Ausführen der Anwendung, als [App] bezeichnet.

  2. [Trace] Starten Sie die Ablaufverfolgung.

    sudo ./perfcollect collect sampleTrace
    

    Erwartete Ausgabe:

    Collection started.  Press CTRL+C to stop.
    
  3. [App] Richten Sie die Anwendungsshell mit den folgenden Umgebungsvariablen ein. Dies ermöglicht die CoreCLR-Konfiguration für die Ablaufverfolgung.

    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

    In .NET 6 ist das Präfix DOTNET_ statt COMPlus_ Standard für Umgebungsvariablen, die das .NET-Runtimeverhalten konfigurieren. Das Präfix COMPlus_ funktioniert jedoch weiterhin. Wenn Sie eine frühere Version der .NET-Runtime verwenden, sollten Sie weiterhin das Präfix COMPlus_ für Umgebungsvariablen verwenden.

  4. [App] Führen Sie die App aus, und zwar so lange wie nötig, um das Leistungsproblem zu erfassen. Die genaue Ausführungsdauer kann auch nur sehr kurz sein, solange das Zeitfenster, in dem das zu untersuchende Leistungsproblem auftritt, ausreichend erfasst wird.

    dotnet run
    
  5. [Trace] Halten Sie die Ablaufverfolgung an. Drücken Sie dazu 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 Ablaufverfolgungsdatei ist jetzt im aktuellen Arbeitsverzeichnis gespeichert.

Anzeigen einer Ablaufverfolgung

Es gibt mehrere Möglichkeiten, die erfasste Ablaufverfolgung anzuzeigen. Ablaufverfolgungen werden am besten mithilfe von PerfView unter Windows angezeigt. Sie können aber auch direkt unter Linux mithilfe von PerfCollect selbst oder mit TraceCompass angezeigt werden.

Verwenden von perfcollect zum Anzeigen der Ablaufverfolgungsdatei

Sie können perfcollect selbst verwenden, um die erfasste Ablaufverfolgung anzuzeigen. Führen Sie zu diesem Zweck den folgenden Befehl aus:

./perfcollect view sampleTrace.trace.zip

Dadurch wird standardmäßig die CPU-Überwachung der Anwendung mithilfe von perf angezeigt.

Zum Anzeigen der über LTTng erfassten Ereignisse können Sie das Flag -viewer lttng übergeben, um die einzelnen Ereignisse anzuzeigen:

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

Dadurch wird der babeltrace-Viewer zum Drucken der Nutzdaten der Ereignisse verwendet:

# [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 von PerfView zum Öffnen der Ablaufverfolgungsdatei

Zum Anzeigen einer Aggregatansicht sowohl des CPU-Beispiels als auch der Ereignisse können Sie PerfView auf einem Windows-Computer verwenden.

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

  2. Laden Sie PerfView über den folgenden Link herunter: https://aka.ms/perfview.

  3. Führen Sie PerfView.exe aus.

    PerfView.exe <path to trace.zip file>
    

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

  • Wählen Sie für CPU-Untersuchungen CPU-Stapel aus.

  • Wählen Sie für detaillierte Informationen GCStats aus.

  • Wählen Sie für JIT-Informationen pro Prozess/Modul/Methode JITStats aus.

  • Wenn für die von Ihnen benötigten Informationen keine Ansicht vorhanden ist, können Sie versuchen, die Ereignisse in der Rohdatenansicht für Ereignisse anzuzeigen. Wählen Sie Ereignisse aus.

Weitere Informationen zum Interpretieren von Ansichten in PerfView finden Sie unter den Hilfeverknüpfungen in der Ansicht selbst oder im Hauptfenster von PerfView unter Help > Users Guide (Hilfe > Benutzerleitfaden).

Hinweis

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

Hinweis

Wenn Sie [unknown] /memfd:doublemapper-Frames in Methodennamen und Aufruflisten beobachten, legen Sie DOTNET_EnableWriteXorExecute=0 vor dem Ausführen der App fest, die Sie mit „perfcollect“ nachverfolgen.

Verwenden von TraceCompass zum Öffnen der Ablaufverfolgungsdatei

Eclipse Trace Compass ist eine weitere Option zum Anzeigen der Ablaufverfolgungen. TraceCompass funktioniert auch auf Linux-Computern, sodass Sie die Ablaufverfolgung nicht auf einen Windows-Computer verschieben müssen. Wenn Sie TraceCompass zum Öffnen Ihrer Ablaufverfolgungsdatei verwenden möchten, müssen Sie die Datei entzippen.

unzip myTrace.trace.zip

perfcollect speichert die erfasste LTTng-Ablaufverfolgung in einem CTF-Dateiformat in einem Unterverzeichnis von lttngTrace. Die CTF-Datei wird in einem Verzeichnis ähnlich dem folgenden gespeichert: lttngTrace/auto-20201025-101230\ust\uid\1000\64-bit\.

Sie können die CTF-Ablaufverfolgungsdatei in TraceCompass öffnen, indem Sie auf File -> Open Trace und dann auf die metadata-Datei klicken.

Weitere Informationen finden Sie in der TraceCompass-Dokumentation.

Abrufen von Symbolen für die native Runtime

In den meisten Fällen sind Sie an Ihrem eigenen Code interessiert, den perfcollect standardmäßig auflöst. Manchmal ist es hilfreich zu wissen, was innerhalb der .NET-DLLs vor sich geht (wovon der letzte Abschnitt handelte). Manchmal ist es aber auch interessant, was in den nativen Runtime-DLLs (in der Regel libcoreclr.so) geschieht. perfcollect löst die Symbole für diese auf, wenn deren Daten konvertiert werden. Dies ist jedoch nur der Fall, wenn die Symbole für diese nativen DLLs vorhanden sind (und sich neben der Bibliothek befinden, der sie dienen).

Sie können hierfür den globalen Befehl dotnet-symbol verwenden. So verwenden Sie „dotnet-symbol“ zum Abrufen von Symbolen der nativen Runtime:

  1. Installieren Sie dotnet-symbol:

    dotnet tool install -g dotnet-symbol
    
  2. Laden Sie die Symbole herunter. Wenn Sie die Version 2.1.0 der .NET Core-Runtime installiert haben, lautet der Befehl hierfür folgendermaßen:

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

    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 Sie die Symbole mithilfe von perf buildid-cache hinzufügen.

Danach sollten symbolische Namen für die nativen DLLs zurückgegeben werden, wenn Sie perfcollect ausführen.

Sammeln in einem Docker-Container

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

Weitere Informationen zu Sammlungsoptionen

Mit perfcollect können Sie die folgenden optionalen Flags gemäß Ihren Diagnoseanforderungen angeben.

Sammeln für eine bestimmte Dauer

Zum Sammeln einer Ablaufverfolgung für eine bestimmte Dauer ist die Option -collectsec geeignet, gefolgt von der Gesamtanzahl der Sekunden für die Sammlung.

Sammeln von Ablaufverfolgungen der Threadzeit

Wenn Sie threadspezifische Daten zur CPU-Auslastung sammeln möchten, geben Sie -threadtime mit perfcollect an. Auf diese Weise können Sie die CPU-Zeit pro Thread analysieren.

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

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

  • perfcollect collect -gccollectonly

Es wird nur eine minimale Anzahl von GC-Ereignissen gesammelt. Hierbei handelt es sich um das am wenigsten ausführliche Sammlungsprofil von GC-Ereignissen mit den geringsten Auswirkungen auf die Leistung der Ziel-App. Dieser Befehl entspricht dem Befehl PerfView.exe /GCCollectOnly collect in PerfView.

  • perfcollect collect -gconly

Mit JIT-, Ladeprogramm- und Ausnahmeereignissen werden ausführlichere GC-Ereignisse gesammelt. Dies erfordert ausführlichere Ereignisse (z. B. Zuordnungs- und GC-Joininformationen) und wirkt sich stärker auf die Leistung der Ziel-App aus als Option -gccollectonly. Dieser Befehl entspricht dem Befehl PerfView.exe /GCOnly collect in PerfView.

  • perfcollect collect -gcwithheap

Hierbei werden die ausführlichsten GC-Ereignisse gesammelt, die auch die beibehaltenen Objekte und Bewegungen des Heaps nachverfolgen. Dies ermöglicht eine detaillierte Analyse des GC-Verhaltens, führt jedoch zu hohen Leistungseinbußen, da jede GC mehr als doppelt so lange dauern kann. Wenn Sie Ablaufverfolgungen in Produktionsumgebungen verwenden möchten, sollten Sie über die Auswirkungen dieser Option auf die Leistung Bescheid wissen.