Compartilhar via


Rastrear aplicativos .NET com PerfCollect

Este artigo se aplica a: ✔️ SDK do .NET Core 2.1 e versões posteriores

Quando problemas de performance são encontrados no Linux, é possível coletar um rastreamento com perfcollect para obter informações detalhadas sobre o que estava acontecendo na máquina no momento do problema de performance.

perfcollect é um script bash que usa o Linux Trace Toolkit: LTTng (próxima geração) para coletar eventos gravados do runtime ou qualquer EventSource, bem como perf para coletar amostras de CPU do processo de destino.

Preparar seu computador

Siga estes passos para preparar seu computador para coletar um registro de desempenho com perfcollect.

Observação

Se você estiver capturando de dentro de um contêiner, seu contêiner deverá ter os recursos apropriados. Os recursos mínimos necessários são PERFMON e SYS_PTRACE. Se a captura falhar com o conjunto mínimo, adicione o recurso SYS_ADMIN ao contêiner. Para obter mais informações sobre como rastrear aplicativos dentro de contêineres usando PerfCollect, consulte Coletar diagnósticos em contêineres.

  1. Baixe o perfcollect.

    curl -OL https://aka.ms/perfcollect
    
  2. Torne o script executável.

    chmod +x perfcollect
    
  3. Instale os pré-requisitos de rastreamento – essas são as bibliotecas de rastreamento reais.

    sudo ./perfcollect install
    

    Isso instalará os seguintes pré-requisitos em seu computador:

    1. perf: o subsistema de Eventos de Desempenho do Linux e o aplicativo complementar de coleta/visualização no modo de usuário. perf faz parte da origem do kernel do Linux, mas geralmente não é instalado por padrão.
    2. LTTng: usado para capturar dados de evento emitidos em tempo de execução pelo CoreCLR. Esses dados são usados para analisar o comportamento de vários componentes de runtime, como o GC, o JIT e o pool de threads.

Versões recentes do .NET Core e da ferramenta de perf do Linux dão suporte à resolução automática de nomes de método para código de estrutura.

Para resolver nomes de método de DLLs nativas de runtime (como libcoreclr.so), perfcollect resolverá símbolos para eles quando converter os dados, mas somente se os símbolos desses binários estiverem presentes. Consulte Como obter símbolos para a seção Tempo de Execução Nativo para obter detalhes.

Coletar um rastreamento

  1. Tenha dois shells disponíveis : um para controlar o rastreamento, conhecido como [Rastreamento], e outro para executar o aplicativo, conhecido como [Aplicativo].

  2. [Rastreamento] Iniciar coleta.

    sudo ./perfcollect collect sampleTrace
    

    Saída esperada:

    Collection started.  Press CTRL+C to stop.
    

    Observação

    LTTng teve uma alteração significativa entre as versões 2.12 e 2.13. O runtime do .NET atualmente dá suporte à versão 2.12. Se a distribuição Linux tiver adotado a versão 2.13 ou posterior, recomendamos desabilitar o componente LTTng da funcionalidade de perfcollect. Para fazer isso, adicione a opção '-nolttng' à linha de comando perfcollect e, na etapa 3, não defina a variável de ambiente DOTNET_EnableEventLog.

  3. [Aplicativo] Configure o shell do aplicativo com as seguintes variáveis de ambiente– isso permite a configuração de rastreamento do CoreCLR.

  4. [Aplicativo] Configure o shell do aplicativo com as seguintes variáveis de ambiente– isso permite a configuração de rastreamento do CoreCLR.

    export DOTNET_PerfMapEnabled=1
    export DOTNET_EnableEventLog=1
    

    Observação

    Ao executar o aplicativo com o .NET 7, você também deve definir DOTNET_EnableWriteXorExecute=0 além das variáveis de ambiente anteriores. Por exemplo:

    export DOTNET_EnableWriteXorExecute=0
    

    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, continue usando o prefixo COMPlus_ para variáveis de ambiente.

  5. [Aplicativo] Execute o aplicativo – permita que ele seja executado o tempo necessário para capturar o problema de desempenho. O comprimento exato pode ser tão curto quanto você precisar, desde que ele capture suficientemente a janela de tempo em que o problema de desempenho que você deseja investigar ocorre.

    dotnet run
    
  6. [Rastreamento] Parar coleta – pressione 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
    

    O arquivo de rastreamento compactado agora está armazenado no diretório de trabalho atual.

Exibir um rastreamento

Há várias opções para exibir o rastreamento que foi coletado. Os rastreamentos são melhor exibidos usando o PerfView no Windows, mas podem ser exibidos diretamente no Linux usando-se PerfCollect ou TraceCompass.

Usar PerfCollect para exibir o arquivo de rastreamento

Você pode usar o próprio perfcollect para exibir o rastreamento coletado. Para fazer isso, use o seguinte comando:

./perfcollect view sampleTrace.trace.zip

Por padrão, isso mostrará o rastreamento de CPU do aplicativo usando perf.

Para examinar os eventos que foram coletados por meio de LTTng, você pode passar o sinalizador -viewer lttng para ver os eventos individuais:

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

Isso usará o visualizador babeltrace para imprimir o conteúdo dos 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 }

Usar o PerfView para abrir o arquivo de rastreamento

Para ver uma exibição agregada do exemplo de CPU e dos eventos, você pode usar PerfView em um computador Windows.

  1. Copie o arquivo trace.zip do Linux para um computador Windows.

  2. Baixe o PerfView de https://aka.ms/perfview.

  3. Executar o PerfView.exe

    PerfView.exe <path to trace.zip file>
    

O PerfView exibirá a lista de exibições com suporte com base nos dados contidos no arquivo de rastreamento.

  • Para investigações de CPU, escolha pilhas de CPU.
  • Para obter informações detalhadas do GC, escolha GCStats.
  • Para obter informações de JIT por processo/módulo/método, escolha JITStats.
  • Se não houver uma exibição para as informações necessárias, você poderá tentar procurar os eventos no modo de exibição de eventos brutos. Escolha Eventos.

Para obter mais informações sobre como interpretar exibições no PerfView, consulte links de ajuda no próprio modo de exibição ou, na janela principal do PerfView, escolha o Guia de Ajuda dos> Usuários.

Observação

Os eventos gravados por meio da API System.Diagnostics.Tracing.EventSource (incluindo os eventos do Framework) não aparecerão no nome do provedor. Em vez disso, eles são gravados como EventSourceEvent eventos no provedor Microsoft-Windows-DotNETRuntime e seus conteúdos são serializados por JSON.

Observação

Se você observar quadros de [unknown] /memfd:doublemapper em nomes de métodos e pilhas de chamadas, defina DOTNET_EnableWriteXorExecute=0 antes de executar o aplicativo que está rastreando com perfcollect.

Usar TraceCompass para abrir o arquivo de rastreamento

Eclipse TraceCompass é outra opção que você pode usar para exibir os rastreamentos. TraceCompass funciona em computadores Linux também, portanto, você não precisa mover seu rastreamento para um computador Windows. Para usar TraceCompass para abrir o arquivo de rastreamento, você precisará descompactar o arquivo.

unzip myTrace.trace.zip

perfcollect salvará o rastreamento LTTng coletado em um formato de arquivo CTF em um subdiretório em lttngTrace. Especificamente, o arquivo CTF estará localizado em um diretório semelhante a lttngTrace/auto-20201025-101230\ust\uid\1000\64-bit\.

Você pode abrir o arquivo TraceCompass de rastreamento CTF selecionando e selecionando File -> Open Trace e o arquivo metadata.

Para obter mais detalhes, consulte a TraceCompass documentação.

Obter símbolos para o runtime nativo

Na maioria das vezes, você está interessado em seu próprio código, que perfcollect resolve por padrão. Às vezes, é útil ver o que está acontecendo dentro das DLLs do .NET (que é sobre a última seção), mas às vezes o que está acontecendo nas dlls de runtime nativo (normalmente libcoreclr.so), é interessante. perfcollect resolverá os símbolos para esses quando ele converter seus dados, mas somente se os símbolos para essas DLLs nativas estiverem presentes (e estiverem ao lado da biblioteca de destino).

Há um comando global chamado dotnet-symbol que faz isso. Para usar o dotnet-symbol para obter símbolos nativos de tempo de execução:

  1. Instale dotnet-symbol:

    dotnet tool install -g dotnet-symbol
    
  2. Baixe os símbolos. Se a versão instalada do runtime do .NET Core for 2.1.0, o comando para fazer isso será:

    mkdir mySymbols
    dotnet symbol --symbols --output mySymbols  /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.0/lib*.so
    
  3. Copie os símbolos para o local correto.

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

    Se isso não puder ser feito porque você não tem acesso de gravação ao diretório apropriado, você pode usar perf buildid-cache para adicionar os símbolos.

Depois disso, você deverá obter nomes simbólicos para as dlls nativas quando executar perfcollect.

Coletar dados em um contêiner Docker

Para obter mais informações sobre como usar perfcollect em ambientes de contêiner, consulte Coletar diagnósticos em contêineres.

Saiba mais sobre as opções de coleção

Você pode especificar os sinalizadores perfcollect opcionais a seguir para atender melhor às suas necessidades de diagnóstico.

Coletar por uma duração específica

Quando você deseja coletar um rastreamento por uma duração específica, você pode usar a opção -collectsec seguida por um número que especifica o total de segundos para o qual coletar um rastreamento.

Coletar rastreamentos de threadtime

Especificar -threadtime com perfcollect permite coletar dados de uso da CPU por thread. Isso permite que você analise onde cada thread estava gastando seu tempo de CPU.

Coletar rastreamentos para desempenho gerenciado de memória e coletor de lixo

As opções a seguir permitem coletar especificamente os eventos do GC do runtime.

  • perfcollect collect -gccollectonly

Colete apenas um conjunto mínimo de eventos da Coleção GC. Esse é o perfil de coleta de eventos GC menos verboso com o menor impacto no desempenho do aplicativo alvo. Esse comando é análogo ao PerfView.exe /GCCollectOnly collect comando no PerfView.

  • perfcollect collect -gconly

Colete eventos de coleção GC mais detalhados com eventos JIT, Loader e Exception. Isso solicita eventos mais detalhados (como as informações de alocação e informações de junção do GC) e terá mais impacto no desempenho do aplicativo de destino do que na opção -gccollectonly. Esse comando é análogo ao PerfView.exe /GCOnly collect comando no PerfView.

  • perfcollect collect -gcwithheap

Colete os eventos de coleção GC mais detalhados, que também acompanham a sobrevivência e os movimentos do heap. Isso fornece uma análise detalhada do comportamento do GC, mas incorrerá em alto custo de desempenho, pois cada GC pode levar mais de duas vezes mais tempo. É recomendável que você entenda a implicação de desempenho do uso dessa opção de rastreamento ao rastrear em ambientes de produção.