Função EnableTraceEx2 (evntrace.h)

Um controlador de sessão de rastreamento chama EnableTraceEx2 para configurar como um provedor de eventos ETW registra eventos em uma sessão de rastreamento.

Essa função substitui as funções EnableTrace e EnableTraceEx .

Sintaxe

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 da sessão de rastreamento de eventos para a qual você está configurando o provedor. A função StartTrace retorna esse identificador quando um novo rastreamento é iniciado. Para obter o identificador de um rastreamento existente, use ControlTrace para consultar as propriedades de rastreamento com base no nome do rastreamento e, em seguida, obter o identificador do campo Wnode.HistoricContext dos dados retornados EVENT_TRACE_PROPERTIES .

[in] ProviderId

A ID do provedor (GUID de controle) do provedor de eventos que você deseja configurar.

[in] ControlCode

Você pode especificar um dos seguintes códigos de controle:

Valor Significado
EVENT_CONTROL_CODE_DISABLE_PROVIDER Atualize a configuração da sessão para que a sessão não receba eventos do provedor.
EVENT_CONTROL_CODE_ENABLE_PROVIDER Atualize a configuração da sessão para que a sessão receba os eventos solicitados do provedor.
EVENT_CONTROL_CODE_CAPTURE_STATE Solicita que o provedor registre suas informações de estado.

[in] Level

Um valor que indica o nível máximo de eventos que você deseja que o provedor escreva. O provedor normalmente grava um evento se o nível do evento for menor ou igual a esse valor, além de atender aos critérios MatchAnyKeyword e MatchAllKeyword .

A Microsoft define a semântica dos níveis 1 a 5, conforme mostrado abaixo. Valores mais baixos indicam eventos mais graves. Cada valor de Level habilita o nível especificado e todos os níveis mais graves. Por exemplo, se você especificar TRACE_LEVEL_WARNING, seu consumidor receberá aviso, erro e eventos críticos.

Valor Significado
TRACE_LEVEL_CRITICAL (1) Eventos anormais de saída ou encerramento
TRACE_LEVEL_ERROR (2) Eventos de erro grave
TRACE_LEVEL_WARNING (3) Eventos de aviso, como falhas de alocação
TRACE_LEVEL_INFORMATION (4) Eventos informativos sem erro
TRACE_LEVEL_VERBOSE (5) Eventos de diagnóstico detalhados

As TRACE_LEVEL constantes são definidas em evntrace.h. Constantes equivalentes WINMETA_LEVEL são definidas em winmeta.h.

[in] MatchAnyKeyword

Máscara de bits de 64 bits de palavras-chave que determinam as categorias de eventos que você deseja que o provedor escreva. O provedor normalmente grava um evento se os bits palavra-chave do evento corresponderem a qualquer um dos bits definidos nesse valor ou se o evento não tiver palavra-chave bits definidos, além de atender aos critérios Level e MatchAllKeyword.

[in] MatchAllKeyword

Máscara de bits de 64 bits de palavras-chave que restringe os eventos que você deseja que o provedor grave. O provedor normalmente grava um evento se os bits palavra-chave do evento corresponderem a todos os bits definidos nesse valor ou se o evento não tiver palavra-chave bits definidos, além de atender aos critérios Level e MatchAnyKeyword.

Esse valor é frequentemente definido como 0.

[in] Timeout

Se Timeout for 0, essa função começará a configurar o provedor de forma assíncrona e retornará imediatamente (ou seja, retornará sem aguardar a conclusão dos retornos de chamada do provedor).

Caso contrário, essa função começará a configurar o provedor e começará a aguardar a conclusão da configuração, inclusive aguardando a conclusão de todos os retornos de chamada do provedor. Se a configuração for concluída antes do tempo limite especificado, essa função retornará ERROR_SUCCESS. Caso contrário, essa função retornará ERROR_TIMEOUT.

Para esperar para sempre, defina como INFINITE.

[in, optional] EnableParameters

Os parâmetros de rastreamento usados para habilitar o provedor. Para obter detalhes, consulte ENABLE_TRACE_PARAMETERS.

Valor retornado

Se a função for bem-sucedida, o valor retornado será ERROR_SUCCESS.

Se a função falhar, o valor retornado será um dos códigos de erro do sistema. Veja a seguir alguns erros comuns e suas causas.

  • ERROR_INVALID_PARAMETER

    Um parâmetro está incorreto.

    Isso poderá ocorrer se qualquer uma das seguintes opções for verdadeira:

    • A ProviderId é NULL.
    • O TraceHandle é 0.
  • ERROR_TIMEOUT

    O valor de tempo limite expirou antes da conclusão do retorno de chamada de habilitação. Para obter detalhes, consulte o parâmetro Timeout .

  • ERROR_INVALID_FUNCTION

    Não é possível atualizar o nível quando o provedor não está registrado.

  • ERROR_NO_SYSTEM_RESOURCES

    Excedeu o número de sessões de rastreamento que podem habilitar o provedor.

  • ERROR_ACCESS_DENIED

    Somente usuários com privilégios administrativos, usuários no Performance Log Users grupo e serviços em execução como LocalSystem, LocalServiceou NetworkService podem habilitar provedores de eventos para uma sessão entre processos. Para conceder a um usuário restrito a capacidade de habilitar um provedor de eventos, adicione-o ao Performance Log Users grupo ou consulte EventAccessControl.

    Windows XP e Windows 2000: Qualquer pessoa pode habilitar um provedor de eventos.

Comentários

Os controladores de rastreamento de eventos chamam essa função para configurar os provedores de eventos que gravam eventos na sessão. Por exemplo, um controlador pode chamar essa função para começar a coletar eventos de um provedor, ajustar o nível ou as palavras-chave dos eventos que estão sendo coletados de um provedor ou parar de coletar eventos de um provedor.

O comportamento de habilitação para um provedor depende de quais APIs o provedor usa.

  • Um provedor que usa RegisterTraceGuids (por exemplo, um provedor que usa WPP ou MOF baseado em TMF) usa o sistema de habilitação herdado (às vezes chamado de "ETW clássico"). Quando um provedor herdado é habilitado ou reconfigurado para uma sessão, o runtime do ETW notifica o provedor e fornece acesso ao nível, aos 32 bits baixos da máscara MatchAnyKeyword e à ID da sessão. Em seguida, o provedor usa sua própria lógica para decidir quais eventos devem ser habilitados e envia esses eventos diretamente para a sessão especificada. Os dados de evento enviados ao ETW em runtime incluem o GUID de decodificação do evento e a ID da mensagem, mas não incluem o GUID de controle do evento, o nível ou as palavras-chave. O ETW verifica se o provedor tem as permissões necessárias e adiciona os dados de evento à sessão especificada.
    • Como os eventos são enviados diretamente para uma sessão específica sem guid de controle, nível ou informações de palavra-chave, o ETW não pode executar nenhuma filtragem ou roteamento adicional para provedores que usam o sistema de habilitação herdado. Cada evento pode ser roteado para não mais do que uma sessão.
  • Um provedor que usa EventRegister (por exemplo, um provedor baseado em manifesto ou um provedor tracelogging) usa o sistema de habilitação moderno (às vezes chamado de "ETW vermelho"). Quando um provedor moderno é habilitado ou reconfigurado para uma sessão, o runtime do ETW notifica o provedor com o nível, a máscara MatchAnyKeyword de 64 bits, a máscara MatchAllKeyword de 64 bits e todos os dados de filtragem personalizados do lado do provedor especificados pelo controlador de rastreamento. Em seguida, o provedor usa sua própria lógica para decidir quais eventos devem ser habilitados, embora a maioria dos provedores apenas duplique a lógica de EventProviderEnabled. O provedor envia os eventos habilitados para o ETW para roteamento. Os dados de evento enviados ao ETW incluem o GUID de controle do evento, a ID da mensagem, o nível e as palavras-chave. O ETW executa a filtragem adicional conforme apropriado, roteando o evento para as sessões apropriadas.
    • Como os eventos são enviados ao ETW com informações descritivas, o ETW pode executar filtragem e roteamento adicionais antes de adicionar o evento à sessão. Os eventos podem ser roteado para mais de uma sessão, se apropriado.

Para provedores que usam o sistema de habilitação moderno (ou seja, provedores que usam EventRegister), o ETW dá suporte a vários recursos que podem ser solicitados pelo controlador de sessão de rastreamento por meio de EnableTraceEx2EnableParameters. (Consulte EVENT_FILTER_DESCRIPTOR para obter detalhes.)

  • Filtragem esquematizada – essa é a configuração de filtragem tradicional, também chamada de filtragem do lado do provedor. O controlador define um conjunto personalizado de filtros como um objeto binário que é passado para o provedor em EnableCallbackFilterData. Cabe ao controlador e ao provedor definir e interpretar esses filtros. Em seguida, o provedor pode usar o parâmetro EventWriteExFilter para indicar sessões para as quais um evento não deve ser enviado devido à filtragem do lado do provedor. Isso requer um acoplamento próximo do controlador e do provedor, pois o tipo e o formato do objeto binário do que pode ser filtrado não são definidos. A função TdhEnumerateProviderFilters pode ser usada para recuperar os filtros definidos em um manifesto.
  • Filtragem de escopo – determinados provedores estão habilitados ou não para uma sessão com base em atender ou não aos critérios especificados pelos filtros de escopo. Há vários tipos de filtros de escopo que permitem a filtragem com base na ID do processo (PID), no nome do arquivo executável, na ID do aplicativo e no nome do pacote do aplicativo. Esse recurso tem suporte no Windows 8.1, no Windows Server 2012 R2 e posterior.
  • Filtragem de stackwalk – isso notifica o ETW para executar apenas uma caminhada de pilha para um determinado conjunto de IDs de evento ou nomes de eventos (para eventos TraceLogging). Esse recurso tem suporte no Windows 8.1, no Windows Server 2012 R2 e posterior.
  • Filtragem de atributo – para provedores de manifesto, os eventos podem ser filtrados com base em atributos de evento, como nível, palavra-chave, ID do evento ou nome do evento.
  • Filtragem de conteúdo de evento – para provedores de manifesto, os eventos podem ser filtrados em tempo real com base em se atendem ou não a uma expressão lógica com base em um ou mais predicados.

Observação

Embora o ETW dê suporte a conteúdo avançado e filtragem de atributos, os eventos devem ser principalmente filtrados com base em filtros de escopo ou por meio de GUID de controle, nível e palavra-chave. Os provedores geralmente executam GUID de controle, nível e palavra-chave filtragem diretamente no código do provedor antes que o evento seja gerado ou enviado ao ETW. Na maioria dos provedores, os eventos desabilitados por nível ou palavra-chave quase não têm impacto sobre o desempenho do sistema. Da mesma forma, os provedores desabilitados por filtros de escopo não têm quase nenhum impacto no desempenho do sistema. Outros tipos de filtragem (com base em conteúdo ou atributos diferentes do nível e palavra-chave) geralmente são executados depois que o provedor gera o evento e o envia para o runtime do ETW, o que significa que o evento tem impacto no desempenho do sistema (o tempo de CPU gasto preparando o evento e enviando-o para ETW), mesmo que a filtragem etw determine que o evento não deve ser registrado por nenhuma sessão. Esse tipo de filtragem só é eficaz na redução do volume de dados de rastreamento e não é tão eficaz para reduzir a sobrecarga da CPU de rastreamento.

Sempre que EnableTraceEx2 é chamado, os filtros para o provedor nessa sessão são substituídos pelos novos parâmetros definidos pelos parâmetros passados para a função EnableTraceEx2 . Vários filtros passados em uma única chamada EnableTraceEx2 podem ser combinados com um efeito aditivo, mas os filtros passados em uma chamada subsequente substituirão o conjunto anterior de filtros.

Para desabilitar a filtragem e, assim, habilitar todos os provedores/eventos na sessão de registro em log, chame EnableTraceEx2 com o parâmetro EnableParameters apontando para uma estrutura ENABLE_TRACE_PARAMETERS com o membro FilterDescCount definido como 0.

Cada filtro passado para a função EnableTraceEx2 é especificado por um membro Type no EVENT_FILTER_DESCRIPTOR. Uma matriz de estruturas EVENT_FILTER_DESCRIPTOR é passada na estrutura ENABLE_TRACE_PARAMETERS passada no parâmetro EnableParameters para a função EnableTraceEx2 .

Cada tipo de filtro (um membro type específico) só pode aparecer uma vez em uma chamada para a função EnableTraceEx2 . Alguns tipos de filtro permitem que várias condições sejam incluídas em um único filtro. O número máximo de filtros que podem ser incluídos em uma chamada para EnableTraceEx2 é definido por MAX_EVENT_FILTERS_COUNT (definido no arquivo de cabeçalho Evntprov.h ; o valor pode ser alterado em versões futuras do SDK do Windows).

Cada tipo de filtro tem seu próprio tamanho ou limites de entidade com base no membro Type específico na estrutura EVENT_FILTER_DESCRIPTOR . A lista abaixo indica esses limites.

  • EVENT_FILTER_TYPE_SCHEMATIZED

    • Limite de tamanho do filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Número de elementos permitidos: definidos por provedor e controlador
  • EVENT_FILTER_TYPE_PID

    • Limite de tamanho do filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Número de elementos permitidos: MAX_EVENT_FILTER_PID_COUNT (8)
  • EVENT_FILTER_TYPE_EXECUTABLE_NAME

    • Limite de tamanho do filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Número de elementos permitidos: uma única cadeia de caracteres que pode conter vários nomes de arquivo executáveis separados por ponto e vírgula.
  • EVENT_FILTER_TYPE_PACKAGE_ID

    • Limite de tamanho do filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Número de elementos permitidos: uma única cadeia de caracteres que pode conter várias IDs de pacote separadas por ponto e vírgula.
  • EVENT_FILTER_TYPE_PACKAGE_APP_ID

    • Limite de tamanho do filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Número de elementos permitidos: uma única cadeia de caracteres que pode conter várias PRAIDs (IDs de aplicativo relativas do pacote) separadas por ponto e vírgula.
  • EVENT_FILTER_TYPE_PAYLOAD

    • Limite de tamanho do filtro: MAX_EVENT_FILTER_PAYLOAD_SIZE (4096)
    • Número de elementos permitidos: 1
  • EVENT_FILTER_TYPE_EVENT_ID

    • Limite de tamanho do filtro: não definido
    • Número de elementos permitidos: MAX_EVENT_FILTER_EVENT_ID_COUNT (64)
  • EVENT_FILTER_TYPE_STACKWALK

    • Limite de tamanho do filtro: não definido
    • Número de elementos permitidos: MAX_EVENT_FILTER_EVENT_ID_COUNT (64)

As palavras-chave definem categorias de evento. Por exemplo, se o provedor definir InitializationKeyword = 0x1 (palavra-chave bit 0), FileOperationKeyword = 0x2 (palavra-chave bit 1) e CalculationKeyword = 0x4 (palavra-chave bit 2), você poderá definir MatchAnyKeyword como (InitializationKeyword | CalculationKeyword) = 5 para receber eventos de inicialização e cálculo, mas não eventos de arquivo.

Quando usado com provedores modernos (baseados em manifesto ou TraceLogging), um valor MatchAnyKeyword de 0 é tratado da mesma forma que um valor MatchAnyKeyword de 0xFFFFFFFFFFFFFFFF, ou seja, habilita todas as palavras-chave de evento. No entanto, esse comportamento não se aplica a provedores herdados (WPP baseados em MOF ou TMF). Para habilitar todas as palavras-chave de evento de um provedor herdado, defina MatchAnyKeyword como0xFFFFFFFF. Para habilitar todas as palavras-chave de evento de provedores herdados e modernos, defina MatchAnyKeyword como0xFFFFFFFFFFFFFFFF.

Se o palavra-chave de um evento for zero, o provedor gravará o evento na sessão, independentemente das máscaras MatchAnyKeyword e MatchAllKeyword. (Esse comportamento pode ser desabilitado usando o sinalizador EVENT_ENABLE_PROPERTY_IGNORE_KEYWORD_0 .)

Para indicar que você deseja habilitar um Grupo de Provedores, use o EVENT_ENABLE_PROPERTY_PROVIDER_GROUP sinalizador no membro EnableProperty de EnableParameters.

Quando você chama EnableTraceEx2, o provedor pode ou não estar registrado. Se o provedor já estiver registrado, o ETW chamará a função de retorno de chamada do provedor (se houver) e a sessão começará a receber eventos. Se o provedor ainda não estiver registrado, o ETW chamará a função de retorno de chamada do provedor (se houver) imediatamente após o provedor registrar e a sessão começará a receber eventos. Se o provedor ainda não estiver registrado, a função de retorno de chamada do provedor não receberá a ID de origem.

Se o provedor estiver registrado e já estiver habilitado para sua sessão, você poderá chamar EnableTraceEx2 novamente para atualizar os parâmetros Level, MatchAnyKeyword, MatchAllKeyword e os membros EnableProperty e EnableFilterDesc de EnableParameters.

Em Windows 8.1, o Windows Server 2012 R2 e posteriores, os filtros de conteúdo de evento, escopo e andar de pilha podem ser usados pela função EnableTraceEx2 e pelas estruturas ENABLE_TRACE_PARAMETERS e EVENT_FILTER_DESCRIPTOR para filtrar condições específicas em uma sessão de agente. Para obter mais informações sobre filtros de conteúdo de evento, consulte as funções TdhCreatePayloadFilter e TdhAggregatePayloadFilters e as estruturas ENABLE_TRACE_PARAMETERS, EVENT_FILTER_DESCRIPTOR e PAYLOAD_FILTER_PREDICATE .

Eventos especiais do provedor de rastreamento do sistema não podem ser habilitados ou desabilitados por EnableTraceEx2. Eles só podem ser habilitados por meio do campo EnableFlags de EVENT_TRACE_PROPERTIES quando o rastreamento é iniciado pela primeira vez pelo StartTrace.

Começando com Windows 11, os eventos do provedor de rastreamento do sistema podem ser habilitados usando EnableTraceEx2.

Até oito sessões de rastreamento podem habilitar e receber eventos do mesmo provedor moderno (baseado em manifesto ou TraceLogging). No entanto, apenas uma sessão de rastreamento pode habilitar um provedor herdado (MOF, WPP baseado em TMF). Se mais de uma sessão tentar habilitar um provedor herdado, a primeira sessão interromperá o recebimento de eventos quando a segunda sessão habilitar o mesmo provedor. Por exemplo, se a Sessão A habilitasse um provedor herdado e a Sessão B habilitasse o mesmo provedor, somente a Sessão B receberia eventos desse provedor.

Um provedor permanece habilitado para a sessão até que a sessão desabilite o provedor. Se o aplicativo que iniciou a sessão terminar sem desabilitar o provedor, o provedor permanecerá habilitado.

Para determinar o nível e as palavras-chave usados para habilitar um provedor baseado em manifesto, use um dos seguintes comandos:

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

Para provedores clássicos, cabe ao provedor documentar e disponibilizar aos controladores potenciais os níveis de severidade ou habilitar sinalizadores aos quais ele dá suporte. Se o provedor quiser ser habilitado por qualquer controlador, o provedor deverá aceitar 0 para o nível de severidade e habilitar sinalizadores e interpretar 0 como uma solicitação para executar o log padrão (seja lá o que for).

Se você usar EnableTraceEx2 para habilitar um provedor clássico, ocorrerá a seguinte tradução:

  • O parâmetro Level é o mesmo que definir o parâmetro EnableLevel em EnableTrace.
  • MatchAnyKeyword é o mesmo que definir o parâmetro EnableFlag em EnableTrace, exceto que o valor palavra-chave é truncado de um valor de 64 bits para um valor de 32 bits.
  • No retorno de chamada ControlCallback , o provedor pode chamar GetTraceEnableLevel para obter o nível e GetTraceEnableFlags para obter o sinalizador de habilitação.
  • O outro parâmetro não é usado.

Exemplos

O exemplo a seguir mostra o uso das funções EnableTraceEx2 com payload usando as funções TdhCreatePayloadFilter e TdhAggregatePayloadFilters para filtrar condições específicas em uma sessão de agente.

#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 com suporte Windows 7 [aplicativos da área de trabalho | Aplicativos UWP]
Servidor mínimo com suporte Windows Server 2008 R2 [aplicativos da área de trabalho | Aplicativos UWP]
Plataforma de Destino Windows
Cabeçalho evntrace.h
Biblioteca Sechost.lib no Windows 8.1 e no Windows Server 2012 R2; Advapi32.lib no Windows 8, Windows Server 2012, Windows 7 e Windows Server 2008 R2
DLL Sechost.dll no Windows 8.1 e no Windows Server 2012 R2; Advapi32.dll no Windows 8, Windows Server 2012, Windows 7 e Windows Server 2008 R2

Confira também

StartTrace

ControlTrace

EnableCallback

ENABLE_TRACE_PARAMETERS

EVENT_FILTER_DESCRIPTOR