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

構成するイベント プロバイダーのプロバイダー ID (制御 GUID)。

[in] ControlCode

次のいずれかの制御コードを指定できます。

価値 意味
EVENT_CONTROL_CODE_DISABLE_PROVIDER セッションがプロバイダーからイベントを受信しないように、セッション構成を更新します。
EVENT_CONTROL_CODE_ENABLE_PROVIDER セッション構成を更新して、セッションがプロバイダーから要求されたイベントを受信するようにします。
EVENT_CONTROL_CODE_CAPTURE_STATE プロバイダーが状態情報をログに記録することを要求します。

[in] Level

プロバイダーが書き込むイベントの最大レベルを示す値。 通常、プロバイダーは、MatchAnyKeyword と MatchAllKeyword 条件を満たすだけでなく、イベントのレベルがこの値以下の場合にイベント 書き込みます。

Microsoft では、次に示すように、レベル 1 から 5 のセマンティクスを定義します。 値を小さくすると、より重大なイベントが示されます。 Level の各値により、指定されたレベルとより厳しいレベルがすべて有効になります。 たとえば、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

Timeout が 0 の場合、この関数はプロバイダーの構成を非同期的に開始し、すぐに戻ります (つまり、プロバイダーのコールバックが完了するのを待たずに戻ります)。

それ以外の場合、この関数はプロバイダーの構成を開始し、すべてのプロバイダー コールバックの完了を待機するなど、構成の完了の待機を開始します。 指定したタイムアウトの前に構成が完了した場合、この関数は ERROR_SUCCESSを返します。 それ以外の場合、この関数は ERROR_TIMEOUTを返します。

永遠に待つには、無限に設定します。

[in, optional] EnableParameters

プロバイダーを有効にするために使用されるトレース パラメーター。 詳細については、ENABLE_TRACE_PARAMETERSを参照してください。

戻り値

関数が成功した場合、戻り値は ERROR_SUCCESS

関数が失敗した場合、戻り値はシステム エラー コードの 1 つです。 一般的なエラーとその原因を次に示します。

  • ERROR_INVALID_PARAMETER

    パラメーターが正しくありません。

    これは、次のいずれかに該当する場合に発生する可能性があります。

    • ProviderId は NULLです。
    • TraceHandle は 0です。
  • ERROR_TIMEOUT

    タイムアウト値は、有効化コールバックが完了する前に期限切れになりました。 詳細については、Timeout パラメーターを参照してください。

  • ERROR_INVALID_FUNCTION

    プロバイダーが登録されていない場合、レベルを更新することはできません。

  • ERROR_NO_SYSTEM_RESOURCES

    プロバイダーを有効にできるトレース セッションの数を超えました。

  • ERROR_ACCESS_DENIED

    管理者特権を持つユーザー、Performance Log Users グループ内のユーザー、LocalSystemLocalService、または NetworkService として実行されているサービスのみが、イベント プロバイダーをクロスプロセス セッションに対して有効にすることができます。 制限付きユーザーにイベント プロバイダーを有効にする権限を付与するには、イベント プロバイダーを グループに追加するか、EventAccessControl参照してください。

    Windows XP と Windows 2000: 誰でもイベント プロバイダーを有効にできます。

備考

イベント トレース コントローラーは、この関数を呼び出して、セッションにイベントを書き込むイベント プロバイダーを構成します。 たとえば、コントローラーはこの関数を呼び出してプロバイダーからのイベントの収集を開始したり、プロバイダーから収集されるイベントのレベルやキーワードを調整したり、プロバイダーからのイベントの収集を停止したりできます。

プロバイダーの有効化動作は、プロバイダーが使用する API によって異なります。

  • RegisterTraceGuids を使用するプロバイダー (たとえば、TMF ベースの WPP または MOF を使用するプロバイダー) は、レガシ有効化システム ("クラシック ETW" と呼ばれることもあります) を使用します。 セッションに対してレガシ プロバイダーが有効または再構成されると、ETW ランタイムはプロバイダーに通知し、レベル、MatchAnyKeyword マスクの下位 32 ビット、およびセッション ID へのアクセスを提供します。 その後、プロバイダーは独自のロジックを使用して、有効にする必要があるイベントを決定し、それらのイベントを指定されたセッションに直接送信します。 実行時に ETW に送信されるイベント データには、イベントのデコード GUID とメッセージ ID が含まれますが、イベントのコントロール GUID、レベル、またはキーワードは含まれません。 ETW は、プロバイダーが必要なアクセス許可を持っていることを確認し、指定されたセッションにイベント データを追加します。
    • イベントは制御 GUID、レベル、キーワード情報なしで特定のセッションに直接送信されるため、ETW では、レガシ有効化システムを使用するプロバイダーに対して追加のフィルター処理やルーティングを実行できません。 各イベントは、複数のセッションにルーティングできません。
  • EventRegister を使用するプロバイダー (マニフェスト ベースのプロバイダーや TraceLogging プロバイダーなど) は、最新の有効化システム ("真紅 ETW" とも呼ばれます) を使用します。 セッションに対して最新のプロバイダーが有効または再構成されると、ETW ランタイムは、レベル、64 ビット MatchAnyKeyword マスク、64 ビット MatchAllKeyword マスク、およびトレース コントローラーで指定されたカスタム プロバイダー側フィルター データを使用してプロバイダーに通知します。 その後、プロバイダーは独自のロジックを使用して、有効にする必要があるイベントを決定しますが、ほとんどのプロバイダーは EventProviderEnabledのロジック 複製するだけです。 プロバイダーは、有効なイベントをルーティングのために ETW に送信します。 ETW に送信されるイベント データには、イベントの制御 GUID、メッセージ ID、レベル、キーワードが含まれます。 ETW は、必要に応じて追加のフィルター処理を実行し、イベントを適切なセッションにルーティングします。
    • イベントは説明情報を使用して ETW に送信されるため、ETW はセッションにイベントを追加する前に追加のフィルター処理とルーティングを実行できます。 必要に応じて、イベントを複数のセッションにルーティングできます。

最新の有効化システムを使用するプロバイダー (つまり、EventRegisterを使用するプロバイダー) の場合、ETW は、EnableTraceEx2EnableParametersを使用してトレース セッション コントローラーから要求できるいくつかの機能 サポートしています。 (詳細については、EVENT_FILTER_DESCRIPTOR を参照してください)。

  • スキーマ化されたフィルター処理 - これは、プロバイダー側のフィルター処理とも呼ばれる従来のフィルター設定です。 コントローラーは、フィルターのカスタム セットをバイナリ オブジェクトとして定義し、EnableCallbackFilterDataでプロバイダーに渡します。 これらのフィルターを定義して解釈することは、コントローラーとプロバイダーに必要です。 プロバイダーは、EventWriteExFilter パラメーターを使用して、プロバイダー側のフィルター処理のためにイベントを送信しないセッションを示すことができます。 これには、フィルター処理できるバイナリ オブジェクトの型と形式が定義されていないため、コントローラーとプロバイダーの密接な結合が必要です。 TdhEnumerateProviderFilters 関数を使用して、マニフェストで定義されているフィルターを取得できます。
  • スコープ フィルター - 特定のプロバイダーは、スコープ フィルターで指定された条件を満たしているかどうかに基づいて、セッションに対して有効または無効になります。 プロセス ID (PID)、実行可能ファイル名、アプリ ID、アプリ パッケージ名に基づくフィルター処理を可能にするスコープ フィルターには、いくつかの種類があります。 この機能は、Windows 8.1、Windows Server 2012 R2 以降でサポートされています。
  • Stackwalk フィルタリング - これは、特定のイベント ID セットまたは (TraceLogging イベントの場合) イベント名に対してのみスタック ウォークを実行するように ETW に通知します。 この機能は、Windows 8.1、Windows Server 2012 R2 以降でサポートされています。
  • 属性フィルター - マニフェスト プロバイダーの場合、イベントは、レベル、キーワード、イベント ID、イベント名などのイベント属性に基づいてフィルター処理できます。
  • イベント ペイロードのフィルター処理 - マニフェスト プロバイダーの場合、イベントは、1 つ以上の述語に基づく論理式を満たすかどうかに基づいて、その場でフィルター処理できます。

手記

ETW では強力なペイロードと属性のフィルター処理がサポートされていますが、イベントは主にフィルター処理ベースのスコープ フィルター、または制御 GUID、レベル、およびキーワードを使用してフィルター処理する必要があります。 通常、プロバイダーは、イベントが生成または ETW に送信される前に、プロバイダーのコードで制御 GUID、レベル、およびキーワードのフィルター処理を直接実行します。 ほとんどのプロバイダーでは、レベルまたはキーワードによって無効になっているイベントは、システムのパフォーマンスにほとんど影響しません。 同様に、スコープ フィルターによって無効にされたプロバイダーは、システムのパフォーマンスにほとんど影響しません。 他の種類のフィルター処理 (ペイロードまたはレベルとキーワード以外の属性に基づく) は、通常、プロバイダーがイベントを生成して ETW ランタイムに送信した後に実行されます。つまり、イベントはシステム パフォーマンス (イベントの準備と ETW への送信に費やされた CPU 時間) に影響を与えます。これは、ETW フィルター処理によってイベントをセッションによって記録すべきでないと判断された場合でも発生します。 この種のフィルター処理は、トレース データ ボリュームの削減にのみ有効であり、トレース CPU のオーバーヘッドを減らすには効果的ではありません。

EnableTraceEx2 呼び出されるたびに、そのセッション内のプロバイダーのフィルターは、EnableTraceEx2 関数に渡されたパラメーターによって定義された新しいパラメーターに置き換えられます。 1 つの EnableTraceEx2 呼び出しで渡された複数のフィルターを追加効果と組み合わせることができますが、後続の呼び出しで渡されたフィルターは、前のフィルター セットに置き換えられます。

フィルター処理を無効にし、ログ セッション内のすべてのプロバイダー/イベントを有効にするには、FilterDescCount メンバーが 0 に設定された ENABLE_TRACE_PARAMETERS 構造体を指す EnableParameters パラメーターを使用して EnableTraceEx2 呼び出します。

EnableTraceEx2 関数に渡される各フィルターは、EVENT_FILTER_DESCRIPTORType メンバーによって指定されます。 EVENT_FILTER_DESCRIPTOR 構造体の配列は、EnableParameters パラメーターで EnableTraceEx2 関数に渡される ENABLE_TRACE_PARAMETERS 構造体で渡されます。

各種類のフィルター (特定の メンバー) は、EnableTraceEx2 関数の呼び出しに 1 回だけ表示できます。 フィルターの種類によっては、複数の条件を 1 つのフィルターに含める場合があります。 EnableTraceEx2 の呼び出しに含めることができるフィルターの最大数は、MAX_EVENT_FILTERS_COUNT によって設定されます (Evntprov.h ヘッダー ファイルで定義されています。値は、将来のバージョンの Windows SDK で変更される可能性があります)。

各フィルターの種類には、EVENT_FILTER_DESCRIPTOR 構造体の特定の Type メンバーに基づいて、独自のサイズまたはエンティティの制限があります。 次の一覧は、これらの制限を示しています。

  • 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)
    • 使用できる要素の数: 複数の実行可能ファイル名をセミコロンで区切って含めることができる 1 つの文字列。
  • EVENT_FILTER_TYPE_PACKAGE_ID

    • フィルター サイズの制限: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • 使用できる要素の数: セミコロンで区切られた複数のパッケージ ID を含めることができる 1 つの文字列。
  • EVENT_FILTER_TYPE_PACKAGE_APP_ID

    • フィルター サイズの制限: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • 使用できる要素の数: セミコロンで区切られた複数のパッケージ相対アプリ ID (PRAID) を含めることができる 1 つの文字列。
  • 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 = (キーワード ビット 0)、FileOperationKeyword = (キーワード ビット 1)、CalculationKeyword = (キーワード ビット 2) を定義している場合、MatchAnyKeyword (InitializationKeyword |CalculationKeyword) = 初期化イベントと計算イベントを受信する場合は 5 ですが、ファイル イベントは受け取りません。

モダン (マニフェスト ベース または TraceLogging) プロバイダーと共に使用すると、0MatchAnyKeyword 値は、MatchAnyKeyword0xFFFFFFFFFFFFFFFFと同じように扱われます。つまり、すべてのイベント キーワードが有効になります。 ただし、この動作は、レガシ (MOF または TMF ベースの WPP) プロバイダーには適用されません。 レガシ プロバイダーからのすべてのイベント キーワードを有効にするには、MatchAnyKeyword に設定します。 従来のプロバイダーと最新のプロバイダーの両方からのすべてのイベント キーワードを有効にするには、MatchAnyKeyword 0xFFFFFFFFFFFFFFFFに設定します。

イベントのキーワードが 0 の場合、MatchAnyKeyword と MatchAllKeyword マスク に関係なく、プロバイダーはセッションにイベントを書き込みます。 (この動作は、EVENT_ENABLE_PROPERTY_IGNORE_KEYWORD_0 フラグを使用して無効にすることができます)。

プロバイダー グループを有効にすることを示すには、EnableParametersの EnableProperty メンバーの フラグ 使用します。

EnableTraceEx2呼び出すと、プロバイダーがまだ登録されている場合と、まだ登録されていない場合があります。 プロバイダーが既に登録されている場合、ETW はプロバイダーのコールバック関数 (存在する場合) を呼び出し、セッションはイベントの受信を開始します。 プロバイダーがまだ登録されていない場合、ETW はプロバイダーの登録直後にプロバイダーのコールバック関数 (存在する場合) を呼び出し、セッションはイベントの受信を開始します。 プロバイダーがまだ登録されていない場合、プロバイダーのコールバック関数はソース ID を受け取りません。

プロバイダーが登録されていて、セッションに対して既に有効になっている場合は、 EnableTraceEx2 をもう一度呼び出して、レベルの、matchAnyKeyword、MatchAllKeyword パラメーター、および EnableParametersの EnableProperty および EnableFilterDesc メンバー を更新できます。

Windows 8.1 では、Windows Server 2012 R2 以降では、イベント ペイロード、スコープ、スタック ウォーク フィルターは、EnableTraceEx2 関数と ENABLE_TRACE_PARAMETERS および EVENT_FILTER_DESCRIPTOR 構造体で使用して、ロガー セッション内の特定の条件でフィルター処理できます。 イベント ペイロード フィルターの詳細については、TdhCreatePayloadFilter、および TdhAggregatePayloadFilters 関数と、ENABLE_TRACE_PARAMETERSEVENT_FILTER_DESCRIPTOR、および PAYLOAD_FILTER_PREDICATE 構造体を します。

EnableTraceEx2では、特殊なシステム トレース プロバイダー イベント 有効または無効にできません。 トレースが StartTraceによって最初に開始されたときに、EVENT_TRACE_PROPERTIESEnableFlags フィールドを使用してのみ有効

Windows 11 以降では、EnableTraceEx2を使用して、システム トレース プロバイダー イベントを有効にできます。

最大 8 つのトレース セッションで、同じモダン (マニフェスト ベースの または TraceLogging) プロバイダーからイベントを有効にして受信できます。 ただし、レガシ (MOF、TMF ベースの WPP) プロバイダーを有効にできるトレース セッションは 1 つだけです。 複数のセッションでレガシ プロバイダーを有効にしようとすると、2 番目のセッションで同じプロバイダーが有効になると、最初のセッションはイベントの受信を停止します。 たとえば、セッション A がレガシ プロバイダーを有効にした後、セッション B が同じプロバイダーを有効にした場合、セッション B のみがそのプロバイダーからイベントを受信します。

セッションがプロバイダーを無効にするまで、プロバイダーはセッションに対して有効なままになります。 プロバイダーを無効にせずにセッションを開始したアプリケーションが終了した場合、プロバイダーは有効のままです。

マニフェスト ベースのプロバイダーを有効にするために使用されるレベルとキーワードを決定するには、次のいずれかのコマンドを使用します。

  • logman クエリ プロバイダー プロバイダー名
  • wevtutil gp provider-name

従来のプロバイダーの場合、重大度レベルを文書化し、潜在的なコントローラーで使用できるようにするか、サポートされているフラグを有効にするかは、プロバイダーの責任です。 プロバイダーを任意のコントローラーで有効にする場合、プロバイダーは重大度レベルで 0 を受け入れ、フラグを有効にし、既定のログ記録を実行する要求として 0 を解釈する必要があります (何でも)。

EnableTraceEx2 を使用してクラシック プロバイダーを有効にすると、次の変換が行われます。

  • Level パラメーターは、EnableTraceで EnableLevel パラメーター 設定する場合と同じです。
  • MatchAnyKeyword は、EnableTraceEnableFlag パラメーターを設定する場合と同じですが、キーワード値が 64 ビット値から 32 ビット値に切り捨てられる点が異なります。
  • ControlCallback コールバックでは、プロバイダーは GetTraceEnableLevel 呼び出してレベルを取得し、GetTraceEnableFlags を して有効フラグを取得できます。
  • その他のパラメーターは使用されません。

次の例は、TdhCreatePayloadFilter を使用したペイロード フィルターと共に EnableTraceEx2 を使用し、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
ライブラリ Windows 8.1 および Windows Server 2012 R2 の Sechost.lib。Windows 8、Windows Server 2012、Windows 7、Windows Server 2008 R2 の Advapi32.lib
DLL Windows 8.1 および Windows Server 2012 R2 での Sechost.dll。Windows 8、Windows Server 2012、Windows 7、Windows Server 2008 R2 での Advapi32.dll

関連項目

StartTrace の

ControlTrace

EnableCallback の

ENABLE_TRACE_PARAMETERS

EVENT_FILTER_DESCRIPTOR