Поделиться через


Функция EnableTraceEx2 (evntrace.h)

Контроллер сеанса трассировки вызывает EnableTraceEx2, чтобы настроить, как поставщик событий ETW регистрирует события в сеанс трассировки.

Эта функция заменяет функции EnableTrace и EnableTraceEx.

Синтаксис

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

Параметры

TraceId

[in] ProviderId

Идентификатор поставщика (GUID элемента управления) поставщика событий, который требуется настроить.

[in] ControlCode

Можно указать один из следующих кодов управления:

Ценность Значение
EVENT_CONTROL_CODE_DISABLE_PROVIDER Обновите конфигурацию сеанса, чтобы сеанс не получал событий от поставщика.
EVENT_CONTROL_CODE_ENABLE_PROVIDER Обновите конфигурацию сеанса, чтобы сеанс получил запрошенные события от поставщика.
EVENT_CONTROL_CODE_CAPTURE_STATE Запрашивает, чтобы поставщик регистрирует сведения о состоянии.

[in] Level

Значение, указывающее максимальный уровень событий, которые требуется записать поставщику. Поставщик обычно записывает событие, если уровень события меньше или равен этому значению, а также соответствует условиям MatchAnyKeyword и MatchAllKeyword.

Корпорация Майкрософт определяет семантику уровней 1–5, как показано ниже. Более низкие значения указывают на более серьезные события. Каждое значение уровня включает указанный уровень и все более тяжелые уровни. Например, если указать TRACE_LEVEL_WARNING, потребитель получит предупреждение, ошибку и критические события.

Ценность Значение
TRACE_LEVEL_CRITICAL (1) Ненормальные события выхода или завершения
TRACE_LEVEL_ERROR (2) События серьезной ошибки
TRACE_LEVEL_WARNING (3) Предупреждения, такие как сбои выделения
TRACE_LEVEL_INFORMATION (4) Информационные события, не связанные с ошибками
TRACE_LEVEL_VERBOSE (5) Подробные диагностические события

Константы TRACE_LEVEL определены в evntrace.h. Эквивалентные WINMETA_LEVEL константы определяются в winmeta.h.

[in] MatchAnyKeyword

64-разрядная битовая маска ключевых слов, определяющих категории событий, которые требуется записать поставщику. Поставщик обычно записывает событие, если биты ключевых слов события соответствуют любой битов, заданных в этом значении, или если событие не имеет битов ключевых слов, а также соответствует условиям уровня и MatchAllKeyword.

[in] MatchAllKeyword

64-разрядная битовая маска ключевых слов, ограничивающая события, которые требуется записать поставщику. Поставщик обычно записывает событие, если биты ключевых слов события соответствуют все битов, заданных в этом значении, или если событие не имеет битов ключевых слов, а также соответствует критериям уровня и MatchAnyKeyword.

Это значение часто имеет значение 0.

[in] Timeout

Если время ожидания равно 0, эта функция начнет настраивать поставщика асинхронно и возвращает немедленно (т. е. возвращается без ожидания завершения обратных вызовов поставщика).

В противном случае эта функция начнет настраивать поставщика и начнет ожидать завершения конфигурации, включая ожидание завершения всех обратных вызовов поставщика. Если конфигурация завершится до указанного времени ожидания, эта функция вернет ERROR_SUCCESS. В противном случае эта функция вернет ERROR_TIMEOUT.

Чтобы ждать вечно, установите для INFINITE.

[in, optional] EnableParameters

Параметры трассировки, используемые для включения поставщика. Дополнительные сведения см. в ENABLE_TRACE_PARAMETERS.

Возвращаемое значение

Если функция выполнена успешно, возвращаемое значение ERROR_SUCCESS.

Если функция завершается ошибкой, возвращаемое значение является одним из системных кодов ошибок. Ниже приведены некоторые распространенные ошибки и их причины.

  • ERROR_INVALID_PARAMETER

    Неправильный параметр.

    Это может произойти, если одно из следующих значений имеет значение true:

    • ProviderIdNULL.
    • TraceHandle0.
  • ERROR_TIMEOUT

    Значение времени ожидания истекло до завершения обратного вызова включения. Дополнительные сведения см. в параметре Timeout.

  • ERROR_INVALID_FUNCTION

    Вы не можете обновить уровень, если поставщик не зарегистрирован.

  • ERROR_NO_SYSTEM_RESOURCES

    Превышено количество сеансов трассировки, которые могут включить поставщик.

  • ERROR_ACCESS_DENIED

    Только пользователи с правами администратора, пользователи в группе Performance Log Users и службах, работающих как LocalSystem, LocalServiceили NetworkService, могут включать поставщиков событий в межпроцессный сеанс. Чтобы предоставить ограниченному пользователю возможность включить поставщика событий, добавьте их в группу Performance Log Users или просмотрите EventAccessControl.

    Windows XP и Windows 2000: любой пользователь может включить поставщик событий.

Замечания

Контроллеры трассировки событий вызывают эту функцию для настройки поставщиков событий, записывающих события в сеанс. Например, контроллер может вызвать эту функцию, чтобы начать сбор событий от поставщика, настроить уровень или ключевые слова событий, собираемых от поставщика, или прекратить сбор событий от поставщика.

Поведение включения для поставщика зависит от того, какие API использует поставщик.

  • Поставщик, использующий RegisterTraceGuids (например, поставщик с использованием WPP или MOF на основе TMF) использует устаревшую систему включения (иногда называемую классической версией ETW). Если устаревший поставщик включен или перенастроен для сеанса, среда выполнения ETW уведомляет поставщика и предоставляет доступ к уровню, низкий 32 бит маски MatchAnyKeyword и идентификатор сеанса. Затем поставщик использует собственную логику, чтобы решить, какие события должны быть включены и отправлять эти события непосредственно в указанный сеанс. Данные событий, отправляемые в ETW во время выполнения, включают идентификатор guid декодировки события и идентификатор сообщения, но не включают guid элемента управления события, уровень или ключевые слова. ETW проверяет, имеет ли поставщик необходимые разрешения, а затем добавляет данные события в указанный сеанс.
    • Так как события отправляются непосредственно в определенный сеанс без идентификатора GUID, уровня или ключевых слов, ETW не может выполнять дополнительную фильтрацию или маршрутизацию для поставщиков, использующих устаревшую систему включения. Каждое событие можно перенаправить в не более одного сеанса.
  • Поставщик, использующий EventRegister (например, поставщик на основе манифеста или поставщик TraceLogging) использует современную систему включения (иногда называемую "crimson ETW"). Если современный поставщик включен или перенастроен для сеанса, среда выполнения ETW уведомляет поставщика с уровнем, 64-разрядную маску MatchAnyKeyword, 64-разрядную маску MatchAllKeyword и любые пользовательские данные фильтрации на стороне поставщика, указанные контроллером трассировки. Затем поставщик использует собственную логику, чтобы решить, какие события следует включить, хотя большинство поставщиков просто дублируют логику EventProviderEnabled. Поставщик отправляет включенные события в ETW для маршрутизации. Данные событий, отправленные в ETW, включают guid элемента управления события, идентификатор сообщения, уровень и ключевые слова. После этого ETW выполняет дополнительную фильтрацию соответствующим образом, перенаправляя событие в соответствующие сеансы.
    • Так как события отправляются в ETW с описательными сведениями, ETW может выполнять дополнительную фильтрацию и маршрутизацию перед добавлением события в сеанс. События можно перенаправить в несколько сеансов при необходимости.

Для поставщиков, использующих современную систему включения (т. е. поставщиков, использующих EventRegister), ETW поддерживает несколько функций, которые могут запрашиваться контроллером сеанса трассировки с помощью EnableTraceEx2EnableParameters. (Дополнительные сведения см. в EVENT_FILTER_DESCRIPTOR.)

  • схематизированной фильтрации . Это традиционная настройка фильтрации, которая также называется фильтрацией на стороне поставщика. Контроллер определяет настраиваемый набор фильтров как двоичный объект, передаваемый поставщику в EnableCallbackFilterData. Он обязан контроллеру и поставщику определять и интерпретировать эти фильтры. Затем поставщик может использовать параметр EventWriteExFilter, чтобы указать сеансы, в которые событие не должно отправляться из-за фильтрации на стороне поставщика. Для этого требуется близкое связывание контроллера и поставщика, так как тип и формат двоичного объекта, который можно отфильтровать, не определен. Функцию TdhEnumerateProviderFilters можно использовать для получения фильтров, определенных в манифесте.
  • фильтрация области . Некоторые поставщики включены или не включены в сеанс на основе того, соответствуют ли они критериям, указанным фильтрами областей. Существует несколько типов фильтров областей, которые позволяют фильтровать на основе идентификатора процесса (PID), имени исполняемого файла, идентификатора приложения и имени пакета приложения. Эта функция поддерживается в Windows 8.1, Windows Server 2012 R2 и более поздних версиях.
  • фильтрация Stackwalk . Это уведомляет трассировку трассировки событий только выполнять стек для заданного набора идентификаторов событий или (для событий TraceLogging). Эта функция поддерживается в Windows 8.1, Windows Server 2012 R2 и более поздних версиях.
  • фильтрация атрибутов. Для поставщиков манифестов события можно фильтровать на основе таких атрибутов событий, как уровень, ключевое слово, идентификатор события или имя события.
  • фильтрация полезных данных событий . Для поставщиков манифестов события можно отфильтровать на лету на основе того, удовлетворяют ли они логическому выражению на основе одного или нескольких предикатов.

Заметка

Несмотря на то, что ETW поддерживает мощные полезные данные и фильтрацию атрибутов, события должны быть в основном отфильтрованы фильтрами области на основе или с помощью GUID элемента управления, уровня и ключевого слова. Поставщики обычно выполняют фильтрацию идентификаторов GUID, уровней и ключевых слов непосредственно в коде поставщика перед созданием или отправкой события в ETW. В большинстве поставщиков события, отключенные по уровню или ключевому слову, практически не влияют на производительность системы. Аналогичным образом поставщики, отключенные фильтрами областей, практически не влияют на производительность системы. Другие виды фильтрации (на основе полезных данных или атрибутов, отличных от уровня и ключевого слова), обычно выполняются после того, как поставщик создал событие и отправил его в среду выполнения ETW, что означает, что событие влияет на производительность системы (время ЦП, затраченное на подготовку события и отправку его в ETW), даже если фильтрация ETW определяет, что событие не должно быть записано в каких-либо сеансах. Этот тип фильтрации эффективен только в снижении объема данных трассировки и не так эффективен для снижения затрат на ЦП трассировки.

Каждый раз, когда вызывается EnableTraceEx2, фильтры для поставщика в этом сеансе заменяются новыми параметрами, определенными параметрами, передаваемыми в функцию EnableTraceEx2. Несколько фильтров, передаваемых в одном вызове EnableTraceEx2, могут сочетаться с аддитивным эффектом, но фильтры, переданные в последующем вызове, заменят предыдущий набор фильтров.

Чтобы отключить фильтрацию и включить все поставщики и события в сеансе ведения журнала, вызовите EnableTraceEx2 с параметром EnableParameters, указывающим на структуру ENABLE_TRACE_PARAMETERS с параметр ом FilterDescCount значение 0.

Каждый фильтр, передаваемый в функцию EnableTraceEx2, задается элементом типа в EVENT_FILTER_DESCRIPTOR. Массив структур EVENT_FILTER_DESCRIPTOR передается в структуре ENABLE_TRACE_PARAMETERS, переданной в параметре EnableParameters в функцию EnableTraceEx2.

Каждый тип фильтра (определенный элемент типа ) может отображаться только один раз в вызове функции EnableTraceEx2. Некоторые типы фильтров позволяют включать несколько условий в один фильтр. Максимальное количество фильтров, которые можно включить в вызов EnableTraceEx2, задается MAX_EVENT_FILTERS_COUNT (определено в файле заголовка Evntprov.h; значение может измениться в будущих версиях пакета SDK для Windows).

Каждый тип фильтра имеет собственные ограничения размера или сущности на основе конкретного элемента Type в структуре EVENT_FILTER_DESCRIPTOR. В приведенном ниже списке указаны эти ограничения.

  • EVENT_FILTER_TYPE_SCHEMATIZED

    • Ограничение размера фильтра: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Количество разрешенных элементов: определяется поставщиком и контроллером
  • EVENT_FILTER_TYPE_PID

    • Ограничение размера фильтра: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Число разрешенных элементов: MAX_EVENT_FILTER_PID_COUNT (8)
  • EVENT_FILTER_TYPE_EXECUTABLE_NAME

    • Ограничение размера фильтра: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Число разрешенных элементов: одна строка, которая может содержать несколько имен исполняемых файлов, разделенных точкой с запятой.
  • EVENT_FILTER_TYPE_PACKAGE_ID

    • Ограничение размера фильтра: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Число разрешенных элементов: одна строка, которая может содержать несколько идентификаторов пакетов, разделенных точкой с запятой.
  • EVENT_FILTER_TYPE_PACKAGE_APP_ID

    • Ограничение размера фильтра: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Число разрешенных элементов: одна строка, которая может содержать несколько идентификаторов относительных приложений (PRAID), разделенных точкой с запятой.
  • EVENT_FILTER_TYPE_PAYLOAD

    • Ограничение размера фильтра: MAX_EVENT_FILTER_PAYLOAD_SIZE (4096)
    • Число разрешенных элементов: 1
  • EVENT_FILTER_TYPE_EVENT_ID

    • Ограничение размера фильтра: не определено
    • Число разрешенных элементов: MAX_EVENT_FILTER_EVENT_ID_COUNT (64)
  • EVENT_FILTER_TYPE_STACKWALK

    • Ограничение размера фильтра: не определено
    • Число разрешенных элементов: MAX_EVENT_FILTER_EVENT_ID_COUNT (64)

Ключевые слова определяют категории событий. Например, если поставщик определяет InitializationKeyword = 0x1 (ключевое слово 0), FileOperationKeyword = 0x2 (ключевое слово бит 1) и CalculationKeyword = 0x4 (ключевое слово 2), можно задать MatchAnyKeyword (InitializationKeyword | CalculationKeyword) = 5, чтобы получать события инициализации и вычисления, но не события файла.

При использовании с современными поставщиками или TraceLogging) MatchAnyKeyword обрабатывается так же, как значение MatchAnyKeyword , т. е. включает все ключевые слова событий. Однако это поведение не применяется к устаревшим поставщикам (MOF или поставщиков WPP на основе TMF). Чтобы включить все ключевые слова событий из устаревшего поставщика, задайте MatchAnyKeyword значение 0xFFFFFFFF. Чтобы включить все ключевые слова событий от устаревших и современных поставщиков, задайте для 0xFFFFFFFFFFFFFFFFзначение MatchAnyKeyword.

Если ключевое слово события равно нулю, поставщик записывает событие в сеанс независимо от MatchAnyKeyword и маски MatchAllKeyword. (Это поведение можно отключить с помощью флага EVENT_ENABLE_PROPERTY_IGNORE_KEYWORD_0.)

Чтобы указать, что вы хотите включить группу поставщиков, используйте флаг EVENT_ENABLE_PROPERTY_PROVIDER_GROUP для элемента EnableProperty элемента EnableParameters.

При вызове EnableTraceEx2поставщик может или не зарегистрирован. Если поставщик уже зарегистрирован, ETW вызывает функцию обратного вызова поставщика (если она есть), а сеанс начинает получать события. Если поставщик еще не зарегистрирован, ETW вызовет функцию обратного вызова поставщика (если она есть) сразу после регистрации поставщика, а сеанс начнет получать события. Если поставщик еще не зарегистрирован, функция обратного вызова поставщика не получит исходный идентификатор.

Если поставщик зарегистрирован и уже включен в сеанс, можно снова вызвать EnableTraceEx2, чтобы обновить параметрыуровня , MatchAnyKeyword, MatchAllKeyword и EnableProperty и членов EnableFilterDe sc EnableParameters.

В Windows 8.1, Windows Server 2012 R2 и более поздних версий полезные данные событий, области и обходные фильтры стека можно использовать функцией EnableTraceEx2 и структурами ENABLE_TRACE_PARAMETERS и EVENT_FILTER_DESCRIPTOR структур для фильтрации по определенным условиям в сеансе ведения журнала. Дополнительные сведения о фильтрах полезных данных событий см. в функции TdhCreatePayloadFilter и функции TdhAggregatePaylters и ENABLE_TRACE_PARAMETERS, EVENT_FILTER_DESCRIPTORи структуры PAYLOAD_FILTER_PREDICATE.

Специальные события поставщика трассировки системы нельзя включить или отключить с помощью EnableTraceEx2. Их можно включить только с помощью поля EnableFlagsEVENT_TRACE_PROPERTIES при первом запуске трассировки StartTrace.

Начиная с Windows 11 события поставщика трассировки системы можно включить с помощью enableTraceEx2.

До восьми сеансов трассировки могут включать и получать события от одного и того же современного поставщика или TraceLogging). Однако только один сеанс трассировки может включить устаревший поставщик WPP (MOF, TMF). Если несколько сеансов пытается включить устаревший поставщик, первый сеанс перестанет получать события, когда второй сеанс включает тот же поставщик. Например, если сеанс A включил устаревший поставщик, а затем сеанс B включил тот же поставщик, только сеанс B получит события от этого поставщика.

Поставщик по-прежнему включен для сеанса, пока сеанс не отключает поставщика. Если приложение, запущенное сеансом, завершается без отключения поставщика, поставщик остается включенным.

Чтобы определить уровень и ключевые слова, используемые для включения поставщика на основе манифеста, используйте одну из следующих команд:

  • Поставщики запросов logman имя поставщика
  • wevtutil gp имя поставщика

Для классических поставщиков поставщики могут документировать и предоставлять доступ к потенциальным контроллерам уровня серьезности или включить флаги, поддерживаемые им. Если поставщик хочет включить любой контроллер, поставщик должен принять 0 для уровня серьезности и включить флаги и интерпретировать 0 как запрос на выполнение ведения журнала по умолчанию (независимо от того, что может быть).

Если вы используете EnableTraceEx2 для включения классического поставщика, происходит следующий перевод:

  • Параметр уровня совпадает с параметром EnableLevel в EnableTrace.
  • MatchAnyKeyword совпадает с параметром EnableFlag в EnableTrace, за исключением того, что ключевое слово усечено из 64-разрядного значения в 32-разрядное значение.
  • В обратном вызове controlCallback ControlCallback поставщик может вызвать GetTraceEnableLevel, чтобы получить уровень и GetTraceEnableFlags, чтобы получить флаг включения.
  • Другой параметр не используется.

Примеры

В следующем примере показано использование EnableTraceEx2 с фильтрами полезных данных с помощью TdhCreatePayloadFilter и функции TdhAggregatePayloadFilters для фильтрации по определенным условиям в сеансе ведения журнала.

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

Требования

Требование Ценность
минимальные поддерживаемые клиентские Windows 7 [классические приложения | Приложения UWP]
минимальный поддерживаемый сервер Windows Server 2008 R2 [классические приложения | Приложения UWP]
целевая платформа Виндоус
заголовка evntrace.h
библиотеки Sechost.lib в Windows 8.1 и Windows Server 2012 R2; Advapi32.lib в Windows 8, Windows Server 2012, Windows 7 и Windows Server 2008 R2
DLL Sechost.dll в Windows 8.1 и Windows Server 2012 R2; Advapi32.dll в Windows 8, Windows Server 2012, Windows 7 и Windows Server 2008 R2

См. также

StartTrace

ControlTrace

EnableCallback

ENABLE_TRACE_PARAMETERS

EVENT_FILTER_DESCRIPTOR