EventPipe
EventPipe es un componente en tiempo de ejecución similar a ETW o perf_events que se puede usar para recopilar datos de seguimiento. El objetivo de EventPipe es permitir a los desarrolladores de .NET realizar un seguimiento sencillo de sus aplicaciones .NET sin tener que depender de componentes con privilegios elevados específicos de la plataforma como ETW o perf_events.
EventPipe es el mecanismo subyacente de muchas de las herramientas de diagnóstico y se puede usar para consumir eventos emitidos por el entorno de ejecución, así como eventos personalizados escritos con EventSource.
Este artículo es una introducción de alto nivel a EventPipe. Describe cuándo y cómo usar EventPipe y cómo configurarlo para que se adapte mejor a sus necesidades.
Aspectos básicos de EventPipe
EventPipe agrega eventos emitidos por componentes en tiempo de ejecución (por ejemplo, el compilador Just-in-Time o el recolector de elementos no utilizados) y eventos escritos desde instancias de EventSource en las bibliotecas y el código de usuario.
A continuación, los eventos se serializan en el formato de archivo .nettrace
y se pueden escribir directamente en un archivo o transmitirse a través de un puerto de diagnóstico para el consumo fuera del proceso.
Para obtener más información sobre el formato de serialización de EventPipe, vea la documentación de formato de EventPipe.
EventPipe frente a ETW/perf_events
EventPipe forma parte del entorno de ejecución .NET y está diseñado para funcionar de la misma manera en todas las plataformas compatibles con .NET Core. Esto permite que herramientas de seguimiento basadas en EventPipe, como dotnet-counters
, dotnet-gcdump
y dotnet-trace
, funcionen sin problemas entre plataformas.
Pero, dado que EventPipe es un componente integrado en tiempo de ejecución, su ámbito se limita al código administrado y al propio entorno de ejecución. Los eventos de EventPipe incluyen seguimientos de pila solo con información de marcos de código administrado. Si desea que los eventos generados a partir de otras bibliotecas en modo de usuario no administrado, el muestreo de CPU para código nativo o eventos de kernel, debe usar herramientas de seguimiento específicas del sistema operativo, como ETW o perf_events. En Linux, la herramienta perfcollect ayuda a automatizar el uso de perf_events y LTTng.
Otra diferencia importante entre EventPipe y ETW/perf_events es el requisito de privilegios de administrador o raíz. Para realizar el seguimiento de una aplicación mediante ETW o perf_events, debe ser administrador o raíz. Con EventPipe puede realizar un seguimiento de las aplicaciones siempre que el seguimiento (por ejemplo, dotnet-trace
) se ejecute como el mismo usuario que el que ha iniciado la aplicación.
En la tabla siguiente se presenta un resumen de las diferencias entre EventPipe y ETW/perf_events
Característica | EventPipe | ETW | perf_events |
---|---|---|---|
Multiplataforma | Sí | No (solo en Windows) | No (solo en distribuciones Linux compatibles) |
Requiere privilegios de administrador o raíz | No | Sí | Sí |
Puede obtener eventos de SO o kernel | No | Sí | Sí |
Puede resolver pilas de llamadas nativas | No | Sí | Sí |
Uso de EventPipe para el seguimiento de la aplicación .NET
Puede usar EventPipe para realizar un seguimiento de la aplicación .NET de muchas maneras:
Use alguna de las herramientas de diagnóstico que se basan en EventPipe.
Use la biblioteca Microsoft.Diagnostics.NETCore.Client para escribir su propia herramienta a fin de configurar e iniciar las sesiones de EventPipe.
Use variables de entorno para iniciar EventPipe.
Después de haber creado un archivo nettrace
que contiene los eventos EventPipe, puede verlo en PerfView o en Visual Studio. En las plataformas que no son de Windows, puede convertir el archivo nettrace
a un formato de seguimiento de speedscope
o Chromium
mediante el comando dotnet-trace convert y verlo con speedscope o Chrome DevTools.
También puede analizar los seguimientos de EventPipe mediante programación con TraceEvent.
Herramientas que usan EventPipe
Esta es la forma más sencilla de usar EventPipe para realizar un seguimiento de la aplicación. Para obtener más información sobre cómo usar cada una de estas herramientas, vea la documentación de cada una de ellas.
dotnet-counters permite supervisar y recopilar diversas métricas emitidas por el entorno de ejecución .NET y las bibliotecas principales, así como métricas personalizadas que se pueden escribir.
dotnet-gcdump permite recopilar volcados de memoria del montón de GC de procesos en vivo para analizar el montón administrado de una aplicación.
dotnet-trace permite recopilar seguimientos de aplicaciones para analizar el rendimiento.
Seguimiento mediante variables de entorno
El mecanismo preferido para usar EventPipe es emplear dotnet-trace o la biblioteca Microsoft.Diagnostics.NETCore.Client.
pero puede usar las siguientes variables de entorno para configurar una sesión de EventPipe en una aplicación y hacer que escriba el seguimiento directamente en un archivo. Para detener el seguimiento, salga de la aplicación.
DOTNET_EnableEventPipe
: establezca en1
para iniciar una sesión de EventPipe que escriba directamente en un archivo. El valor predeterminado es0
.DOTNET_EventPipeOutputPath
: ruta de acceso al archivo de seguimiento de EventPipe de salida cuando está configurado para ejecutarse medianteDOTNET_EnableEventPipe
. El valor predeterminado estrace.nettrace
, que se crea en el mismo directorio desde el que se ejecuta la aplicación.Nota:
A partir de .NET 6, las instancias de la cadena
{pid}
enDOTNET_EventPipeOutputPath
se reemplazan por el identificador del proceso del que se realiza el seguimiento.DOTNET_EventPipeCircularMB
: valor hexadecimal que representa el tamaño del búfer interno de EventPipe en megabytes. Este valor de configuración solo se usa cuando EventPipe está configurado para ejecutarse medianteDOTNET_EnableEventPipe
. El tamaño de búfer predeterminado es de 1024 MB, que se traduce en esta variable de entorno estableciéndose en400
, puesto que0x400
==1024
.Nota:
Si el proceso de destino escribe eventos con demasiada frecuencia, puede desbordar este búfer y se pueden eliminar algunos eventos. Si se quitan demasiados eventos, aumente el tamaño del búfer para ver si se reduce el número de eventos eliminados. Si el número de eventos eliminados no disminuye con un tamaño de búfer mayor, puede deberse a que un lector lento está evitando que se vacíen los búferes del proceso de destino.
DOTNET_EventPipeProcNumbers
: establézcalo en1
para habilitar la captura de números de procesador en los encabezados de evento de EventPipe. El valor predeterminado es0
.DOTNET_EventPipeConfig
: establece la configuración de sesión de EventPipe al iniciar una sesión de EventPipe conDOTNET_EnableEventPipe
. La sintaxis es la siguiente:<provider>:<keyword>:<level>
También puede especificar varios proveedores si los concatena con una coma:
<provider1>:<keyword1>:<level1>,<provider2>:<keyword2>:<level2>
Si no se establece esta variable de entorno sino que EventPipe se habilita por medio de
DOTNET_EnableEventPipe
, comienza el seguimiento mediante la habilitación de los siguientes proveedores con las siguientes palabras clave y niveles:Microsoft-Windows-DotNETRuntime:4c14fccbd:5
Microsoft-Windows-DotNETRuntimePrivate:4002000b:5
Microsoft-DotNETCore-SampleProfiler:0:5
Para obtener más información acerca de algunos de los proveedores conocidos en .NET, consulte Proveedores de eventos conocidos en .NET.
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.