EventPipe
EventPipe é um componente de runtime que pode ser usado para coletar dados de rastreamento, semelhantes a ETW ou LTTng. O objetivo do EventPipe é permitir que os desenvolvedores do .NET rastreiem facilmente seus aplicativos .NET sem precisar contar com componentes nativos do sistema operacional específicos da plataforma, como ETW ou LTTng.
O EventPipe é o mecanismo por trás de muitas das ferramentas de diagnóstico e pode ser usado para consumir eventos emitidos pelo runtime, bem como eventos personalizados gravados com EventSource.
Este artigo é uma visão geral de alto nível do EventPipe. Ele descreve quando e como usar o EventPipe e como configurá-lo para atender da melhor forma às suas necessidades.
Noções básicas do EventPipe
O EventPipe agrega eventos emitidos por componentes de runtime - por exemplo, o compilador Just-In-Time ou o coletor de lixo, e eventos gravados a partir de instâncias EventSource nas bibliotecas e no código do usuário.
Em seguida, os eventos são serializados no formato de arquivo .nettrace
e podem ser gravados diretamente em um arquivo ou transmitidos por meio de uma porta de diagnóstico para consumo fora do processo.
Para saber mais sobre o formato de serialização do EventPipe, consulte a documentação do formato EventPipe.
EventPipe vs. ETW/LTTng
O EventPipe faz parte do CoreCLR (runtime do .NET) e foi projetado para funcionar da mesma maneira em todas as plataformas compatíveis com o .NET Core. Isso permite que as ferramentas de rastreamento baseadas em EventPipe, como dotnet-counters
, dotnet-gcdump
e dotnet-trace
, funcionem perfeitamente entre plataformas.
No entanto, como o EventPipe é um componente interno de runtime, seu escopo é limitado ao código gerenciado e ao próprio runtime. O EventPipe não pode ser usado para acompanhar alguns eventos de nível inferior, como resolver a pilha de código nativa ou obter vários eventos de kernel. Se você usar a interoperabilidade C/C++ em seu aplicativo ou quiser rastrear o runtime em si (que é gravado em C++) ou deseja um diagnóstico mais profundo no comportamento do aplicativo que requer eventos de kernel (ou seja, eventos de alternância de contexto de thread nativo), você deve usar ETW ou perf/LTTng.
Outra grande diferença entre EventPipe e ETW/LTTng é o requisito de privilégio de administrador/raiz. Para rastrear um aplicativo usando ETW ou LTTng, você precisa ser um administrador/raiz. Usando o EventPipe, você pode rastrear aplicativos desde que o rastreador (por exemplo, dotnet-trace
) seja executado como o mesmo usuário que o usuário que iniciou o aplicativo.
A tabela a seguir é um resumo das diferenças entre EventPipe e ETW/LTTng.
Recurso | EventPipe | ETW | LTTng |
---|---|---|---|
Plataforma cruzada | Sim | Não (somente no Windows) | Não (somente em distribuições do Linux com suporte) |
Exigir privilégio de administrador/raiz | No | Sim | Sim |
Pode obter eventos de SO/kernel | No | Sim | Yes |
Pode resolver pilhas de chamadas nativas | No | Sim | Sim |
Usar o EventPipe para rastrear seu aplicativo .NET
Você pode usar o EventPipe para rastrear seu aplicativo .NET de várias maneiras:
Use uma das ferramentas de diagnóstico criadas sobre o EventPipe.
Use a biblioteca Microsoft.Diagnostics.NETCore.Client para escrever sua própria ferramenta para configurar e iniciar sessões do EventPipe.
Use variáveis de ambiente para iniciar o EventPipe.
Depois de produzir um arquivo nettrace
que contém seus eventos eventPipe, você pode exibir o arquivo no PerfView ou no Visual Studio. Em plataformas que não sejam Windows, você pode converter o arquivo nettrace
em um formato de rastrteamento speedscope
ou Chromium
usando o comando dotnet-trace convert e exibi-lo com speedscope ou Chrome DevTools.
Você também pode analisar rastreamentos do EventPipe programaticamente com o TraceEvent.
Ferramentas que usam o EventPipe
Essa é a maneira mais fácil de usar o EventPipe para rastrear seu aplicativo. Para saber mais sobre como usar cada uma dessas ferramentas, consulte a documentação de cada ferramenta.
Os dotnet-counters permitem monitorar e coletar várias métricas emitidas pelo runtime do .NET e bibliotecas principais, bem como métricas personalizadas que você pode gravar.
O dotnet-gcdump permite coletar despejos de heap de GC de processos dinâmicos para analisar o heap gerenciado de um aplicativo.
O dotnet-trace permite coletar rastreamentos de aplicativos para analisar o desempenho.
Rastreamento usando variáveis de ambiente
O mecanismo preferencial para usar o EventPipe é usar o dotnet-trace ou a biblioteca Microsoft.Diagnostics.NETCore.Client .
No entanto, você pode usar as variáveis de ambiente a seguir para configurar uma sessão EventoPipe em um aplicativo e fazer com que ele escreva o rastreamento diretamente em um arquivo. Para interromper o rastreamento, saia do aplicativo.
DOTNET_EnableEventPipe
: defina para1
para iniciar uma sessão EventPipe que grava diretamente em um arquivo. O valor padrão é0
.DOTNET_EventPipeOutputPath
: o caminho para o arquivo de rastreamento do EventPipe de saída quando ele está configurado para ser executado por meio deDOTNET_EnableEventPipe
. O valor padrão étrace.nettrace
, que será criado no mesmo diretório do qual o aplicativo está sendo executado.Observação
Desde o .NET 6, as instâncias da cadeia de caracteres
{pid}
emDOTNET_EventPipeOutputPath
são substituídas pela ID de processo do processo que está sendo rastreado.DOTNET_EventPipeCircularMB
: um valor hexadecimal que representa o tamanho do buffer interno do EventPipe em megabytes. Esse valor de configuração só é usado quando o EventPipe é configurado para ser executado por meio eDOTNET_EnableEventPipe
. O tamanho padrão do buffer é 1024 MB, que se traduz para essa variável de ambiente que está sendo definida como400
, desde0x400
==1024
.Observação
Se o processo de destino gravar eventos com muita frequência, ele poderá estourar esse buffer e alguns eventos poderão ser descartados. Se muitos eventos estiverem sendo descartados, aumente o tamanho do buffer para ver se o número de eventos descartados reduz. Se o número de eventos descartados não diminuir com um tamanho maior de buffer, pode ser devido a um leitor lento que impede que os buffers do processo de destino sejam liberados.
DOTNET_EventPipeProcNumbers
: defina para1
para habilitar a captura de números de processador em cabeçalhos de evento do EventPipe. O valor padrão é0
.DOTNET_EventPipeConfig
: define a configuração da sessão do EventPipe ao iniciar uma sessão do EventPipe comDOTNET_EnableEventPipe
. A sintaxe dela é a seguinte:<provider>:<keyword>:<level>
Você também pode especificar vários provedores concatenando-os com uma vírgula:
<provider1>:<keyword1>:<level1>,<provider2>:<keyword2>:<level2>
Se essa variável de ambiente não estiver definida, mas o EventPipe estiver habilitado por
DOTNET_EnableEventPipe
, ele começará a rastrear habilitando os seguintes provedores com as seguintes palavras-chave e níveis:Microsoft-Windows-DotNETRuntime:4c14fccbd:5
Microsoft-Windows-DotNETRuntimePrivate:4002000b:5
Microsoft-DotNETCore-SampleProfiler:0:5
Para saber mais sobre alguns dos provedores conhecidos no .NET, consulte Provedores de eventos conhecidos.
Observação
O .NET 6 usa o prefixo DOTNET_
como padrão em vez de COMPlus_
para variáveis de ambiente que configuram o comportamento de tempo de execução do .NET. No entanto, o prefixo COMPlus_
continuará funcionando. Se você estiver usando uma versão anterior do runtime do .NET, ainda terá que usar o prefixo COMPlus_
para variáveis de ambiente.