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

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

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

Синтаксис

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

Параметры

[in] TraceHandle

Дескриптор сеанса трассировки событий, для которого настраивается поставщик. Функция StartTrace возвращает этот дескриптор при запуске новой трассировки. Чтобы получить дескриптор существующей трассировки, используйте ControlTrace для запроса свойств трассировки на основе имени трассировки, а затем получите дескриптор из поля Wnode.HistoricalContext возвращаемых EVENT_TRACE_PROPERTIES данных.

[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-разрядная битовая маска ключевых слов, определяющих категории событий, которые требуется записать поставщику. Поставщик обычно записывает событие, если ключевое слово биты события соответствуют любому из битов, заданных в этом значении, или если для события не задано ключевое слово битов, помимо соответствия критериям Level и MatchAllKeyword.

[in] MatchAllKeyword

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

Это значение часто устанавливается равным 0.

[in] Timeout

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

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

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

[in, optional] EnableParameters

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

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

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

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

  • ERROR_INVALID_PARAMETER

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

    Это может произойти, если выполняются следующие условия:

    • Значение ProviderId равно NULL.
    • TraceHandle имеет значение 0.
  • 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), использует устаревшую систему включения (иногда называемую "классической трассировкой событий Windows"). Если устаревший поставщик включен или перенастроен для сеанса, среда выполнения ETW уведомляет поставщика и предоставляет доступ к уровню, низким 32 битам маски MatchAnyKeyword и идентификатору сеанса. Затем поставщик использует собственную логику, чтобы решить, какие события следует включить, и отправляет эти события непосредственно в указанный сеанс. Данные события, отправляемые в etW во время выполнения, включают guid декодирования события и идентификатор сообщения, но не включают GUID элемента управления событием, уровень или ключевые слова. Трассировка событий Windows проверяет, имеет ли поставщик необходимые разрешения, а затем добавляет данные события в указанный сеанс.
    • Так как события отправляются непосредственно в определенный сеанс без guid элемента управления, уровня или ключевое слово информации, трассировка событий Windows не может выполнять дополнительную фильтрацию или маршрутизацию для поставщиков, использующих устаревшую систему включения. Каждое событие может быть перенаправлено не более чем в один сеанс.
  • Поставщик, использующий EventRegister (например, поставщик на основе манифеста или поставщик TraceLogging), использует современную систему включения (иногда называемую "багровым etW"). Если современный поставщик включен или перенастроен для сеанса, среда выполнения ETW уведомляет поставщика об уровне, 64-разрядной маске MatchAnyKeyword, 64-разрядной маске MatchAllKeyword и любых настраиваемых данных фильтрации на стороне поставщика, указанных контроллером трассировки. Затем поставщик использует собственную логику, чтобы решить, какие события следует включить, хотя большинство поставщиков просто дублируют логику EventProviderEnabled. Поставщик отправляет включенные события в трассировку событий Windows для маршрутизации. Данные события, отправляемые в etW, включают GUID элемента управления событиями, идентификатор сообщения, уровень и ключевые слова. Затем трассировка событий Windows выполняет дополнительную фильтрацию, перенаправляя событие в соответствующие сеансы.
    • Так как события отправляются в ETW с описательными сведениями, трассировка событий Windows может выполнить дополнительную фильтрацию и маршрутизацию перед добавлением события в сеанс. При необходимости события могут быть перенаправлены в несколько сеансов.

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

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

Примечание

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

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

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

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

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

Каждый тип фильтра имеет собственный размер или ограничения сущности в зависимости от конкретного элемента 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) значение 0MatchAnyKeyword обрабатывается так же, как значение 0xFFFFFFFFFFFFFFFFMatchAnyKeyword , т. е. включает все ключевые слова события. Однако это поведение не применяется к устаревшим поставщикам WPP (MOF или TMF). Чтобы включить все ключевые слова событий от устаревшего поставщика, задайте для matchAnyKeyword значение 0xFFFFFFFF. Чтобы включить все ключевые слова событий от устаревших и современных поставщиков, задайте для параметра MatchAnyKeyword значение0xFFFFFFFFFFFFFFFF.

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Параметр Level совпадает с параметром EnableLevel в EnableTrace.
  • Параметр MatchAnyKeyword совпадает с параметром EnableFlag в EnableTrace, за исключением того, что ключевое слово значение усекается с 64-разрядного до 32-разрядного.
  • В обратном вызове 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]
Целевая платформа Windows
Header 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