Seguimiento de aplicaciones de .NET con PerfCollect

Este artículo se aplica a: ✔️ SDK de .NET Core 2.1 y versiones posteriores

Cuando se producen problemas de rendimiento en Linux, la recopilación de un seguimiento con perfcollect se puede usar para recopilar información detallada sobre lo que ocurre en el equipo en el momento del problema de rendimiento.

perfcollect es un script de bash que usa Linux Trace Toolkit: next generation (LTTng), el kit de herramientas de seguimiento de Linux de próxima generación, para recopilar eventos escritos en el entorno de ejecución o cualquier elemento EventSource, así como perf para recopilar ejemplos de CPU del proceso de destino.

Preparación del equipo

Siga estos pasos para preparar el equipo a fin de recopilar un seguimiento de rendimiento con perfcollect.

Nota:

Si va a capturar desde dentro de un contenedor, el contenedor debe tener las funcionalidades adecuadas. Las funcionalidades mínimas necesarias son PERFMON y SYS_PTRACE. Si se produce un error en la captura con el conjunto mínimo, agregue la funcionalidad SYS_ADMIN al contenedor. Para obtener más información sobre el seguimiento de aplicaciones dentro de contenedores con PerfCollect, vea Recopilación de diagnósticos en contenedores.

  1. Descargue perfcollect.

    curl -OL https://aka.ms/perfcollect
    
  2. Haga que el script sea ejecutable.

    chmod +x perfcollect
    
  3. Instale los requisitos previos de seguimiento; son las bibliotecas de seguimiento reales.

    sudo ./perfcollect install
    

    Esto instalará los siguientes requisitos previos en el equipo:

    1. perf: subsistema de eventos de rendimiento de Linux y aplicación complementaria del visor o recopilación de modo de usuario. perf forma parte del origen del kernel de Linux, pero normalmente no se instala de forma predeterminada.

    2. LTTng: se usa para capturar datos de eventos emitidos en tiempo de ejecución por CoreCLR. Después, estos datos se usan para analizar el comportamiento de varios componentes del entorno de ejecución, como el GC, JIT y el grupo de subprocesos.

Las versiones recientes de .NET Core y la herramienta perf de Linux admiten la resolución automática de nombres de método para el código del marco.

Para resolver los nombres de métodos de archivos DLL nativos del entorno de ejecución (como libcoreclr.so), perfcollect resolverá sus símbolos al convertir los datos, pero solo si los símbolos de estos archivos binarios están presentes. Para obtener más información, vea la sección Obtención de símbolos para el entorno de ejecución nativo.

Recopilación de un seguimiento

  1. Debe tener dos shells disponibles: uno para controlar el seguimiento, denominado [Trace] , y otro para ejecutar la aplicación, denominado [App] .

  2. [Trace] Inicie la recolección.

    sudo ./perfcollect collect sampleTrace
    

    Salida esperada:

    Collection started.  Press CTRL+C to stop.
    
  3. [App] Configure el shell de aplicaciones con las variables de entorno siguientes; esto habilita la configuración de seguimiento de CoreCLR.

    export DOTNET_PerfMapEnabled=1
    export DOTNET_EnableEventLog=1
    

    Nota:

    Al ejecutar la aplicación con .NET 7, también debe establecer DOTNET_EnableWriteXorExecute=0 además de las variables de entorno anteriores. Por ejemplo:

    export DOTNET_EnableWriteXorExecute=0
    

    Nota

    .NET 6 estandariza en el prefijo DOTNET_ en lugar de en COMPlus_ para las variables de entorno que configuran el comportamiento en tiempo de ejecución de .NET. Sin embargo, el prefijo COMPlus_ seguirá funcionando. Si usa una versión anterior del runtime de .NET, debe seguir usando el prefijo COMPlus_ para las variables de entorno.

  4. [App] Ejecute la aplicación; permita que se ejecute siempre que sea necesario para capturar el problema de rendimiento. La longitud exacta puede ser tan breve como sea necesario, siempre y cuando capture el período de tiempo en el que se produce el problema de rendimiento que se quiere investigar.

    dotnet run
    
  5. [Trace] Detenga la recolección; presione Ctrl + 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
    

    Ahora el archivo de seguimiento comprimido se almacena en el directorio de trabajo actual.

Visualización de un seguimiento

Hay una serie de opciones para ver el seguimiento que se ha recopilado. Los seguimientos se ven mejor con PerfView en Windows, pero se pueden ver directamente en Linux mediante el propio PerfCollect o TraceCompass.

Uso de PerfCollect para ver el archivo de seguimiento

Puede usar perfcollect para ver el seguimiento que se ha recopilado. Para ello, ejecute el siguiente comando:

./perfcollect view sampleTrace.trace.zip

De forma predeterminada, se mostrará el seguimiento de la CPU de la aplicación mediante perf.

Para examinar los eventos recopilados a través de LTTng, puede pasar la marca -viewer lttng a fin de ver los eventos individuales:

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

Se usará el visor babeltrace para imprimir la carga de eventos:

# [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 }

Uso de PerfView para abrir el archivo de seguimiento

Para ver una vista agregada del ejemplo de CPU y de los eventos, puede usar PerfView en un equipo Windows.

  1. Copie el archivo trace.zip de Linux en un equipo Windows.

  2. Descargue PerfView de https://aka.ms/perfview.

  3. Ejecución de PerfView.exe

    PerfView.exe <path to trace.zip file>
    

PerfView mostrará la lista de vistas que se admiten en función de los datos contenidos en el archivo de seguimiento.

  • Para las investigaciones de CPU, elija CPU stacks (Pilas de CPU).

  • Para obtener información detallada sobre la recolección de elementos no utilizados, elija GCStats.

  • Para obtener información de JIT en función de un proceso, módulo o método, elija JITStats.

  • Si no hay ninguna vista de la información que necesita, puede intentar buscar los eventos en la vista de eventos sin procesar. Elija Events (Eventos).

Para obtener más información sobre cómo interpretar las vistas en PerfView, vea los vínculos de ayuda en la propia vista, o bien elija Ayuda->Guía de usuarios en la ventana principal de PerfView.

Nota

Los eventos escritos mediante la API System.Diagnostics.Tracing.EventSource (incluidos los de Framework) no se mostrarán bajo el nombre de su proveedor. En su lugar, se escriben como eventos EventSourceEvent en el proveedor Microsoft-Windows-DotNETRuntime y sus cargas se serializan en JSON.

Nota

Si observa marcos de [unknown] /memfd:doublemapper en nombres de método y pilas de llamadas, establezca DOTNET_EnableWriteXorExecute=0 antes de ejecutar la aplicación que está siguiendo con PerfCollect.

Uso de TraceCompass para abrir el archivo de seguimiento

Eclipse TraceCompass es otra opción que puede usar para ver los seguimientos. TraceCompass también funciona en equipos Linux, por lo que no es necesario trasladar el seguimiento a un equipo Windows. Para usar TraceCompass y abrir el archivo de seguimiento, tendrá que descomprimirlo.

unzip myTrace.trace.zip

perfcollect guardará el seguimiento de LTTng que ha recopilado en un formato de archivo CTF en un subdirectorio de lttngTrace. En concreto, el archivo CTF se ubicará en un directorio como lttngTrace/auto-20201025-101230\ust\uid\1000\64-bit\.

Puede abrir el archivo de seguimiento CTF en TraceCompass si selecciona File -> Open Trace y, después, el archivo metadata.

Para obtener más información, consulte la documentación de TraceCompass.

Obtención de símbolos para el entorno de ejecución nativo

En la mayoría de los casos le interesará el código propio, que perfcollect resuelve de forma predeterminada. En ocasiones resulta útil ver lo que ocurre dentro de los archivos DLL de .NET (el objetivo de la última sección), pero a veces es interesante lo que sucede en los archivos DLL del entorno de ejecución nativo (normalmente libcoreclr.so). perfcollect resolverá los símbolos para estos archivos DLL al convertir sus datos, pero solo si los símbolos están presentes (y cerca de la biblioteca para la que están destinados).

Hay un comando global denominado dotnet-symbol que se encarga de ello. Para usar dotnet-symbol a fin de obtener símbolos del entorno de ejecución nativo:

  1. Instale dotnet-symbol:

    dotnet tool install -g dotnet-symbol
    
  2. Descargue los símbolos. Si la versión instalada del entorno de ejecución de .NET Core es la 2.1.0, el comando para hacerlo es el siguiente:

    mkdir mySymbols
    dotnet symbol --symbols --output mySymbols  /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.0/lib*.so
    
  3. Copie los símbolos en el lugar correcto.

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

    Si no lo puede hacer porque no tiene acceso de escritura al directorio adecuado, puede usar perf buildid-cache para agregar los símbolos.

Después, debe obtener nombres simbólicos para los archivos DLL nativos al ejecutar perfcollect.

Recopilación en un contenedor de Docker

Para obtener más información sobre cómo usar perfcollect en entornos de contenedor, vea Recopilación de diagnósticos en contenedores.

Más información sobre las opciones de recopilación

Puede especificar las siguientes marcas opcionales con perfcollect para que se adapte mejor a sus necesidades de diagnóstico.

Recopilación con una duración específica

Si quiere recopilar un seguimiento con una duración específica, puede usar la opción -collectsec seguida de un número que especifique el total de segundos durante los que se va a recopilar el seguimiento.

Recopilación de seguimientos de tiempo de subproceso

Si especifica -threadtime con perfcollect, podrá recopilar datos de uso de CPU por subproceso. Esto le permite analizar el lugar en el que está consumiendo su tiempo de CPU cada subproceso.

Recopilación de seguimientos de memoria administrada y rendimiento del recolector de elementos no utilizados

Las siguientes opciones le permiten recopilar específicamente los eventos de GC del entorno de ejecución.

  • perfcollect collect -gccollectonly

Recopile solo un conjunto mínimo de eventos de recopilación de GC. Este es el perfil de recopilación de eventos de GC menos detallado y con el menor impacto en el rendimiento de la aplicación de destino. Este comando es análogo al comando PerfView.exe /GCCollectOnly collect en PerfView.

  • perfcollect collect -gconly

Recopile eventos de recopilación de GC más detallados con eventos JIT, Loader y de excepción. Esto solicita eventos más detallados (como la información de asignación y la información de combinación de GC) y tendrá un impacto mayor en el rendimiento de la aplicación de destino que la opción -gccollectonly. Este comando es análogo al comando PerfView.exe /GCOnly collect en PerfView.

  • perfcollect collect -gcwithheap

Recopile los eventos de recopilación de GC más detallados; esto incluye también un seguimiento de los movimientos y la supervivencia del montón. Esto proporciona un análisis exhaustivo del comportamiento del GC, pero incurrirá en un costo de alto rendimiento, ya que cada GC puede tardar más del doble. Es recomendable que comprenda la implicación del rendimiento del uso de esta opción de seguimiento cuando realice el seguimiento en entornos de producción.