Función EnableTraceEx2 (evntrace.h)

Un controlador de sesión de seguimiento llama a EnableTraceEx2 para configurar cómo un proveedor de eventos ETW registra los eventos en una sesión de seguimiento.

Esta función sustituye a las funciones EnableTrace y EnableTraceEx .

Sintaxis

ULONG WMIAPI EnableTraceEx2(
  [in]           TRACEHANDLE              TraceHandle,
  [in]           LPCGUID                  ProviderId,
  [in]           ULONG                    ControlCode,
  [in]           UCHAR                    Level,
  [in]           ULONGLONG                MatchAnyKeyword,
  [in]           ULONGLONG                MatchAllKeyword,
  [in]           ULONG                    Timeout,
  [in, optional] PENABLE_TRACE_PARAMETERS EnableParameters
);

Parámetros

[in] TraceHandle

Identificador de la sesión de seguimiento de eventos para la que está configurando el proveedor. La función StartTrace devuelve este identificador cuando se inicia un nuevo seguimiento. Para obtener el identificador de un seguimiento existente, use ControlTrace para consultar las propiedades de seguimiento en función del nombre del seguimiento y, a continuación, obtener el identificador del campo Wnode.HistoricalContext de los datos devueltos EVENT_TRACE_PROPERTIES .

[in] ProviderId

Identificador de proveedor (GUID de control) del proveedor de eventos que desea configurar.

[in] ControlCode

Puede especificar uno de los siguientes códigos de control:

Valor Significado
EVENT_CONTROL_CODE_DISABLE_PROVIDER Actualice la configuración de sesión para que la sesión no reciba eventos del proveedor.
EVENT_CONTROL_CODE_ENABLE_PROVIDER Actualice la configuración de sesión para que la sesión reciba los eventos solicitados del proveedor.
EVENT_CONTROL_CODE_CAPTURE_STATE Solicita que el proveedor registre su información de estado.

[in] Level

Valor que indica el nivel máximo de eventos que desea que escriba el proveedor. Normalmente, el proveedor escribe un evento si el nivel del evento es menor o igual que este valor, además de cumplir los criterios MatchAnyKeyword y MatchAllKeyword .

Microsoft define la semántica de los niveles 1 a 5, como se muestra a continuación. Los valores inferiores indican eventos más graves. Cada valor de Level habilita el nivel especificado y todos los niveles más graves. Por ejemplo, si especifica TRACE_LEVEL_WARNING, el consumidor recibirá eventos de advertencia, error y crítico.

Valor Significado
TRACE_LEVEL_CRITICAL (1) Eventos de salida o finalización anómalos
TRACE_LEVEL_ERROR (2) Eventos de error graves
TRACE_LEVEL_WARNING (3) Eventos de advertencia, como errores de asignación
TRACE_LEVEL_INFORMATION (4) Eventos informativos que no son de error
TRACE_LEVEL_VERBOSE (5) Eventos de diagnóstico detallados

Las TRACE_LEVEL constantes se definen en evntrace.h. Las constantes equivalentes WINMETA_LEVEL se definen en winmeta.h.

[in] MatchAnyKeyword

Máscara de bits de 64 bits de palabras clave que determinan las categorías de eventos que desea que escriba el proveedor. Normalmente, el proveedor escribe un evento si los bits de palabra clave del evento coinciden con cualquiera de los bits establecidos en este valor o si el evento no tiene ningún bits de palabra clave establecido, además de cumplir los criterios Level y MatchAllKeyword .

[in] MatchAllKeyword

Máscara de bits de 64 bits de palabras clave que restringe los eventos que desea que escriba el proveedor. Normalmente, el proveedor escribe un evento si los bits de palabra clave del evento coinciden con todos los bits establecidos en este valor o si el evento no tiene ningún bits de palabra clave establecido, además de cumplir los criterios Level y MatchAnyKeyword .

Este valor se establece con frecuencia en 0.

[in] Timeout

Si Timeout es 0, esta función comenzará a configurar el proveedor de forma asincrónica y devolverá inmediatamente (es decir, se devolverá sin esperar a que se completen las devoluciones de llamada del proveedor).

De lo contrario, esta función comenzará a configurar el proveedor y, a continuación, comenzará a esperar a que se complete la configuración, incluida la espera de que se completen todas las devoluciones de llamada del proveedor. Si la configuración se completa antes del tiempo de espera especificado, esta función devolverá ERROR_SUCCESS. De lo contrario, esta función devolverá ERROR_TIMEOUT.

Para esperar para siempre, establezca en INFINITE.

[in, optional] EnableParameters

Parámetros de seguimiento usados para habilitar el proveedor. Para más información, consulte ENABLE_TRACE_PARAMETERS.

Valor devuelto

Si la función se realiza correctamente, el valor devuelto se ERROR_SUCCESS.

Si se produce un error en la función, el valor devuelto es uno de los códigos de error del sistema. A continuación se muestran algunos errores comunes y sus causas.

  • ERROR_INVALID_PARAMETER

    Un parámetro es incorrecto.

    Esto puede ocurrir si se cumple alguna de las siguientes condiciones:

    • ProviderId es NULL.
    • TraceHandle es 0.
  • ERROR_TIMEOUT

    El valor de tiempo de espera expiró antes de que se complete la devolución de llamada de habilitación. Para obtener más información, consulte el parámetro Timeout .

  • ERROR_INVALID_FUNCTION

    No se puede actualizar el nivel cuando el proveedor no está registrado.

  • ERROR_NO_SYSTEM_RESOURCES

    Se superó el número de sesiones de seguimiento que pueden habilitar el proveedor.

  • ERROR_ACCESS_DENIED

    Solo los usuarios con privilegios administrativos, los usuarios del Performance Log Users grupo y los servicios que se ejecutan como LocalSystem, LocalServiceo NetworkService pueden habilitar proveedores de eventos en una sesión entre procesos. Para conceder a un usuario restringido la capacidad de habilitar un proveedor de eventos, agréguelos al Performance Log Users grupo o vea EventAccessControl.

    Windows XP y Windows 2000: Cualquier persona puede habilitar un proveedor de eventos.

Comentarios

Los controladores de seguimiento de eventos llaman a esta función para configurar los proveedores de eventos que escriben eventos en la sesión. Por ejemplo, un controlador podría llamar a esta función para comenzar a recopilar eventos de un proveedor, para ajustar el nivel o las palabras clave de los eventos que se recopilan de un proveedor, o para detener la recopilación de eventos de un proveedor.

El comportamiento de habilitación de un proveedor depende de las API que usa el proveedor.

  • Un proveedor que usa RegisterTraceGuids (por ejemplo, un proveedor que usa WPP o MOF basado en TMF) usa el sistema de habilitación heredado (a veces denominado "ETW clásico"). Cuando un proveedor heredado está habilitado o reconfigurado para una sesión, el tiempo de ejecución de ETW notifica al proveedor y proporciona acceso al nivel, los 32 bits bajos de la máscara MatchAnyKeyword y el identificador de sesión. A continuación, el proveedor usa su propia lógica para decidir qué eventos se deben habilitar y enviar esos eventos directamente a la sesión especificada. Los datos del evento enviados a ETW en tiempo de ejecución incluyen el GUID de descodificación del evento y el identificador de mensaje, pero no incluye el GUID de control, el nivel o las palabras clave del evento. ETW comprueba que el proveedor tiene los permisos necesarios y, a continuación, agrega los datos del evento a la sesión especificada.
    • Dado que los eventos se envían directamente a una sesión específica sin guid de control, información de nivel o palabra clave, ETW no puede realizar ningún filtrado o enrutamiento adicional para los proveedores que usan el sistema de habilitación heredado. Cada evento se puede enrutar a no más de una sesión.
  • Un proveedor que usa EventRegister (por ejemplo, un proveedor basado en manifiesto o un proveedor traceLogging) usa el sistema de habilitación moderno (a veces denominado "CRIMSON ETW"). Cuando se habilita o se vuelve a configurar un proveedor moderno para una sesión, el tiempo de ejecución de ETW notifica al proveedor con el nivel , la máscara MatchAnyKeyword de 64 bits, la máscara MatchAllKeyword de 64 bits y los datos de filtrado del lado del proveedor personalizados especificados por el controlador de seguimiento. A continuación, el proveedor usa su propia lógica para decidir qué eventos deben habilitarse, aunque la mayoría de los proveedores simplemente duplican la lógica de EventProviderEnabled. El proveedor envía los eventos habilitados a ETW para el enrutamiento. Los datos del evento enviados a ETW incluyen el GUID de control del evento, el identificador de mensaje, el nivel y las palabras clave. A continuación, ETW realiza un filtrado adicional según corresponda, enrutando el evento a las sesiones adecuadas.
    • Dado que los eventos se envían a ETW con información descriptiva, ETW puede realizar un filtrado y enrutamiento adicionales antes de agregar el evento a la sesión. Los eventos se pueden enrutar a más de una sesión si procede.

Para los proveedores que usan el sistema de habilitación moderno (es decir, proveedores que usan EventRegister), ETW admite varias características que el controlador de sesión de seguimiento puede solicitar mediante EnableTraceEx2EnableParameters. (Consulte EVENT_FILTER_DESCRIPTOR para obtener más información).

  • Filtrado esquematizado : esta es la configuración de filtrado tradicional, también denominada filtrado del lado proveedor. El controlador define un conjunto personalizado de filtros como un objeto binario que se pasa al proveedor en EnableCallbackFilterData. Es necesario que el controlador y el proveedor definan e interpreten estos filtros. A continuación, el proveedor puede usar el parámetro EventWriteExFilter para indicar las sesiones a las que no se debe enviar un evento debido al filtrado del lado proveedor. Esto requiere un acoplamiento cercano del controlador y el proveedor, ya que no se define el tipo y el formato del objeto binario de lo que se puede filtrar. La función TdhEnumerateProviderFilters se puede usar para recuperar los filtros definidos en un manifiesto.
  • Filtrado de ámbito: determinados proveedores están habilitados o no en una sesión en función de si cumplen o no los criterios especificados por los filtros de ámbito. Hay varios tipos de filtros de ámbito que permiten el filtrado en función del identificador de proceso (PID), el nombre de archivo ejecutable, el identificador de la aplicación y el nombre del paquete de la aplicación. Esta característica se admite en Windows 8.1, Windows Server 2012 R2 y versiones posteriores.
  • Filtrado de Stackwalk : esto notifica a ETW que solo realice un recorrido de pila para un conjunto determinado de identificadores de evento o nombres de eventos (para eventos traceLogging). Esta característica se admite en Windows 8.1, Windows Server 2012 R2 y versiones posteriores.
  • Filtrado de atributos: en el caso de los proveedores de manifiestos, los eventos se pueden filtrar en función de atributos de evento como el nivel, la palabra clave, el identificador de evento o el nombre del evento.
  • Filtrado de carga de eventos: en el caso de los proveedores de manifiestos, los eventos se pueden filtrar sobre la marcha en función de si satisfacen o no una expresión lógica basada en uno o varios predicados.

Nota

Aunque ETW admite un eficaz filtrado de carga y atributos, los eventos deben filtrarse principalmente por filtros de ámbito basados o a través del GUID de control, el nivel y la palabra clave. Normalmente, los proveedores realizan el filtrado de GUID de control, nivel y palabra clave directamente en el código del proveedor antes de que se genere o envíe el evento a ETW. En la mayoría de los proveedores, los eventos que están deshabilitados por nivel o palabra clave no tienen casi ningún impacto en el rendimiento del sistema. Del mismo modo, los proveedores deshabilitados por filtros de ámbito casi no afectan al rendimiento del sistema. Otros tipos de filtrado (basados en cargas o atributos distintos del nivel y la palabra clave) se realizan normalmente después de que el proveedor haya generado el evento y lo haya enviado al tiempo de ejecución de ETW, lo que significa que el evento tiene un impacto en el rendimiento del sistema (el tiempo de CPU dedicado a preparar el evento y enviarlo a ETW), incluso si el filtrado ETW determina que el evento no se debe registrar en ninguna sesión. Este tipo de filtrado solo es eficaz para reducir el volumen de datos de seguimiento y no es tan eficaz para reducir la sobrecarga de CPU de seguimiento.

Cada vez que se llama a EnableTraceEx2 , los filtros del proveedor de esa sesión se reemplazan por los nuevos parámetros definidos por los parámetros pasados a la función EnableTraceEx2 . Se pueden combinar varios filtros pasados en una sola llamada a EnableTraceEx2 con un efecto aditivo, pero los filtros pasados en una llamada posterior reemplazarán al conjunto anterior de filtros.

Para deshabilitar el filtrado y, por tanto, habilitar todos los proveedores o eventos de la sesión de registro, llame a EnableTraceEx2 con el parámetro EnableParameters que apunta a una estructura de ENABLE_TRACE_PARAMETERS con el miembro FilterDescCount establecido en 0.

Cada filtro pasado a la función EnableTraceEx2 se especifica mediante un miembro Type en el EVENT_FILTER_DESCRIPTOR. Se pasa una matriz de estructuras EVENT_FILTER_DESCRIPTOR en la estructura de ENABLE_TRACE_PARAMETERS pasada en el parámetro EnableParameters a la función EnableTraceEx2 .

Cada tipo de filtro (un miembro type específico) solo puede aparecer una vez en una llamada a la función EnableTraceEx2 . Algunos tipos de filtro permiten incluir varias condiciones en un único filtro. El número máximo de filtros que se pueden incluir en una llamada a EnableTraceEx2 se establece mediante MAX_EVENT_FILTERS_COUNT (definido en el archivo de encabezado Evntprov.h ; el valor puede cambiar en versiones futuras de Windows SDK).

Cada tipo de filtro tiene sus propios límites de tamaño o entidad en función del miembro Type específico de la estructura EVENT_FILTER_DESCRIPTOR . La lista siguiente indica estos límites.

  • EVENT_FILTER_TYPE_SCHEMATIZED

    • Límite de tamaño de filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Número de elementos permitidos: definido por proveedor y controlador
  • EVENT_FILTER_TYPE_PID

    • Límite de tamaño de filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Número de elementos permitidos: MAX_EVENT_FILTER_PID_COUNT (8)
  • EVENT_FILTER_TYPE_EXECUTABLE_NAME

    • Límite de tamaño de filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Número de elementos permitidos: una sola cadena que puede contener varios nombres de archivo ejecutables separados por punto y coma.
  • EVENT_FILTER_TYPE_PACKAGE_ID

    • Límite de tamaño de filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Número de elementos permitidos: una sola cadena que puede contener varios identificadores de paquete separados por punto y coma.
  • EVENT_FILTER_TYPE_PACKAGE_APP_ID

    • Límite de tamaño de filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Número de elementos permitidos: una sola cadena que puede contener varios identificadores de aplicación relativos al paquete (PRAID) separados por punto y coma.
  • EVENT_FILTER_TYPE_PAYLOAD

    • Límite de tamaño de filtro: MAX_EVENT_FILTER_PAYLOAD_SIZE (4096)
    • Número de elementos permitidos: 1
  • EVENT_FILTER_TYPE_EVENT_ID

    • Límite de tamaño de filtro: no definido
    • Número de elementos permitidos: MAX_EVENT_FILTER_EVENT_ID_COUNT (64)
  • EVENT_FILTER_TYPE_STACKWALK

    • Límite de tamaño de filtro: no definido
    • Número de elementos permitidos: MAX_EVENT_FILTER_EVENT_ID_COUNT (64)

Las palabras clave definen categorías de eventos. Por ejemplo, si el proveedor define InitializationKeyword = 0x1 (keyword bit 0), FileOperationKeyword = 0x2 (keyword bit 1) y CalculationKeyword = 0x4 (keyword bit 2), puede establecer MatchAnyKeyword en (InitializationKeyword | CalculationKeyword) = 5 para recibir eventos de inicialización y cálculo, pero no eventos de archivo.

Cuando se usa con proveedores modernos (basados en manifiestos o TraceLogging), un valor MatchAnyKeyword de 0 se trata igual que un valor MatchAnyKeyword de 0xFFFFFFFFFFFFFFFF, es decir, habilita todas las palabras clave de evento. Sin embargo, este comportamiento no se aplica a los proveedores heredados (MOF o WPP basados en TMF). Para habilitar todas las palabras clave de evento de un proveedor heredado, establezca MatchAnyKeyword0xFFFFFFFFen . Para habilitar todas las palabras clave de evento de proveedores heredados y modernos, establezca MatchAnyKeyword0xFFFFFFFFFFFFFFFFen .

Si la palabra clave de un evento es cero, el proveedor escribirá el evento en la sesión independientemente de las máscaras MatchAnyKeyword y MatchAllKeyword . (Este comportamiento se puede deshabilitar mediante la marca EVENT_ENABLE_PROPERTY_IGNORE_KEYWORD_0 ).

Para indicar que desea habilitar un grupo de proveedores, use la EVENT_ENABLE_PROPERTY_PROVIDER_GROUP marca en el miembro EnableProperty de EnableParameters.

Al llamar a EnableTraceEx2, es posible que el proveedor esté registrado o no. Si el proveedor ya está registrado, ETW llama a la función de devolución de llamada del proveedor (si existe) y la sesión comienza a recibir eventos. Si el proveedor aún no está registrado, ETW llamará a la función de devolución de llamada del proveedor (si existe) inmediatamente después de que el proveedor se registre y la sesión comenzará a recibir eventos. Si el proveedor aún no está registrado, la función de devolución de llamada del proveedor no recibirá el identificador de origen.

Si el proveedor está registrado y ya está habilitado para la sesión, puede volver a llamar a EnableTraceEx2 para actualizar los parámetros Level, MatchAnyKeyword, MatchAllKeyword y los miembros EnableProperty y EnableFilterDesc de EnableParameters.

En Windows 8.1, windows Server 2012 R2 y versiones posteriores, los filtros de recorrido de eventos, ámbito y pila se pueden usar mediante la función EnableTraceEx2 y las estructuras de ENABLE_TRACE_PARAMETERS y EVENT_FILTER_DESCRIPTOR para filtrar por condiciones específicas en una sesión del registrador. Para obtener más información sobre los filtros de carga de eventos, consulte las funciones TdhCreatePayloadFilter y TdhAggregatePayloadFilters y las estructuras ENABLE_TRACE_PARAMETERS, EVENT_FILTER_DESCRIPTOR y PAYLOAD_FILTER_PREDICATE .

EnableTraceEx2 no puede habilitar ni deshabilitar eventos especiales del proveedor de seguimiento del sistema. Solo se pueden habilitar a través del campo EnableFlags de EVENT_TRACE_PROPERTIES cuando StartTrace inicia el seguimiento por primera vez.

A partir de Windows 11, los eventos del proveedor de seguimiento del sistema se pueden habilitar mediante EnableTraceEx2.

Hasta ocho sesiones de seguimiento pueden habilitar y recibir eventos del mismo proveedor moderno (basado en manifiesto o TraceLogging). Sin embargo, solo una sesión de seguimiento puede habilitar un proveedor heredado (MOF, WPP basado en TMF). Si más de una sesión intenta habilitar un proveedor heredado, la primera sesión dejaría de recibir eventos cuando la segunda sesión habilita el mismo proveedor. Por ejemplo, si la sesión A habilitó un proveedor heredado y, a continuación, la sesión B habilitó el mismo proveedor, solo la sesión B recibiría eventos de ese proveedor.

Un proveedor permanece habilitado para la sesión hasta que la sesión deshabilita el proveedor. Si la aplicación que inició la sesión finaliza sin deshabilitar el proveedor, el proveedor permanece habilitado.

Para determinar el nivel y las palabras clave que se usan para habilitar un proveedor basado en manifiesto, use uno de los siguientes comandos:

  • logman query providers provider-name
  • wevtutil gp provider-name

En el caso de los proveedores clásicos, el proveedor debe documentar y poner a disposición de los posibles controladores los niveles de gravedad o habilitar las marcas que admite. Si cualquier controlador quiere habilitar el proveedor, el proveedor debe aceptar 0 para el nivel de gravedad y habilitar las marcas e interpretar 0 como una solicitud para realizar el registro predeterminado (lo que pueda ser).

Si usa EnableTraceEx2 para habilitar un proveedor clásico, se produce la traducción siguiente:

  • El parámetro Level es el mismo que establecer el parámetro EnableLevel en EnableTrace.
  • MatchAnyKeyword es el mismo que establecer el parámetro EnableFlag en EnableTrace, salvo que el valor de palabra clave se trunca de un valor de 64 bits a un valor de 32 bits.
  • En la devolución de llamada ControlCallback , el proveedor puede llamar a GetTraceEnableLevel para obtener el nivel y GetTraceEnableFlags para obtener la marca enable.
  • No se usa el otro parámetro.

Ejemplos

En el ejemplo siguiente se muestra el uso de las funciones EnableTraceEx2 con filtros de carga mediante las funciones TdhCreatePayloadFilter y TdhAggregatePayloadFilters para filtrar por condiciones específicas en una sesión del registrador.

#define INITGUID
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <strsafe.h>
#include <evntrace.h>
#include <tdh.h>

#define MAXIMUM_SESSION_NAME 1024

#define PATH_TO_MANIFEST_FILE L"c:\\ExampleManifest.man"

//
// The following definitions would be found in the include file generated by
// message compiler from the manifest file.
//

// Provider Example-Provider Event Count 2
EXTERN_C __declspec(selectany) const GUID EXAMPLE_PROVIDER = {0x37a59b93, 0xbb25, 0x4cee, {0x97, 0xaa, 0x8b, 0x6a, 0xcd, 0xc, 0x4d, 0xf8}};

//
// Event Descriptors
//
EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR Example_Event_1 = { 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0 };
#define Example_Event_1_value 0x1
EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR Example_Event_2 = { 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0 };
#define Example_Event_2_value 0x2

//
// (End of snippet from include file)
//

// Allocate an EVENT_TRACE_PROPERTIES structure and set the needed logging session properties
PEVENT_TRACE_PROPERTIES AllocateTraceProperties(
    _In_opt_ PCWSTR LoggerName,
    _In_opt_ PCWSTR LogFileName
)
{
    PEVENT_TRACE_PROPERTIES TraceProperties = NULL;
    ULONG BufferSize;

    BufferSize = sizeof(EVENT_TRACE_PROPERTIES) +
        (MAXIMUM_SESSION_NAME + MAX_PATH) * sizeof(WCHAR);

    TraceProperties = (PEVENT_TRACE_PROPERTIES)malloc(BufferSize);
    if (TraceProperties == NULL) {
        printf("Unable to allocate %d bytes for properties structure.\n", BufferSize);
        goto Exit;
    }

    //
    // Set the session properties.
    //
    ZeroMemory(TraceProperties, BufferSize);
    TraceProperties->Wnode.BufferSize = BufferSize;
    TraceProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
    TraceProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
    TraceProperties->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) +
        (MAXIMUM_SESSION_NAME * sizeof(WCHAR));

    if (LoggerName != NULL) {
        StringCchCopyW((LPWSTR)((PCHAR)TraceProperties + TraceProperties->LoggerNameOffset),
            MAXIMUM_SESSION_NAME,
            LoggerName);
    }

    if (LogFileName != NULL) {
        StringCchCopyW((LPWSTR)((PCHAR)TraceProperties + TraceProperties->LogFileNameOffset),
            MAX_PATH,
            LogFileName);
    }

Exit:
    return TraceProperties;
}

// Free the EVENT_TRACE_PROPERTIES structure previously allocated
VOID FreeTraceProperties(
    _In_ PEVENT_TRACE_PROPERTIES TraceProperties
)
{
    free(TraceProperties);
    return;
}

// Set the values needed in a PAYLOAD_FILTER_PREDICATE for a single payload filter
FORCEINLINE VOID PayloadPredicateCreate(
    _Out_ PAYLOAD_FILTER_PREDICATE* Predicate,
    _In_ PCWSTR FieldName,
    USHORT CompareOp,
    PCWSTR Value
)
{
    Predicate->FieldName = (PWSTR)FieldName;
    Predicate->CompareOp = CompareOp;
    Predicate->Value = (PWSTR)Value;
    return;
}

int __cdecl wmain()
{
    UINT i;
    PVOID EventFilters[2];
    EVENT_FILTER_DESCRIPTOR FilterDescriptor;
    UINT PredicateCount;
    PAYLOAD_FILTER_PREDICATE Predicates[3];
    ULONG FilterCount;
    ULONG Status = ERROR_SUCCESS;
    TRACEHANDLE SessionHandle = 0;
    PEVENT_TRACE_PROPERTIES TraceProperties;
    BOOLEAN TraceStarted = FALSE;
    PCWSTR LoggerName = L"MyTrace";
    ENABLE_TRACE_PARAMETERS EnableParameters;

    ZeroMemory(EventFilters, sizeof(EventFilters));
    ZeroMemory(Predicates, sizeof(Predicates));
    TraceProperties = NULL;
    FilterCount = 0;

    //
    // Load the manifest for the provider
    //
    Status = TdhLoadManifest((PWSTR)PATH_TO_MANIFEST_FILE);
    if (Status != ERROR_SUCCESS) {
        printf("TdhCreatePayloadFilter() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Create predicates that match the following high-level expression:
    //
    // INCLUDE Example_Event_1 IF
    //     Example_Event_1.Initiator == "User" AND
    //     7 <= Example_Event_1.Level <= 16
    //
    PredicateCount = 0;

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        (PWSTR)L"Initiator",
        PAYLOADFIELD_IS,
        (PWSTR)L"User");

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        L"Level",
        PAYLOADFIELD_BETWEEN,
        L"7,16");

    Status = TdhCreatePayloadFilter(
        &EXAMPLE_PROVIDER,
        &Example_Event_1,
        FALSE,      // Match all predicates (AND)
        PredicateCount,
        Predicates,
        &EventFilters[FilterCount++]);
    if (Status != ERROR_SUCCESS) {
        printf("TdhCreatePayloadFilter() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Create predicates that match the following high-level expression:
    // INCLUDE Example_Event_2 IF
    //      Example_Event_2.Title CONTAINS "UNI" OR
    //      Example_Event_2.InstanceId == {0E95CFBC-58D4-44BA-BE40-E63A853536DF} OR
    //      Example_Event_2.ErrorCode != 0      //
    PredicateCount = 0;

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        L"Title",
        PAYLOADFIELD_CONTAINS,
        L"UNI");

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        L"InstanceId",
        PAYLOADFIELD_IS,
        L" {0E95CFBC-58D4-44BA-BE40-E63A853536DF}");

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        L"ErrorCode",
        PAYLOADFIELD_NE,
        L"0");

    Status = TdhCreatePayloadFilter(
        &EXAMPLE_PROVIDER,
        &Example_Event_2,
        FALSE,      // Match any predicates (OR)
        PredicateCount,
        Predicates,
        &EventFilters[FilterCount++]);
    if (Status != ERROR_SUCCESS) {
        printf("TdhCreatePayloadFilter() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Combine the interim filters into a final filter descriptor.
    //
    Status = TdhAggregatePayloadFilters(
        FilterCount,
        EventFilters,
        NULL,
        &FilterDescriptor);
    if (Status != ERROR_SUCCESS) {
        printf("TdhAggregatePayloadFilters() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Clean up the interim filters
    //
    for (i = 0; i < FilterCount; i++) {

        Status = TdhDeletePayloadFilter(&EventFilters[i]);
        if (Status != ERROR_SUCCESS) {
            printf("TdhDeletePayloadFilter() failed with %lu\n", Status);
            goto Exit;
        }
    }

    //
    // Create a new trace session
    //
    //
    // Allocate EVENT_TRACE_PROPERTIES structure and perform some
    // basic initialization.
    //
    // N.B. LoggerName will be populated during StartTrace call.
    //
    TraceProperties = AllocateTraceProperties(NULL, L"SystemTrace.etl");
    if (TraceProperties == NULL) {
        Status = ERROR_OUTOFMEMORY;
        goto Exit;
    }

    TraceProperties->LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL | EVENT_TRACE_SYSTEM_LOGGER_MODE;
    TraceProperties->MaximumFileSize = 100; // Limit file size to 100MB max
    TraceProperties->BufferSize = 512; // Use 512KB trace buffers
    TraceProperties->MinimumBuffers = 8;
    TraceProperties->MaximumBuffers = 64;

    Status = StartTraceW(&SessionHandle, LoggerName, TraceProperties);
    if (Status != ERROR_SUCCESS) {
        printf("StartTrace() failed with %lu\n", Status);
        goto Exit;
    }

    TraceStarted = TRUE;

    //
    // Enable the provider to a trace session with filtering enabled on the
    // provider
    //
    ZeroMemory(&EnableParameters, sizeof(EnableParameters));
    EnableParameters.Version = ENABLE_TRACE_PARAMETERS_VERSION_2;
    EnableParameters.EnableFilterDesc = &FilterDescriptor;
    EnableParameters.FilterDescCount = 1;

    Status = EnableTraceEx2(
        SessionHandle,
        &EXAMPLE_PROVIDER,
        EVENT_CONTROL_CODE_ENABLE_PROVIDER,
        TRACE_LEVEL_VERBOSE,
        0,
        0,
        0,
        &EnableParameters);
    if (Status != ERROR_SUCCESS) {
        printf("EnableTraceEx2() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Clean up the payload descriptor
    //
    Status = TdhCleanupPayloadEventFilterDescriptor(&FilterDescriptor);
    if (Status != ERROR_SUCCESS) {
        printf("TdhCleanupPayloadEventFilterDescriptor() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Collect trace for 30 seconds
    //
    Sleep(30 * 1000);

Exit:

    //
    // Stop tracing.
    //
    if (TraceStarted != FALSE) {
        Status = ControlTraceW(SessionHandle, NULL, TraceProperties, EVENT_TRACE_CONTROL_STOP);
        if (Status != ERROR_SUCCESS) {
            printf("StopTrace() failed with %lu\n", Status);
        }
    }

    if (TraceProperties != NULL) {
        FreeTraceProperties(TraceProperties);
    }

    TdhUnloadManifest((PWSTR)PATH_TO_MANIFEST_FILE);

    return Status;
}

Requisitos

   
Cliente mínimo compatible Windows 7 [aplicaciones de escritorio | Aplicaciones para UWP]
Servidor mínimo compatible Windows Server 2008 R2 [aplicaciones de escritorio | Aplicaciones para UWP]
Plataforma de destino Windows
Encabezado evntrace.h
Library Sechost.lib en Windows 8.1 y Windows Server 2012 R2; Advapi32.lib en Windows 8, Windows Server 2012, Windows 7 y Windows Server 2008 R2
Archivo DLL Sechost.dll en Windows 8.1 y Windows Server 2012 R2; Advapi32.dll en Windows 8, Windows Server 2012, Windows 7 y Windows Server 2008 R2

Consulte también

StartTrace

ControlTrace

EnableCallback

ENABLE_TRACE_PARAMETERS

EVENT_FILTER_DESCRIPTOR