Visualizador de Eventos

No Criador de Perfil de Desempenho, é possível coletar informações de diagnóstico durante a execução do aplicativo e, em seguida, examinar as informações coletadas depois que o aplicativo é interrompido como uma análise post-mortem.

O visualizador de eventos genéricos mostra a atividade do aplicativo por meio de uma lista de eventos, como carga do módulo, início do thread e configuração do sistema. Essa exibição ajuda você a diagnosticar melhor como seu aplicativo está dentro do criador de perfil do Visual Studio.

Instalação

  1. Selecione Alt+F2 para abrir o Criador de Perfil de Desempenho no Visual Studio.

  2. Marque a caixa de seleção Visualizador de Eventos.

    A caixa de seleção Visualizador de Eventos selecionada

  3. Selecione o botão Iniciar para executar a ferramenta.

  4. Após a execução da ferramenta, veja o cenário cujo perfil deseja criar em seu aplicativo. Em seguida, selecione Parar coleta ou feche seu aplicativo para ver seus dados.

    Uma janela mostrando Parar coleta

Para obter mais informações sobre como tornar a ferramenta mais eficiente, confira Otimizar as configurações de Criação de Perfil.

Entender seus dados

Um rastreamento do visualizador de eventos

Nome da coluna Descrição
Nome do Provedor A origem do evento
Nome do evento O evento conforme especificado por seu provedor
Texto Descrições do provedor, do nome do evento e da ID do evento
Carimbo de data/hora (ms) Quando o evento ocorreu
GUID do provedor A ID do provedor de eventos
ID do evento A ID do evento
ID do Processo O processo no qual o evento ocorreu (se houver)
Nome do Processo O nome do processo se estiver em execução ativa
ID do thread A ID do thread do evento que ocorreu (se houver)

Se alguma coluna estiver ausente por padrão, clique com o botão direito do mouse em um dos cabeçalhos de coluna existentes e selecione a coluna que deseja adicionar.

Adicionando colunas ao visualizador de eventos

Quando você seleciona um evento, a janela Propriedades Adicionais é exibida. Propriedades Comuns mostra a lista de propriedades que serão exibidas para qualquer evento. Propriedades de conteúdo mostra propriedades específicas do evento. Para alguns eventos, também é possível exibir Pilhas.

O visualizador de eventos mostrando pilhas

Organizar seus dados

Todas as colunas, exceto a coluna Texto, podem ser classificadas.

O rastreamento do visualizador de eventos

O visualizador de eventos exibe até 20.000 eventos por vez. Para se concentrar nos eventos de interesse, é possível filtrar a exibição de eventos selecionando o filtro de Evento. Também é possível ver a porcentagem do número total de eventos ocorridos para cada provedor, e essas informações oferecem um detalhamento do tempo gasto. Passe o mouse sobre um único filtro de evento para ver uma dica de ferramenta que mostra:

  • Nome do evento
  • Provedor
  • GUID
  • Porcentagem de eventos totais
  • Contagem do evento

O filtro de eventos do visualizador de eventos

O filtro do provedor mostra o percentual do número total de eventos que ocorreram para cada provedor. Passe o mouse sobre um único provedor para ver uma dica de ferramenta semelhante com o nome do provedor, o percentual de eventos totais e a contagem de eventos.

O filtro do provedor do visualizador de eventos

Habilitar eventos ETW personalizados

Você pode instrumentar seu código com eventos ETW personalizados e habilitá-los a aparecer no Visualizador de Eventos. Para habilitar eventos personalizados:

  1. Crie o código de evento personalizado.

    Um exemplo de código de evento personalizado C++ é fornecido no final desta seção.

  2. Abra o Criador de Perfil de Desempenho (Alt + F2), habilite o Visualizador de Eventos e selecione o ícone Configurações (ícone de engrenagem) ao lado dele.

    Captura de tela do ícone de configurações do Visualizador de Eventos.

  3. Na caixa de diálogo, habilite a primeira linha em Provedores Adicionais e execute uma das seguintes ações:

    • Para o código de evento personalizado nativo, defina o GUID do provedor com base no GUID para o código de evento personalizado e deixe o valor do Nome do Provedor vazio ou use seu valor padrão.

    • Para o código de evento personalizado C#, defina o mesmo valor do Nome do Provedor usado ao declarar o código do evento. Esse nome é convertido em um GUID em segundo plano, portanto, deixe o GUID do provedor vazio.

      Para um evento personalizado nativo, a linha deve ser semelhante à ilustração a seguir.

      Captura de tela das configurações do Visualizador de Eventos.

  4. Selecione OK.

    O evento personalizado aparece no Visualizador de Eventos quando você coleta um rastreamento de diagnóstico e o abre. A ilustração a seguir mostra os eventos personalizados no Visualizador de Eventos com filtragem definida para mostrar apenas o evento personalizado.

    Captura de tela do Visualizador de Eventos mostrando eventos personalizados.

Aqui está um exemplo do código de evento personalizado para C++.

#include <Windows.h>
#include <evntprov.h>
#include <iostream>
#include <thread>

// This GUID must be regenerated so it is unique for your provider
// {7369B7AC-64EB-4618-B6B6-C8442B12E8F2}
GUID customEventProvider = { 0x7369b7ac, 0x64eb, 0x4618, { 0xb6, 0xb6, 0xc8, 0x44, 0x2b, 0x12, 0xe8, 0xf2 } };
REGHANDLE _customEventProviderRegHandle = 0;

// Id, Version, Channel, Level, OpCode, Task, Keyword
const EVENT_DESCRIPTOR CustomEventDescriptor = { 1, 0, 0, 0, 0, 0, 1 };

int main()
{
    // Register the provider
    ULONG res = ::EventRegister(&customEventProvider, nullptr, nullptr, &_customEventProviderRegHandle);
    if (res != ERROR_SUCCESS)
    {
        return res;
    }

    byte data[] = { 0xFF, 0xFF, 0xFF, 0xFF };
    EVENT_DATA_DESCRIPTOR eventData[1];
    ::EventDataDescCreate(&(eventData[0]), &data, sizeof(data));

    for (int i = 0; i < 10; ++i)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        ::EventWrite(_customEventProviderRegHandle, &CustomEventDescriptor, _countof(eventData), eventData);
        std::cout << "Wrote event\n";
    }

    res = ::EventUnregister(_customEventProviderRegHandle);
    if (res != ERROR_SUCCESS)
    {
        return res;
    }

    return 0;
}