Visor de eventos

En el Generador de perfiles de rendimiento, puede recopilar información de diagnóstico mientras se ejecuta la aplicación y, después, examinar la información recopilada cuando la aplicación se haya detenido, como un análisis final.

El visor de eventos genérico muestra la actividad de la aplicación a través de una lista de eventos, como la carga del módulo, el inicio del subproceso y la configuración del sistema. Esta vista ayuda a diagnosticar mejor el funcionamiento de la aplicación dentro del generador de perfiles de Visual Studio.

Programa de instalación

  1. Seleccione Alt + F2 para abrir el Generador de perfiles de rendimiento en Visual Studio.

  2. Active la casilla Visor de eventos.

    The Events Viewer check box selected

  3. Seleccione el botón Iniciar para ejecutar la herramienta.

  4. Una vez que se inicie la ejecución de la herramienta, repase el escenario del que se van a generar perfiles en su aplicación. A continuación, seleccione Detener recopilación o cierre la aplicación para ver los datos.

    A window showing Stop collection

Para más información sobre cómo aumentar la eficacia de la herramienta, consulte el artículo Optimización de la configuración del generador de perfiles.

Comprensión de los datos

An event viewer trace

Nombre de la columna Descripción
Nombre del proveedor El origen del evento
Nombre de evento El evento tal y como lo especifica su proveedor
Text Descripciones del proveedor, el nombre del evento y el id. del evento
Marca de tiempo (ms) Cuándo se realizó el evento
Guid del proveedor El id. del proveedor de eventos
Id. de evento El id. del evento
Identificador del proceso El proceso a partir del cual se produjo el evento (si se conoce)
Nombre del proceso El nombre del proceso si se está ejecutando activamente
Id. de subproceso El identificador del subproceso a partir del cual se produjo el evento (si se conoce)

Si se omite alguna columna de forma predeterminada, haga clic con el botón derecho en uno de los encabezados de columna existentes y seleccione la columna que quiere agregar.

Adding columns to the event viewer

Al seleccionar un evento, aparece la ventana Propiedades adicionales. Propiedades comunes muestra la lista de propiedades que se mostrarán para cualquier evento. Propiedades de carga muestra propiedades específicas del evento. En el caso de algunos eventos, también puede ver las Pilas.

The event viewer showing stacks

Organización de los datos

Se pueden ordenar todas las columnas, excepto la columna Texto.

The event viewer trace

El visor de eventos muestra hasta 20 000 eventos a la vez. Para centrarse en los eventos de interés, puede seleccionar el Filtro de evento para filtrar la presentación de los eventos. También puede ver el porcentaje del número total de eventos que se han producido para cada proveedor, esta información le proporciona un desglose de dónde se invierte el tiempo. Mantenga el mouse sobre un solo filtro de evento para ver información rápida que muestra:

  • Nombre del evento.
  • Proveedor
  • GUID
  • Porcentaje de eventos totales
  • Recuento de eventos

The event viewer event filter

El filtro del proveedor muestra el porcentaje del número total de eventos que se han producido para cada proveedor. Mantenga el mouse sobre un solo proveedor para ver una información rápida similar con el nombre del proveedor, el porcentaje de eventos totales y el recuento de eventos.

The event viewer provider filter

Habilitar eventos ETW personalizados

Puede instrumentar su código con eventos ETW personalizados y habilitarlos para que aparezcan en el Visor de Eventos. Para habilitar los eventos personalizados:

  1. Cree el código del evento personalizado.

    Al final de esta sección se ofrece un ejemplo de código de evento personalizado en C++.

  2. Abra el Generador de perfiles de rendimiento (Alt + F2), habilite el Visor de Eventos, y luego, seleccione el icono de Configuración (icono de engranaje) situado junto a él.

    Screenshot of the events viewer settings icon.

  3. En el cuadro de diálogo, habilite la primera fila en Proveedores adicionales, y luego, realice una de las siguientes acciones:

    • Para el código de evento personalizado nativo, establezca el GUID del Proveedor basado en el GUID para el código de evento personalizado, y deje el valor de Nombre del Proveedor vacío o utilice su valor por defecto.

    • Para el código de evento personalizado de C#, establezca el mismo valor de Nombre del Proveedor que utilizó al declarar su código de evento. Este nombre se convierte en un GUID en segundo plano, así que deje vacío el GUID del Proveedor.

      Para un evento personalizado nativo, la fila debería tener un aspecto similar al de la siguiente ilustración.

      Screenshot of the events viewer settings.

  4. Seleccione Aceptar.

    El evento personalizado aparece en el Visor de Eventos cuando se recopila una traza de diagnóstico y se abre. La siguiente ilustración muestra los eventos personalizados en el Visor de Eventos con el filtrado configurado para mostrar solo el evento personalizado.

    Screenshot of the events viewer showing custom events.

He aquí un ejemplo de 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;
}