Funzione EnableTraceEx2 (evntrace.h)

Un controller di sessione di traccia chiama EnableTraceEx2 per configurare il modo in cui un provider di eventi ETW registra gli eventi in una sessione di traccia.

Questa funzione sostituisce le funzioni EnableTrace e EnableTraceEx .

Sintassi

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
);

Parametri

[in] TraceHandle

Handle della sessione di traccia eventi per cui si sta configurando il provider. La funzione StartTrace restituisce questo handle all'avvio di una nuova traccia. Per ottenere l'handle di una traccia esistente, utilizzare ControlTrace per eseguire una query sulle proprietà di traccia in base al nome della traccia e quindi ottenere l'handle dal campo Wnode.HistoricalContext dei dati restituiti EVENT_TRACE_PROPERTIES .

[in] ProviderId

ID provider (GUID di controllo) del provider di eventi da configurare.

[in] ControlCode

È possibile specificare uno dei codici di controllo seguenti:

Valore Significato
EVENT_CONTROL_CODE_DISABLE_PROVIDER Aggiornare la configurazione della sessione in modo che la sessione non riceva gli eventi dal provider.
EVENT_CONTROL_CODE_ENABLE_PROVIDER Aggiornare la configurazione della sessione in modo che la sessione riceva gli eventi richiesti dal provider.
EVENT_CONTROL_CODE_CAPTURE_STATE Richiede che il provider registri le informazioni sullo stato.

[in] Level

Valore che indica il livello massimo di eventi che il provider deve scrivere. Il provider scrive in genere un evento se il livello dell'evento è minore o uguale a questo valore, oltre a soddisfare i criteri MatchAnyKeyword e MatchAllKeyword .

Microsoft definisce la semantica dei livelli 1-5, come illustrato di seguito. I valori inferiori indicano eventi più gravi. Ogni valore di Level abilita il livello specificato e tutti i livelli più gravi. Ad esempio, se si specifica TRACE_LEVEL_WARNING, il consumer riceverà avvisi, errori ed eventi critici.

Valore Significato
TRACE_LEVEL_CRITICAL (1) Eventi di chiusura o chiusura anomali
TRACE_LEVEL_ERROR (2) Eventi di errore gravi
TRACE_LEVEL_WARNING (3) Eventi di avviso, ad esempio errori di allocazione
TRACE_LEVEL_INFORMATION (4) Eventi informativi non di errore
TRACE_LEVEL_VERBOSE (5) Eventi di diagnostica dettagliati

Le TRACE_LEVEL costanti sono definite in evntrace.h. Le costanti equivalenti WINMETA_LEVEL sono definite in winmeta.h.

[in] MatchAnyKeyword

Maschera di parole chiave a 64 bit che determinano le categorie di eventi che si desidera che il provider scriva. Il provider scrive in genere un evento se i bit della parola chiave dell'evento corrispondono a uno qualsiasi dei bit impostati in questo valore o se l'evento non ha bit di parole chiave impostati, oltre a soddisfare i criteri Level e MatchAllKeyword .

[in] MatchAllKeyword

Maschera di parole chiave a 64 bit che limita gli eventi che si desidera che il provider scriva. Il provider scrive in genere un evento se i bit della parola chiave dell'evento corrispondono a tutti i bit impostati in questo valore o se l'evento non ha bit di parole chiave impostati, oltre a soddisfare i criteri Level e MatchAnyKeyword .

Questo valore viene spesso impostato su 0.

[in] Timeout

Se Timeout è 0, questa funzione inizierà a configurare il provider in modo asincrono e restituirà immediatamente (ovvero restituirà senza attendere il completamento dei callback del provider).

In caso contrario, questa funzione inizierà a configurare il provider e inizierà ad attendere il completamento della configurazione, inclusa l'attesa del completamento di tutti i callback del provider. Se la configurazione viene completata prima del timeout specificato, questa funzione restituirà ERROR_SUCCESS. In caso contrario, questa funzione restituirà ERROR_TIMEOUT.

Per attendere per sempre, impostare su INFINITE.

[in, optional] EnableParameters

Parametri di traccia utilizzati per abilitare il provider. Per informazioni dettagliate, vedere ENABLE_TRACE_PARAMETERS.

Valore restituito

Se la funzione ha esito positivo, il valore restituito viene ERROR_SUCCESS.

Se la funzione ha esito negativo, il valore restituito è uno dei codici di errore di sistema. Di seguito sono riportati alcuni errori comuni e le relative cause.

  • ERROR_INVALID_PARAMETER

    Un parametro non è corretto.

    Questa situazione può verificarsi se sono soddisfatte le condizioni seguenti:

    • ProviderId è NULL.
    • TraceHandle è 0.
  • ERROR_TIMEOUT

    Il valore di timeout è scaduto prima del completamento del callback di abilitazione. Per informazioni dettagliate, vedere il parametro Timeout .

  • ERROR_INVALID_FUNCTION

    Non è possibile aggiornare il livello quando il provider non è registrato.

  • ERROR_NO_SYSTEM_RESOURCES

    È stato superato il numero di sessioni di traccia che possono abilitare il provider.

  • ERROR_ACCESS_DENIED

    Solo gli utenti con privilegi amministrativi, gli utenti nel Performance Log Users gruppo e i servizi in esecuzione come LocalSystem, LocalServiceo NetworkService possono abilitare i provider di eventi a una sessione tra processi. Per concedere a un utente con restrizioni la possibilità di abilitare un provider di eventi, aggiungerli al Performance Log Users gruppo o vedere EventAccessControl.

    Windows XP e Windows 2000: Chiunque può abilitare un provider di eventi.

Commenti

I controller di traccia eventi chiamano questa funzione per configurare i provider di eventi che scrivono eventi nella sessione. Ad esempio, un controller potrebbe chiamare questa funzione per iniziare a raccogliere eventi da un provider, per modificare il livello o le parole chiave degli eventi raccolti da un provider o per interrompere la raccolta di eventi da un provider.

Il comportamento di abilitazione per un provider dipende dalle API usate dal provider.

  • Un provider che usa RegisterTraceGuids (ad esempio, un provider che usa WPP o MOF basato su TMF) usa il sistema di abilitazione legacy (talvolta denominato "ETW classico"). Quando un provider legacy è abilitato o riconfigurato per una sessione, il runtime ETW invia una notifica al provider e fornisce l'accesso al livello, i 32 bit bassi della maschera MatchAnyKeyword e l'ID sessione. Il provider usa quindi la propria logica per decidere quali eventi devono essere abilitati e li invia direttamente alla sessione specificata. I dati dell'evento inviati a ETW in fase di esecuzione includono il GUID decodifica dell'evento e l'ID del messaggio, ma non include il GUID del controllo dell'evento, il livello o le parole chiave. ETW verifica che il provider disponga delle autorizzazioni necessarie e quindi aggiunge i dati dell'evento alla sessione specificata.
    • Poiché gli eventi vengono inviati direttamente a una sessione specifica senza GUID di controllo, informazioni sul livello o sulle parole chiave, ETW non può eseguire filtri o routing aggiuntivi per i provider che usano il sistema di abilitazione legacy. Ogni evento può essere indirizzato a non più di una sessione.
  • Un provider che usa EventRegister (ad esempio, un provider basato su manifesto o un provider TraceLogging) usa il sistema di abilitazione moderno (talvolta denominato "crimson ETW"). Quando un provider moderno è abilitato o riconfigurato per una sessione, il runtime ETW invia una notifica al provider con il livello, la maschera MatchAnyKeyword a 64 bit, la maschera MatchAllKeyword a 64 bit e tutti i dati di filtro lato provider personalizzati specificati dal controller di traccia. Il provider usa quindi la propria logica per decidere quali eventi devono essere abilitati, anche se la maggior parte dei provider duplica solo la logica di EventProviderEnabled. Il provider invia gli eventi abilitati a ETW per il routing. I dati dell'evento inviati a ETW includono il GUID del controllo dell'evento, l'ID del messaggio, il livello e le parole chiave. ETW esegue quindi filtri aggiuntivi in base alle esigenze, indirizzando l'evento alle sessioni appropriate.
    • Poiché gli eventi vengono inviati a ETW con informazioni descrittive, ETW può eseguire filtri e routing aggiuntivi prima di aggiungere l'evento alla sessione. Gli eventi possono essere indirizzati a più sessioni, se appropriato.

Per i provider che usano il sistema di abilitazione moderno (ad esempio provider che usano EventRegister), ETW supporta diverse funzionalità che possono essere richieste dal controller di sessione di traccia tramite EnableTraceEx2EnableParameters. Per informazioni dettagliate , vedere EVENT_FILTER_DESCRIPTOR .

  • Filtro con schema : si tratta della configurazione tradizionale del filtro, detta anche filtro sul lato provider. Il controller definisce un set personalizzato di filtri come oggetto binario passato al provider in EnableCallbackFilterData. È necessario che il controller e il provider definiscano e interpretino questi filtri. Il provider può quindi usare il parametro EventWriteExFilter per indicare le sessioni a cui non deve essere inviato un evento a causa del filtro sul lato provider. Ciò richiede un accoppiamento ravvicinato del controller e del provider perché il tipo e il formato dell'oggetto binario di ciò che è possibile filtrare non è definito. La funzione TdhEnumerateProviderFilters può essere usata per recuperare i filtri definiti in un manifesto.
  • Filtro dell'ambito : alcuni provider sono abilitati o meno a una sessione in base al fatto che soddisfino o meno i criteri specificati dai filtri di ambito. Esistono diversi tipi di filtri di ambito che consentono il filtro in base all'ID processo (PID), al nome file eseguibile, all'ID dell'app e al nome del pacchetto dell'app. Questa funzionalità è supportata in Windows 8.1, Windows Server 2012 R2 e versioni successive.
  • Filtro stackwalk : indica a ETW di eseguire una procedura dettagliata dello stack solo per un determinato set di ID evento o (per gli eventi TraceLogging). Questa funzionalità è supportata in Windows 8.1, Windows Server 2012 R2 e versioni successive.
  • Filtro degli attributi: per i provider di manifesti, gli eventi possono essere filtrati in base agli attributi di evento, ad esempio livello, parola chiave, ID evento o nome evento.
  • Filtro del payload degli eventi: per i provider di manifesti, gli eventi possono essere filtrati in base al fatto che soddisfino o meno un'espressione logica in base a uno o più predicati.

Nota

Anche se ETW supporta un potente filtro di payload e attributi, gli eventi devono essere filtrati principalmente filtri di ambito basati su controllo o tramite GUID, livello e parola chiave. I provider in genere eseguono il GUID, il livello e il filtro delle parole chiave direttamente nel codice del provider prima che l'evento venga generato o inviato a ETW. Nella maggior parte dei provider gli eventi disabilitati per livello o parola chiave hanno quasi alcun impatto sulle prestazioni del sistema. Analogamente, i provider disabilitati dai filtri dell'ambito non hanno quasi alcun impatto sulle prestazioni del sistema. Altri tipi di filtro (basati su payload o attributi diversi da livello e parola chiave) vengono in genere eseguiti dopo che il provider ha generato l'evento e lo ha inviato al runtime ETW, ovvero l'evento ha impatto sulle prestazioni del sistema (il tempo di preparazione dell'evento e l'invio a ETW) anche se il filtro ETW determina che l'evento non deve essere registrato da alcuna sessione. Questo tipo di filtro è efficace solo per ridurre il volume di dati di traccia e non è efficace per ridurre il sovraccarico della CPU di traccia.

Ogni volta che EnableTraceEx2 viene chiamato, i filtri per il provider in tale sessione vengono sostituiti dai nuovi parametri definiti dai parametri passati alla funzione EnableTraceEx2 . Più filtri passati in una singola chiamata EnableTraceEx2 possono essere combinati con un effetto additivo, ma i filtri passati in una chiamata successiva sostituiranno il set precedente di filtri.

Per disabilitare il filtro e abilitare quindi tutti i provider/eventi nella sessione di registrazione, chiamare EnableTraceEx2 con il parametro EnableParameters che punta a una struttura ENABLE_TRACE_PARAMETERS con il membro FilterDescCount impostato su 0.

Ogni filtro passato alla funzione EnableTraceEx2 viene specificato da un membro Type nella EVENT_FILTER_DESCRIPTOR. Una matrice di strutture EVENT_FILTER_DESCRIPTOR viene passata nella struttura ENABLE_TRACE_PARAMETERS passata al parametro EnableParameters alla funzione EnableTraceEx2 .

Ogni tipo di filtro (un membro tipo specifico) può essere visualizzato una sola volta in una chiamata alla funzione EnableTraceEx2 . Alcuni tipi di filtro consentono l'inserimento di più condizioni in un singolo filtro. Il numero massimo di filtri che possono essere inclusi in una chiamata a EnableTraceEx2 è impostato da MAX_EVENT_FILTERS_COUNT (definito nel file di intestazione Evntprov.h ; il valore può cambiare nelle versioni future di Windows SDK).

Ogni tipo di filtro ha le proprie dimensioni o limiti di entità in base al membro tipo specifico nella struttura EVENT_FILTER_DESCRIPTOR . L'elenco seguente indica questi limiti.

  • EVENT_FILTER_TYPE_SCHEMATIZED

    • Limite di dimensioni del filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Numero di elementi consentiti: definito dal provider e dal controller
  • EVENT_FILTER_TYPE_PID

    • Limite di dimensioni del filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Numero di elementi consentiti: MAX_EVENT_FILTER_PID_COUNT (8)
  • EVENT_FILTER_TYPE_EXECUTABLE_NAME

    • Limite di dimensioni del filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Numero di elementi consentiti: stringa singola che può contenere più nomi di file eseguibili separati da punti e virgola.
  • EVENT_FILTER_TYPE_PACKAGE_ID

    • Limite di dimensioni del filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Numero di elementi consentiti: stringa singola che può contenere più ID pacchetto separati da punti e virgola.
  • EVENT_FILTER_TYPE_PACKAGE_APP_ID

    • Limite di dimensioni del filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Numero di elementi consentiti: stringa singola che può contenere più ID app relative al pacchetto (PRAID) separati da punti e virgola.
  • EVENT_FILTER_TYPE_PAYLOAD

    • Limite di dimensioni filtro: MAX_EVENT_FILTER_PAYLOAD_SIZE (4096)
    • Numero di elementi consentiti: 1
  • EVENT_FILTER_TYPE_EVENT_ID

    • Limite delle dimensioni del filtro: non definito
    • Numero di elementi consentiti: MAX_EVENT_FILTER_EVENT_ID_COUNT (64)
  • EVENT_FILTER_TYPE_STACKWALK

    • Limite delle dimensioni del filtro: non definito
    • Numero di elementi consentiti: MAX_EVENT_FILTER_EVENT_ID_COUNT (64)

Le parole chiave definiscono le categorie di eventi. Ad esempio, se il provider definisce InitializationKeyword = (parola chiave bit 0), FileOperationKeyword = 0x10x2 (parola chiave bit 1) e CalculationKeyword = 0x4 (parola chiave bit 2), è possibile impostare MatchAnyKeyword su (InitializationKeyword | ComputKeyword) = 5 per ricevere eventi di inizializzazione e calcolo, ma non eventi di file.

Se usato con provider moderni (basati su manifesto o TraceLogging), un valore MatchAnyKeyword di 0 viene considerato uguale a un valore MatchAnyKeyword di 0xFFFFFFFFFFFFFFFF, ad esempio abilita tutte le parole chiave dell'evento. Tuttavia, questo comportamento non si applica ai provider WPP legacy (MOF o TMF). Per abilitare tutte le parole chiave evento da un provider legacy, impostare MatchAnyKeyword su 0xFFFFFFFF. Per abilitare tutte le parole chiave dell'evento da provider legacy e moderni, impostare MatchAnyKeyword su 0xFFFFFFFFFFFFFFFF.

Se la parola chiave di un evento è zero, il provider scriverà l'evento nella sessione indipendentemente dalle maschere MatchAnyKeyword e MatchAllKeyword. Questo comportamento può essere disabilitato usando il flag di EVENT_ENABLE_PROPERTY_IGNORE_KEYWORD_0 .

Per indicare che si vuole abilitare un gruppo di provider, usare il flag nel EVENT_ENABLE_PROPERTY_PROVIDER_GROUP membro EnableProperty di EnableParameters.

Quando si chiama EnableTraceEx2, il provider potrebbe o non essere già registrato. Se il provider è già registrato, ETW chiama la funzione di callback del provider (se presente) e la sessione inizia a ricevere eventi. Se il provider non è già registrato, ETW chiamerà la funzione di callback del provider (se presente) immediatamente dopo la registrazione del provider e la sessione inizierà a ricevere eventi. Se il provider non è già registrato, la funzione di callback del provider non riceverà l'ID di origine.

Se il provider è registrato e già abilitato alla sessione, è possibile chiamare di nuovo EnableTraceEx2 per aggiornare i parametri Level, MatchAnyKeyword, MatchAllKeyword e i membri EnableProperty e EnableFilterDesc di EnableParameters.

In Windows 8.1, windows Server 2012 R2 e versioni successive, il payload degli eventi, l'ambito e i filtri di procedura dettagliata dello stack possono essere usati dalla funzione EnableTraceEx2 e dalle strutture ENABLE_TRACE_PARAMETERS e EVENT_FILTER_DESCRIPTOR per filtrare in condizioni specifiche in una sessione di logger. Per altre informazioni sui filtri del payload degli eventi, vedere le funzioni TdhCreatePayloadFilter e TdhAggregatePayloadFilterse le ENABLE_TRACE_PARAMETERS, EVENT_FILTER_DESCRIPTOR e le strutture PAYLOAD_FILTER_PREDICATE .

Gli eventi del provider di traccia di sistema speciali non possono essere abilitati o disabilitati da EnableTraceEx2. Possono essere abilitati solo tramite il campo EnableFlags di EVENT_TRACE_PROPERTIES quando la traccia viene avviata per la prima volta da StartTrace.

A partire da Windows 11, è possibile abilitare gli eventi del provider di traccia di sistema usando EnableTraceEx2.

Fino a otto sessioni di traccia possono abilitare e ricevere eventi dallo stesso provider moderno (basato su manifesto o TraceLogging). Tuttavia, solo una sessione di traccia può abilitare un provider WPP (MOF, TMF) legacy. Se più sessioni tenta di abilitare un provider legacy, la prima sessione interrompe la ricezione di eventi quando la seconda sessione abilita lo stesso provider. Ad esempio, se Sessione A ha abilitato un provider legacy e quindi Session B abilitato lo stesso provider, solo Session B riceverà eventi da tale provider.

Un provider rimane abilitato per la sessione fino a quando la sessione disabilita il provider. Se l'applicazione che ha avviato la sessione termina senza disabilitare il provider, il provider rimane abilitato.

Per determinare il livello e le parole chiave usate per abilitare un provider basato su manifesto, usare uno dei comandi seguenti:

  • provider di query logman
  • wevtutil gp provider-name

Per i provider classici, il provider deve documentare e rendere disponibili i potenziali controller i livelli di gravità o abilitare i flag supportati. Se il provider vuole essere abilitato da qualsiasi controller, il provider deve accettare 0 per il livello di gravità e abilitare i flag e interpretare 0 come richiesta per eseguire la registrazione predefinita (qualsiasi cosa possa essere).

Se si usa EnableTraceEx2 per abilitare un provider classico, si verifica la traduzione seguente:

  • Il parametro Level corrisponde all'impostazione del parametro EnableLevel in EnableTrace.
  • MatchAnyKeyword corrisponde all'impostazione del parametro EnableFlag in EnableTrace, ad eccezione del fatto che il valore della parola chiave viene troncato da un valore a 64 bit a un valore a 32 bit.
  • Nel callback ControlCallback il provider può chiamare GetTraceEnableLevel per ottenere il livello e GetTraceEnableFlags per ottenere il flag di abilitazione.
  • L'altro parametro non viene usato.

Esempio

Nell'esempio seguente viene illustrato l'uso delle funzioni EnableTraceEx2 con filtri payload usando TdhCreatePayloadFilter e TdhAggregatePayloadFilters per filtrare in condizioni specifiche in una sessione di logger.

#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;
}

Requisiti

   
Client minimo supportato Windows 7 [app desktop | App UWP]
Server minimo supportato Windows Server 2008 R2 [app desktop | App UWP]
Piattaforma di destinazione Windows
Intestazione evntrace.h
Libreria Sechost.lib in Windows 8.1 e Windows Server 2012 R2; Advapi32.lib in Windows 8, Windows Server 2012, Windows 7 e Windows Server 2008 R2
DLL Sechost.dll in Windows 8.1 e Windows Server 2012 R2; Advapi32.dll in Windows 8, Windows Server 2012, Windows 7 e Windows Server 2008 R2

Vedi anche

StartTrace

ControlTrace

EnableCallback

ENABLE_TRACE_PARAMETERS

EVENT_FILTER_DESCRIPTOR